static _inline void b64conv(HWND hwnd){ char B64D[8*10]; char buf[2][4*4]; DWORD adrs,s; t_memory *pmem; BYTE *buff[2]; GetWindowTextM(IDC_EDT_TOPADDR,buf[0],sizeof(buf[0])); GetWindowTextM(IDC_EDT_NUMBER,buf[1],sizeof(buf[1])); s=GetWindowTextM(IDC_COMBO1,B64D,sizeof(B64D)); if(s<64) return; adrs = strtoul(buf[0],NULL,16); s = strtoul(buf[1],NULL,10); if(adrs==0 || s==0) return; pmem=Findmemory(adrs); if(pmem==NULL) return; if ((buff[0] = (BYTE *)malloc(s+4)) == NULL) return; if(Readmemory(buff[0], pdump->sel0, s, MM_RESTORE | MM_SILENT) == s){ buff[1]=MS_Base64Encodes(B64D,buff[0],s); if(buff[1]){ SetWindowTextM(IDC_EDIT1,buff[1]); free(buff[1]); } free(buff[0]); } }
int AddBreakpoint(unsigned long addr, unsigned int type) { t_polymorphicbreakpoint crt_breakpoint; if(numberofpatch>=__MAX_PMBP__) { olly_add_to_list(0, __ERROR__, "[Error at %x08X] Too many breakpoint are already set.", addr); return 0; } crt_breakpoint.index=numberofpatch; crt_breakpoint.addr=addr; crt_breakpoint.type=type; crt_breakpoint.able=1; if(Readmemory(tpatch[numberofpatch].original, addr, (unsigned long)size[crt_breakpoint.type], MM_RESILENT) == 0) { olly_add_to_list(0, __ERROR__, "[Error at %x08X] Can't read the memory.", addr); return 0; } if(Writememory(polymorph[crt_breakpoint.type], addr, (unsigned long)size[crt_breakpoint.type], MM_RESILENT) == 0) { olly_add_to_list(0, __ERROR__, "[Error at %x08X] Can't write the memory / Set the breakpoint.", addr); return 0; } tpatch[numberofpatch].addr = addr; tpatch[numberofpatch].size = size[crt_breakpoint.type]; olly_add_sorted_data(&(breakpoint.data),&crt_breakpoint); olly_add_to_list(0,0,"New breakpoint at 0x%08X", addr); numberofpatch++; return 1; }
//--------------------------------------------------------------------------- BOOL RtlDeleteCriticalSection_Call( LPLOGDATA pLogData, t_reg * pRegisters ) { DWORD dwParameter; Readmemory( &dwParameter, pRegisters->r[REG_ESP]+4, 4, MM_SILENT ); snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlDeleteCriticalSection( 0x%.8X )", dwParameter ); return TRUE; }
int MalwareExtractor::Initialize() { m_thread = Findthread(Getcputhreadid()); if (m_thread == NULL) { m_error_code = ME_ERROR_NOTHREAD; return -1; } m_module = Findmodule(m_thread->reg.ip); m_imagecopy = new uchar[m_module->size]; if (m_imagecopy == NULL) { m_error_code = ME_ERROR_MEMALLOC; return -1; } if (Readmemory(m_imagecopy, m_module->base, m_module->size, MM_RESTORE) == 0) { m_error_code = ME_ERROR_MEMREAD; return -1; } this->BackupModuleRanges(); m_running = 1; return 0; }
bool SaveDump(string fileName, DWORD ep) { strCurEIP = ep; //OPENFILENAME ofn; HANDLE hHeap, hFile; PIMAGE_DOS_HEADER idosh; PIMAGE_NT_HEADERS ipeh; PIMAGE_SECTION_HEADER isech; LPBYTE lpDumpData; DWORD dwFrom,dwSize,dwAccBytes; unsigned int i; dwFrom = PEFileInfo.dwImageBase; dwSize = PEFileInfo.dwSizeOfImage; hHeap = HeapCreate(HEAP_NO_SERIALIZE,1,0); lpDumpData = (LPBYTE)HeapAlloc(hHeap,HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY,dwSize); dwSize = Readmemory(lpDumpData,dwFrom,dwSize,MM_RESTORE); idosh = (PIMAGE_DOS_HEADER)lpDumpData; if(idosh->e_magic != IMAGE_DOS_SIGNATURE) { MessageBox(0, "DUMP: 错误的DOS头(MZ)!!",PNAME,MB_OK | MB_ICONEXCLAMATION); HeapFree(hHeap,HEAP_NO_SERIALIZE,lpDumpData); return false; } ipeh = (PIMAGE_NT_HEADERS)(lpDumpData + idosh->e_lfanew); if(ipeh->Signature != IMAGE_NT_SIGNATURE) { MessageBox(0, "DUMP: 错误的PE标志头!!",PNAME,MB_OK | MB_ICONEXCLAMATION); HeapFree(hHeap,HEAP_NO_SERIALIZE,lpDumpData); return false; } ipeh->FileHeader.NumberOfSections = PEFileInfo.woNumOfSect; ipeh->OptionalHeader.ImageBase = PEFileInfo.dwImageBase; ipeh->OptionalHeader.SizeOfImage = PEFileInfo.dwSizeOfImage; ipeh->OptionalHeader.BaseOfCode = PEFileInfo.dwBaseOfCode; ipeh->OptionalHeader.BaseOfData = PEFileInfo.dwBaseOfData; ipeh->OptionalHeader.AddressOfEntryPoint = (strCurEIP - PEFileInfo.dwImageBase) ; isech = IMAGE_FIRST_SECTION(ipeh); if(FixSect) { for(i=0; i<(int)PEFileInfo.woNumOfSect; i++) { strcpy((char *)(isech+i)->Name,(char *)(lpSectInfo+i)->byName); (isech+i)->Misc.VirtualSize = (lpSectInfo+i)->dwVSize; (isech+i)->VirtualAddress = (lpSectInfo+i)->dwVOffset; (isech+i)->SizeOfRawData = (lpSectInfo+i)->dwVSize; (isech+i)->PointerToRawData = (lpSectInfo+i)->dwVOffset; (isech+i)->Characteristics = (lpSectInfo+i)->dwCharacteristics; } } strcpy( szFileName, fileName.c_str() ); hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile != INVALID_HANDLE_VALUE) { SetFilePointer(hFile, 0, 0, FILE_BEGIN); WriteFile(hFile, lpDumpData, dwSize, &dwAccBytes, NULL); CloseHandle(hFile); } HeapFree(hHeap,HEAP_NO_SERIALIZE,lpDumpData); return true; }
//--------------------------------------------------------------------------- BOOL RtlCreateHeap_Call( LPLOGDATA pLogData, t_reg * pRegisters ) { char cFlagsOutput[MAX_PATH]; DWORD dwParameters[3]; Readmemory( &dwParameters, pRegisters->r[REG_ESP]+4, 12, MM_SILENT ); ResolveHeapFlags( dwParameters[0], (char *)&cFlagsOutput ); snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlCreateHeap( %s, %d, %d )", cFlagsOutput, dwParameters[1], dwParameters[2] ); return TRUE; }
//--------------------------------------------------------------------------- BOOL RtlDestroyHeap_Call( LPLOGDATA pLogData, t_reg * pRegisters ) { DWORD dwParameter; Readmemory( &dwParameter, pRegisters->r[REG_ESP]+4, 4, MM_SILENT ); if( dwProcessHeap != NULL && dwParameter == dwProcessHeap ) snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlDestroyHeap( GetProcessHeap() )" ); else snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlDestroyHeap( 0x%.8X )", dwParameter ); pLogData->dwHeap = dwParameter; return TRUE; }
// Standard function Painttable() makes most of OllyDbg windows redrawing. You // only need to supply another function that prepares text strings and // optionally colours them. Case of custom windows is a bit more complicated, // please read documentation. int Bookmarkgettext(char *s, char *mask, int *select, t_sortheader *ph, int column) { int n; ulong cmdsize, decodesize; char cmd[MAXCMDSIZE], *pdecode; t_memory *pmem; t_disasm da; t_bookmark *pb = (t_bookmark *)ph; if (column == 0) // Name of bookmark { // Column 0 contains name of bookmark in form "Alt+n", where n is the // digit from 0 to 9. Mainly for demonstration purposes, I display prefix // "Alt+" in grayed and digit in normal text. Standard table windows do // not need to bother about selection. n = sprintf(s, "Alt+%i", pb->index); *select = DRAW_MASK; memset(mask, DRAW_GRAY, 4); mask[4] = DRAW_NORMAL; } else if (column == 1) // Address of bookmark n = sprintf(s, "%08X", pb->addr); else if (column == 2) // Disassembled command { // Function Disasm() requires that calling routine supplies code to be // disassembled. Read this code from memory. First determine possible // code size. pmem = Findmemory(pb->addr); // Find memory block containing code if (pmem == NULL) { *select = DRAW_GRAY; return sprintf(s, "???"); }; cmdsize = pmem->base + pmem->size - pb->addr; if (cmdsize > MAXCMDSIZE) cmdsize = MAXCMDSIZE; if (Readmemory(cmd, pb->addr, cmdsize, MM_RESTORE | MM_SILENT) != cmdsize) { *select = DRAW_GRAY; return sprintf(s, "???"); }; pdecode = Finddecode(pb->addr, &decodesize); if (decodesize < cmdsize) pdecode = NULL; Disasm(cmd, cmdsize, pb->addr, pdecode, &da, DISASM_CODE, 0); strcpy(s, da.result); n = strlen(s); } else if (column == 3) // Comment // Only user-defined comments are displayed here. n = Findname(pb->addr, NM_COMMENT, s); else n = 0; // s is not necessarily 0-terminated return n; };
void ShowOriAddr(HWND hWnd) { DWORD addr,index,data; index = SendMessage(hWnd,LB_GETCURSEL,0,0); addr = SendMessage(hWnd,LB_GETITEMDATA,index,0); addr &= 0x7fffffff; Readmemory(&data,addr+1,4,MM_SILENT); addr = data+addr+5; Setcpu(0,addr,0,0,CPU_ASMFOCUS); HWND phWnd = (HWND)GetWindowLong(hWnd,GWL_HWNDPARENT); ShowWindow(phWnd,SW_SHOWMINIMIZED); SetFocus(odghwnd); }
//--------------------------------------------------------------------------- BOOL RtlAllocateHeap_Call( LPLOGDATA pLogData, t_reg * pRegisters ) { char cFlagsOutput[MAX_PATH]; DWORD dwParameters[3]; Readmemory( &dwParameters, pRegisters->r[REG_ESP]+4, 12, MM_SILENT ); ResolveHeapFlags( dwParameters[1], (char *)&cFlagsOutput ); if( dwProcessHeap != NULL && dwParameters[0] == dwProcessHeap ) snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlAllocateHeap( GetProcessHeap(), %s, %d )", cFlagsOutput, dwParameters[2] ); else snprintf( pLogData->cMessage, BUFFER_SIZE, "RtlAllocateHeap( 0x%.8X, %s, %d )", dwParameters[0], cFlagsOutput, dwParameters[2] ); pLogData->dwHeap = dwParameters[0]; pLogData->dwHeapBlockSize = dwParameters[2]; return TRUE; }
/******************************************************************************* * * 函 数 名 : GetOEP * 功能描述 : 取得程序入口地址 * 参数列表 : dwImageBase -- 程序映像基础 * 说 明 : 函数并没有对程序正确性做检测 * 返回结果 : 如果成功返回程序OEP,否则返回0 * *******************************************************************************/ DWORD GetOEP(DWORD dwImageBase) { DWORD dwOEP = 0 ; char szBuffer[1024] ; if(0 == Readmemory(szBuffer, dwImageBase, 1024, 0)) { return dwOEP ; } PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer ; PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + szBuffer) ; dwOEP = pNtHeader->OptionalHeader.AddressOfEntryPoint + dwImageBase ; return dwOEP ; }
void FlashListBox(HWND hWnd) { DWORD i,count,addr; char data; count = SendMessage(hWnd,LB_GETCOUNT,0,0); for(i=0;i<count;i++) { addr = SendMessage(hWnd,LB_GETITEMDATA,i,0); Readmemory(&data,addr&0x7fffffff,1,MM_SILENT); if(data == 0xcc) { addr|=0x80000000; SendMessage(hWnd,LB_SETITEMDATA,i,addr); } else { addr&=0x7fffffff; SendMessage(hWnd,LB_SETITEMDATA,i,addr); } } }
LRESULT CALLBACK polybp_winproc(HWND hw,UINT msg,WPARAM wp,LPARAM lp) { HMENU menu; unsigned int i; unsigned long retaddr; t_polymorphicbreakpoint *slt_breakpoint; t_thread *pthread; switch (msg) { case WM_DESTROY: case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_HSCROLL: case WM_VSCROLL: case WM_TIMER: case WM_SYSKEYDOWN: case WM_USER_SCR: case WM_USER_VABS: case WM_USER_VREL: case WM_USER_VBYTE: case WM_USER_STS: case WM_USER_CNTS: case WM_USER_CHGS: case WM_WINDOWPOSCHANGED: return olly_table_function(&breakpoint,hw,msg,wp,lp); case WM_USER_MENU: slt_breakpoint=(t_polymorphicbreakpoint *)olly_get_sorted_by_selection(&(breakpoint.data),breakpoint.data.selected); menu=olly_create_popup_menu(); if (menu != 0 && slt_breakpoint != 0) { olly_append_menu(menu,MF_STRING,1,"Follow\tEnter"); olly_append_menu(menu,MF_STRING,2,"Disable\tDel"); i = olly_table_function(&breakpoint,hw,WM_USER_MENU,0,(LPARAM)menu); if (menu != 0) DestroyMenu(menu); if(i==1) olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS); if(i==2) { /* Remove a PolyMorphic Breakpoint */ if((slt_breakpoint->able == 1) && (ispaused == 1)) { switch(slt_breakpoint->type) { case 0: pthread=olly_find_thread(olly_get_cpu_thread_id()); context = pthread->context; if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 12)) { // Ajust esp context.Esp += 4; pthread->reg.r[4] += 4; // Restore eip context.Eip = slt_breakpoint->addr; pthread->reg.ip = slt_breakpoint->addr; } // Delete DisableBreakpoint(slt_breakpoint); break; case 1: pthread=olly_find_thread(olly_get_cpu_thread_id()); context = pthread->context; if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 17)) { // Ajust esp context.Esp += 4; pthread->reg.r[4] += 4; // Restore eip context.Eip = slt_breakpoint->addr; pthread->reg.ip = slt_breakpoint->addr; } // Delete DisableBreakpoint(slt_breakpoint); break; case 2: // Delete DisableBreakpoint(slt_breakpoint); break; case 3: pthread=olly_find_thread(olly_get_cpu_thread_id()); context = pthread->context; if((context.Eip >= slt_breakpoint->addr+4) && (context.Eip < slt_breakpoint->addr + 15)) { // Ajust esp context.Esp += 4; pthread->reg.r[4] += 4; // Restore eip pthread->reg.ip = slt_breakpoint->addr; context.Eip = slt_breakpoint->addr; } else if(context.Eip == context.Esp) { if(Readmemory(&retaddr,pthread->reg.r[4]+2,4,MM_RESILENT) == 0) { olly_add_to_list(0, __ERROR__, "[Error at %x08X] Can't read the memory.", pthread->reg.r[4]+2); break; } if(retaddr == slt_breakpoint->addr+5) { // Ajust esp context.Esp += 6; pthread->reg.r[4] += 6; // Restore eip pthread->reg.ip = slt_breakpoint->addr; context.Eip = slt_breakpoint->addr; } } // Delete DisableBreakpoint(slt_breakpoint); break; } // switch(slt_breakpoint->type) } // pause } // ifremove InvalidateRect(hw,NULL,FALSE); } return 0; case WM_USER_DBLCLK: slt_breakpoint=(t_polymorphicbreakpoint *)olly_get_sorted_by_selection( &(breakpoint.data),breakpoint.data.selected); if(slt_breakpoint != 0) olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS); return 0; case WM_KEYDOWN: if (wp==VK_RETURN && (GetKeyState(VK_SHIFT) & 0x8000)==0 && (GetKeyState(VK_CONTROL) & 0x8000)==0) { slt_breakpoint=(t_polymorphicbreakpoint *)Getsortedbyselection( &(breakpoint.data),breakpoint.data.selected); if(slt_breakpoint!=NULL) olly_set_cpu(0,slt_breakpoint->addr,0,0,CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS); } return 0; case WM_USER_CHALL: case WM_USER_CHMEM: InvalidateRect(hw, NULL, FALSE); return 0; case WM_PAINT: olly_paint_table(hw, &breakpoint, polybp_get_text); return 0; default: break; } return DefMDIChildProc(hw,msg,wp,lp); }
void SetEditText(HWND hWnd,DWORD type) { DWORD temp,t1,t2,i; char *info; wchar_t *winfo; if(type == CPUDUMP) { // __try { temp = Plugingetvalue(VAL_CPUDDUMP); t1=*(DWORD*)(temp+0x385); t2=*(DWORD*)(temp+0x389); temp=t2-t1; info = (char *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, temp + 2); winfo = (wchar_t *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (temp + 2) * sizeof(wchar_t)); Readmemory(info,(DWORD)t1,temp,MM_SILENT); for(i=0;i<temp;i++) { if(info[i]==0) { if(info[i+1]==0) { info[i]=0x0d; info[++i]=0x0a; } else info[i]=' '; } } MultiByteToWideChar(pagecode,0,info,-1,winfo,temp+2); SetWindowTextW(hWnd,winfo); HeapFree(hHeap, 0, info); HeapFree(hHeap, 0, winfo); } // __except(EXCEPTION_EXECUTE_HANDLER) // { // return; // } } else { temp = Plugingetvalue(VAL_CPUDSTACK ); t1 = *(DWORD*)(temp+0x385); char tempchar; // __try { Readmemory(&t2,t1,4,MM_SILENT); /* char s[128] = {0}; sprintf(s,"0x%08x 0x%08x",t2,info); MessageBox(hWnd,s,s,0);*/ t1 = t2; temp=0; do { Readmemory(&tempchar,t2++,1,MM_SILENT); ++temp; }while( tempchar != 0 ); if(temp==1) return; info = (char *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, temp); Readmemory(info,t1,temp,MM_SILENT); winfo = (wchar_t *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, temp * sizeof(wchar_t)); MultiByteToWideChar(pagecode,0,info,-1,winfo,temp); SetWindowTextW(hWnd,winfo); HeapFree(hHeap, 0, info); HeapFree(hHeap, 0, winfo); } // __except(EXCEPTION_EXECUTE_HANDLER) // { // return; // } } }
void GetCallAddress(HWND hWnd) { DWORD addr = Plugingetvalue(VAL_CPUDASM); addr = *(int*)(addr+0x385); DWORD mask=0xffff0000; DWORD base = addr&mask; IMAGE_DOS_HEADER dosh; char s[64]; Readmemory(&dosh,base,sizeof(IMAGE_DOS_HEADER),MM_RESTORE | MM_SILENT); while(dosh.e_magic!=IMAGE_DOS_SIGNATURE||mask==0) { mask<<=1; base = addr&mask; Readmemory(&dosh,base,sizeof(IMAGE_DOS_HEADER),MM_SILENT); } if(base==0) return; DWORD pebase = base; base+=dosh.e_lfanew+sizeof(IMAGE_NT_SIGNATURE)+sizeof(IMAGE_FILE_HEADER)+sizeof(IMAGE_OPTIONAL_HEADER); IMAGE_SECTION_HEADER sh; Readmemory(&sh,base,sizeof(IMAGE_SECTION_HEADER),MM_SILENT); while(sh.VirtualAddress!=0) { if( sh.VirtualAddress+pebase<addr&&sh.VirtualAddress+sh.SizeOfRawData+pebase>addr) break; base+=sizeof(IMAGE_SECTION_HEADER); Readmemory(&sh,base,sizeof(IMAGE_SECTION_HEADER),MM_SILENT); } if(sh.VirtualAddress==0)return; base = pebase+sh.VirtualAddress; DWORD size = sh.SizeOfRawData; char *data = (char *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size); Readmemory(data,base,size,MM_SILENT); // wsprintf(s,"0x%08x 0x%08x 0x%08x",base,pebase,addr); // MessageBox(hWnd,s,s,0); for(size_t i=0,j=0;i<size;i++) { // if(data[i]==0xe8) // { // sprintf(s,"0x%08x 0x%08x 0x%08x",*(DWORD*)(data+i+1),pebase,addr); // MessageBox(hWnd,s,s,0); if(*(DWORD*)(data+i) == (addr-base-i-4)) { if(data[i-1]==0xe8||data[i-1]==0xcc) { DWORD target = base+i-1; wsprintf(s,"0x%08x",target); if(data[i-1]==0xcc) target|=0x80000000; SendMessage(hWnd,LB_INSERTSTRING,j,(LPARAM)s); SendMessage(hWnd,LB_SETITEMDATA,j++,target); i+=3; } } } wsprintf(s,"调用0x%08x的参考",addr); SetWindowText((HWND)GetWindowLong(hWnd,GWL_HWNDPARENT),s); HeapFree(hHeap, 0, data); }
static int MCompareTrace(t_table *pt,wchar_t *name,ulong index,int mode) { wchar_t buffer[100]; uchar * codeline; ulong codelinesize; if (mode==MENU_VERIFY) return MENU_NORMAL; // Always available else if (mode==MENU_EXECUTE) { ulong i,j,length, declength; uchar cmd[MAXCMDSIZE],*decode; t_disasm da; t_reg *reg; void * result; t_memory *pmem; t_hitlist hitlistitem; Deletesorteddatarange(&(hitlisttable.sorted),0,0xFFFFFFFF); for ( i=0; i<memory.sorted.n; i++) { pmem=(t_memory *)Getsortedbyindex(&memory.sorted,i); // Get next memory block. if ((pmem->type & MEM_GAP)!=0) continue; // Unallocated memory // Check whether it contains executable code. if ((pmem->type & (MEM_CODE|MEM_SFX))==0) continue; // Not a code // iterate through code for ( j=pmem->base; j<=pmem->base +pmem->size; j++) { codeline = Finddecode(j,&codelinesize); if (codeline) if (((*codeline)&DEC_TRACED)==DEC_TRACED){ result = Findsorteddata(&baselist,j,0); //Addtolist(result,DRAW_NORMAL,L"sorted"); if(!result){ length=Readmemory(cmd,j,MAXCMDSIZE,MM_SILENT|MM_PARTIAL); if (length==0) Addtolist(j,DRAW_NORMAL,L"Readmemory returned zero!"); decode=Finddecode(j,&declength); if (decode!=NULL && declength<length) decode=NULL; length=Disasm(cmd,length,j,decode,&da,DA_TEXT|DA_OPCOMM|DA_MEMORY,NULL,NULL); if (length==0) Addtolist(j,DRAW_NORMAL,L"Disasm returned zero!"); StrcopyW(hitlistitem.decodedinstruction,TEXTLEN,da.result); hitlistitem.index=j; hitlistitem.size=1; hitlistitem.type=0; Addsorteddata(&(hitlisttable.sorted),&hitlistitem); } } } } if (hitlisttable.hw==NULL){ // Create table window. Third parameter (ncolumn) is the number of // visible columns in the newly created window (ignored if appearance is // restored from the initialization file). If it's lower than the total // number of columns, remaining columns are initially invisible. Fourth // parameter is the name of icon - as OllyDbg resource. Createtablewindow(&hitlisttable,0,hitlisttable.bar.nbar,NULL, L"ICO_PLUGIN",PLUGINNAME); } else Activatetablewindow(&hitlisttable); return MENU_REDRAW; } return MENU_ABSENT; };