// 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; };
// Menu function of Disassembler pane that deletes existing bookmark. static int MMarkTrace(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; t_memory *pmem; t_hitlist hitlistitem; Deletesorteddatarange(&(hitlisttable.sorted),0,0xFFFFFFFF); Deletesorteddatarange(&baselist,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){ hitlistitem.index=j; hitlistitem.size=1; hitlistitem.type=0; Addsorteddata(&baselist,&hitlistitem); } } } return MENU_REDRAW; } return MENU_ABSENT; };
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; };