// This function receives possible keyboard shortcuts from standard OllyDbg // windows. If it recognizes shortcut, it must process it and return 1, // otherwise it returns 0. extc int _export cdecl ODBG_Pluginshortcut( int origin, int ctrl, int alt, int shift, int key, void *item) { t_dump *pd; t_bookmark mark, *pm; // Plugin accepts shortcuts in form Alt+x or Shift+Alt+x, where x is a key // '0'..'9'. Shifted shortcut sets bookmark (only in Disassembler), // non-shifted jumps to bookmark from everywhere. if (ctrl == 0 && alt != 0 && key >= '0' && key <= '9') { if (shift != 0 && origin == PM_DISASM && item != NULL) { // Set new or replace existing bookmark. pd = (t_dump *)item; mark.index = key - '0'; mark.size = 1; mark.type = 0; mark.addr = pd->sel0; Addsorteddata(&(bookmark.data), &mark); if (bookmark.hw != NULL) InvalidateRect(bookmark.hw, NULL, FALSE); return 1; } // Shortcut recognized else if (shift == 0) { // Jump to existing bookmark (from any window). pm = Findsorteddata(&(bookmark.data), key - '0'); if (pm == NULL) Flash("Undefined bookmark"); else Setcpu(0, pm->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS); return 1; // Shortcut recognized }; }; return 0; // Shortcut not recognized };
void ShowDisasmAddr(HWND hWnd) { DWORD addr,index; index = SendMessage(hWnd,LB_GETCURSEL,0,0); addr = SendMessage(hWnd,LB_GETITEMDATA,index,0); Setcpu(0,addr&0x7fffffff,0,0,CPU_ASMFOCUS); HWND phWnd = (HWND)GetWindowLong(hWnd,GWL_HWNDPARENT); ShowWindow(phWnd,SW_SHOWMINIMIZED); SetFocus(odghwnd); }
int Assembl(char *answer,ulong parm) { int i,j,k,n,good; char s[TEXTLEN]; t_asmmodel model,attempt; t_memory *pmem; t_dump *pasm; // Visualize changes. Setcpu(0,address,0,0,CPU_ASMHIST|CPU_ASMCENTER); if (string[0]=='\0') // No immediate command Sendshortcut(PM_DISASM,address,WM_CHAR,0,0,' '); else { // Assemble immediate command. If there are several possible encodings, // select the shortest one. model.length=0; for (j=0; ; j++) { // Try all possible encodings good=0; for (k=0; k<4; k++) { // Try all possible constant sizes n=Assemble(string,address,&attempt,j,k,model.length==0?answer:s); if (n>0) { good=1; // If another decoding is found, check if it is shorter. if (model.length==0 || n<model.length) model=attempt; // Shortest encoding so far ; }; }; if (good==0) break; // No more encodings }; if (model.length==0) return -1; // Invalid command // Check for imprecise parameters. k=model.mask[0]; for (i=1; i<model.length; i++) k&=model.mask[i]; if (k!=0xFF) { strcpy(answer,"Command contains imprecise operands"); return -1; }; // If there is no backup copy, create it. Dump window always assumes that // backup has the same base and size as the dump, so check it to avoid // strange ireproducible errors. pmem=Findmemory(address); if (pmem==NULL) { //strcpy(answer,"Attempt to assemble to non-existing memory"); wsprintf(answer,"%X",model.code[0]); for(i=1; i<model.length; i++) { wsprintf(answer,"%s%X",answer,model.code[i]); } return -1; }; pasm=(t_dump *)Plugingetvalue(VAL_CPUDASM); if (pasm!=NULL && pmem->copy==NULL && pmem->base==pasm->base && pmem->size==pasm->size) Dumpbackup(pasm,BKUP_CREATE); // Now write assembled code to memory. Writememory(model.code,address,model.length,MM_RESTORE|MM_DELANAL); }; return 0; };
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); }
// Custom table function of hitlist window. Here it is used only to process // doubleclicks (custom message WM_USER_DBLCLK). This function is also called // on WM_DESTROY, WM_CLOSE (by returning -1, you can prevent window from // closing), WM_SIZE (custom tables only), WM_CHAR (only if TABLE_WANTCHAR is // set) and different custom messages WM_USER_xxx (depending on table type). // See documentation for details. long HitlistSelfunc(t_table *pt,HWND hw,UINT msg,WPARAM wp,LPARAM lp) { t_hitlist * item; switch (msg) { case WM_USER_DBLCLK: // Doubleclick // Get selection. item=(t_hitlist *)Getsortedbyselection(&(pt->sorted),pt->sorted.selected); // Follow address in CPU Disassembler pane. Actual address is added to // the history, so that user can easily return back to it. if (item!=NULL) Setcpu(0,item->index,0,0,0, CPU_ASMHIST|CPU_ASMCENTER|CPU_ASMFOCUS); return 1; default: break; }; return 0; };
void _export cdecl ODBG_Pluginaction(int origin, int action, void *item) { list_t* names; TCHAR path[TEXTLEN]; t_status status; if (origin == PM_MAIN) { switch (action) { case ACTION_IMPORT: status = Getstatus(); if (status && status != STAT_FINISHED && status != STAT_CLOSING) { if (mapfile_browse(path)) { names = mapfile_parse(path); if (names) { mapfile_apply(names); list_freenames(names); Setcpu(0, 0, 0, 0, CPU_ASMFOCUS); } else { Flash("Failed to open the file"); } } } else { Flash("Start the debugging session first"); } break; case ACTION_OPTIONS: configwnd_create(); break; case ACTION_ABOUT: MessageBox(g_hwndOlly, c_About, "About mapimp", MB_ICONINFORMATION); break; default: break; } } }
int _export cdecl ODBG_Pausedex(int reason, int extdata, t_reg *reg, DEBUG_EVENT *debugevent) { list_t* names; WIN32_FIND_DATA fdata; TCHAR path[MAX_PATH]; TCHAR* pos; HANDLE result; if ((reason & PP_INT3BREAK) && !g_SessionStarted && !g_Autoloaded) { g_SessionStarted = TRUE; strcpy(path, (TCHAR*)Plugingetvalue(VAL_EXEFILENAME)); pos = strrchr(path, '.'); if (pos) { strcpy(pos, ".map"); } else { strcat(path, ".map"); } result = FindFirstFile(path, &fdata); if (result != INVALID_HANDLE_VALUE) { FindClose(result); g_Autoloaded = TRUE; if ((g_Config->aimport == AUTOIMPORT_ASK) && (MessageBox(g_hwndOlly, "Corresponding map file found. Do you want to import it now?", "mapimp", MB_YESNO | MB_ICONQUESTION) == IDYES) || (g_Config->aimport == AUTOIMPORT_ALWAYS)) { names = mapfile_parse(path); if (names) { mapfile_apply(names); list_freenames(names); Setcpu(0, 0, 0, 0, CPU_ASMFOCUS); } else { Flash("Failed to open the file"); } } } } return 0; }
// This optional function receives commands from plugin menu in window of type // origin. Argument action is menu identifier from ODBG_Pluginmenu(). If user // activates automatically created entry in main menu, action is 0. extc void _export cdecl ODBG_Pluginaction(int origin, int action, void *item) { t_bookmark mark, *pb; t_dump *pd; if (origin == PM_MAIN) { switch (action) { case 0: // Menu item "Bookmarks", creates bookmark window. //Createbookmarkwindow(); // Make launcher { t_table *table; t_sorted *sorted; t_patch *patches; t_patch *elem; int i; FILE *f; table = Plugingetvalue(VAL_PATCHES); sorted = &table->data; patches = sorted->data; if(patches != NULL) { char *exe_name; char *launcher_name; int exe_name_len; // remove full path and keep exe name exe_name = Plugingetvalue(VAL_EXEFILENAME); exe_name += strlen(exe_name) - 1; while(*exe_name != '\\') --exe_name; ++exe_name; exe_name_len = strlen(exe_name); // create launcher file launcher_name = malloc(exe_name_len + 2); launcher_name[0] = '_'; strcpy(launcher_name + 1, exe_name); CopyFile("launcher.exe", launcher_name, 0); f = fopen(launcher_name, "a"); if(f != NULL) { //void *base_address = Plugingetvalue(VAL_MAINBASE); elem = patches; for(i = 0; i < sorted->n; i++) { fwrite(elem->orig, elem->size, 1, f); fwrite(elem->mod, elem->size, 1, f); fwrite(&elem->addr, sizeof(elem->addr) + sizeof(elem->size), 1, f); ++elem; } fwrite(exe_name, exe_name_len, 1, f); fwrite(&exe_name_len, sizeof(exe_name_len), 1, f); fwrite(&sorted->n, sizeof(sorted->n), 1, f); fwrite(SIG, sizeof(SIG) - 1, 1, f); fclose(f); } free(launcher_name); } } break; case 1: // Menu item "About", displays plugin info. If you write your own code, // please replace with own copyright! MessageBox(hwmain, "Bookmark plugin v1.10\n" "(demonstration of plugin capabilities)\n" "Copyright (C) 2001-2004 Oleh Yuschuk & Piérrot", "Bookmark plugin", MB_OK | MB_ICONINFORMATION); break; default: break; }; } else if (origin == PM_DISASM) { pd = (t_dump *)item; if (action >= 0 && action < 10) // Insert bookmark { mark.index = action; mark.size = 1; mark.type = 0; mark.addr = pd->sel0; Addsorteddata(&(bookmark.data), &mark); if (bookmark.hw != NULL) InvalidateRect(bookmark.hw, NULL, FALSE); } else if (action >= 10 && action < 20) // Delete bookmark { pb = (t_bookmark *)Findsorteddata(&(bookmark.data), action - 10); if (pb != NULL) { Deletesorteddata(&(bookmark.data), action - 10); if (bookmark.hw != NULL) InvalidateRect(bookmark.hw, NULL, FALSE); }; } else if (action >= 20 && action < 30) //Go to bookmark { pb = (t_bookmark *)Findsorteddata(&(bookmark.data), action - 20); if (pb != NULL) { Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS); }; }; }; };
// Each window class needs its own window procedure. Both standard and custom // OllyDbg windows must pass some system and OllyDbg-defined messages to // Tablefunction(). See description of Tablefunction() for more details. LRESULT CALLBACK Bookmarkwinproc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) { int i, shiftkey, controlkey; HMENU menu; t_bookmark *pb; switch (msg) { // Standard messages. You can process them, but - unless absolutely sure - // always pass them to Tablefunction(). 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: Tablefunction(&bookmark, hw, msg, wp, lp); break; // Pass message to DefMDIChildProc() // Custom messages responsible for scrolling and selection. User-drawn // windows must process them, standard OllyDbg windows without extra // functionality pass them to Tablefunction(). 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: return Tablefunction(&bookmark, hw, msg, wp, lp); // WM_WINDOWPOSCHANGED is responsible for always-on-top MDI windows. case WM_WINDOWPOSCHANGED: return Tablefunction(&bookmark, hw, msg, wp, lp); case WM_USER_MENU: menu = CreatePopupMenu(); // Find selected bookmark. Any operations with bookmarks make sense only // if at least one bookmark exists and is selected. Note that sorted data // has special sort index table which is updated only when necessary. // Getsortedbyselection() does this; some other sorted data functions // don't and you must call Sortsorteddata(). Read documentation! pb = (t_bookmark *)Getsortedbyselection( &(bookmark.data), bookmark.data.selected); if (menu != NULL && pb != NULL) { AppendMenu(menu, MF_STRING, 1, "&Follow\tEnter"); AppendMenu(menu, MF_STRING, 2, "&Delete\tDel"); }; // Even when menu is NULL, call to Tablefunction is still meaningful. i = Tablefunction(&bookmark, hw, WM_USER_MENU, 0, (LPARAM)menu); if (menu != NULL) DestroyMenu(menu); if (i == 1) // Follow bookmark in Disassembler Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS); else if (i == 2) // Delete bookmark { Deletesorteddata(&(bookmark.data), pb->index); // There is no automatical window update, do it yourself. InvalidateRect(hw, NULL, FALSE); }; return 0; case WM_KEYDOWN: // Processing of WM_KEYDOWN messages is - surprise, surprise - very // similar to that of corresponding menu entries. shiftkey = GetKeyState(VK_SHIFT) & 0x8000; controlkey = GetKeyState(VK_CONTROL) & 0x8000; if (wp == VK_RETURN && shiftkey == 0 && controlkey == 0) { // Return key follows bookmark in Disassembler. pb = (t_bookmark *)Getsortedbyselection( &(bookmark.data), bookmark.data.selected); if (pb != NULL) Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS); ; } else if (wp == VK_DELETE && shiftkey == 0 && controlkey == 0) { // DEL key deletes bookmark. pb = (t_bookmark *)Getsortedbyselection( &(bookmark.data), bookmark.data.selected); if (pb != NULL) { Deletesorteddata(&(bookmark.data), pb->index); InvalidateRect(hw, NULL, FALSE); }; } else // Add all this arrow, home and pageup functionality. Tablefunction(&bookmark, hw, msg, wp, lp); break; case WM_USER_DBLCLK: // Doubleclicking row follows bookmark in Disassembler. pb = (t_bookmark *)Getsortedbyselection( &(bookmark.data), bookmark.data.selected); if (pb != NULL) Setcpu(0, pb->addr, 0, 0, CPU_ASMHIST | CPU_ASMCENTER | CPU_ASMFOCUS); return 1; // Doubleclick processed case WM_USER_CHALL: case WM_USER_CHMEM: // Something is changed, redraw window. InvalidateRect(hw, NULL, FALSE); return 0; case WM_PAINT: // Painting of all OllyDbg windows is done by Painttable(). Make custom // drawing only if you have important reasons to do this. Painttable(hw, &bookmark, Bookmarkgettext); return 0; default: break; }; return DefMDIChildProc(hw, msg, wp, lp); };
int Stakcmd(char *answer,ulong parm) { Setcpu(0,0,0,address,CPU_DUMPHIST|CPU_DUMPFIRST|CPU_DUMPFOCUS); return 0; };
int Dumpcmd(char *answer,ulong parm) { Setcpu(0,0,address,0,CPU_DUMPHIST|CPU_DUMPFIRST|CPU_DUMPFOCUS); if (parm!=0) Setdumptype((t_dump *)Plugingetvalue(VAL_CPUDDUMP),parm); return 0; };
int Dasmcmd(char *answer,ulong parm) { Setcpu(0,address,0,0,CPU_ASMHIST|CPU_ASMCENTER); return 0; };
/******************************************************************************* * * 函 数 名 : SetASMCpu * 功能描述 : 设置反汇编窗口的地址 * 参数列表 : 无 * 说 明 : * 返回结果 : 如果成功返回TRUE,失败返回FALSE * *******************************************************************************/ BOOL SetASMCpu(DWORD dwAddr) { Setcpu(Getcputhreadid(), dwAddr, 0,0, CPU_REDRAW | CPU_ASMFOCUS) ; return TRUE ; }