.586p .model flat, stdcall ; 32 bit memory model option scoped ; local labels are enabled, global labels inside ; PROC should be defined with double colons (LABEL::) option casemap :none ; case sensitive DlgDumpProc proto :DWORD,:DWORD,:DWORD,:DWORD DlgOptionProc proto :DWORD,:DWORD,:DWORD,:DWORD include windows.inc include kernel32.inc include user32.inc include ..\plugin.inc include masm32.inc include comdlg32.inc includelib kernel32.lib includelib user32.lib includelib ..\ollydbg.lib includelib masm32.lib includelib comdlg32.lib ;
; literal string MACRO ;
literal MACRO quoted_text:VARARG LOCAL local_text .data local_text db quoted_text,0 .code EXITM <local_text> ENDM CTEXT MACRO quoted_text:VARARG EXITM <offset literal(quoted_text)> ENDM m2m MACRO M1, M2 push M2 pop M1 ENDM return MACRO arg mov eax, arg ret ENDM MAXSIZE equ 260 ;Dumper.dlg IDD_DUMP equ 1000 IDC_BTCANCEL equ 1001 IDC_BTDUMP equ 1002 IDC_EDTSIZE equ 1003 IDC_STC1 equ 1004 IDC_EDTOFFSET equ 1005 IDC_STC2 equ 1006 ;Res\Params.dlg IDD_OPTION equ 1001 IDC_GRP1 equ 1003 IDC_CHK1 equ 1001 IDC_STC3 equ 1002 IDC_SLEEPTIME equ 1004 IDC_STC4 equ 1005 IDC_BTN1 equ 1006 IDC_BTN2 equ 1007 ;IsDebug.rc .data the_byte db 1 null_byte db 0 ofn OPENFILENAME <> FilterString db "Bin Files",0 ;dont insert between bin_extend db "*.bin",0,0 ;here template db "%d",0 str_idb_Autoload db "idb_Autoload",0 str_idb_Sleeptime db "idb_Sleeptime",0 .data? hinst HINSTANCE ? ; DLL instance hwmain HWND ? ; Handle of main OllyDbg window textbuffer db 512 dup(?) byte_location dd ? SizeWritten dd ? hFileWrite dd ? hMemory_code dd ? pMemory_code dd ? SVWinClass db 32 dup(?) svthreadid dd ? sleep_time dd ? auto_load dd ? dw_buffer dd ? .code ; Entry point into a plugin DLL. Many system calls require DLL instance ; which is passed to DllEntryPoint() as one of parameters. Remember it. ; Preferrable way is to place initializations into ODBG_Plugininit() and ; cleanup in ODBG_Plugindestroy(). DllEntryPoint proc hi:HINSTANCE, reason:dword, res:dword .IF reason == DLL_PROCESS_ATTACH m2m hinst, hi ; Mark plugin instance .ENDIF return 1 ; Report success DllEntryPoint endp ; ODBG_Plugindata() is a "must" for valid OllyDbg plugin. It must fill in ; plugin name and return version of plugin interface. If function is absent, ; or version is not compatible, plugin will be not installed. Short name ; identifies it in the Plugins menu. This name is max. 31 alphanumerical ; characters or spaces + terminating '\0' long. To keep life easy for users, ; this name should be descriptive and correlate with the name of DLL. ODBG_Plugindata proc C shortname:ptr byte invoke lstrcpy, shortname, CTEXT("IsDebugPresent") ; Name of plugin return PLUGIN_VERSION; ODBG_Plugindata endp ; OllyDbg calls this obligatory function once during startup. Place all ; one-time initializations here. If all resources are successfully allocated, ; function must return 0. On error, it must free partially allocated resources ; and return -1, in this case plugin will be removed. Parameter ollydbgversion ; is the version of OllyDbg, use it to assure that it is compatible with your ; plugin; hw is the handle of main OllyDbg window, keep it if necessary. ; Parameter features is reserved for future extentions, do not use it. ODBG_Plugininit proc C ollydbgversion:dword, hw:HWND, features:ptr dword ; Check that version of OllyDbg is correct. .IF ollydbgversion < PLUGIN_VERSION jmp @@bad_exit .ENDIF invoke Addtolist, 0, 0, CTEXT("IsDebugPresent plugin v1.4 (SV 2oo3)") ; Keep handle of main OllyDbg window. This handle is necessary, for example, ; to display message box. m2m hwmain, hw return 0 @@bad_exit: return -1 ODBG_Plugininit endp ; OllyDbg calls this optional function once on exit. At this moment, all MDI ; windows created by plugin are already destroyed (and received WM_DESTROY ; messages). Function must free all internally allocated resources, like ; window classes, files, memory and so on. ODBG_Plugindestroy proc C invoke Unregisterpluginclass,addr SVWinClass ret ODBG_Plugindestroy endp ; Function is called when user opens new or restarts current application. ; Plugin should reset internal variables and data structures to initial state. ODBG_Pluginreset proc C invoke Pluginreadintfromini,hinst,addr str_idb_Autoload,0 ;Auto ? .if (eax!=0) invoke Pluginreadintfromini,hinst,addr str_idb_Sleeptime,1000 mov sleep_time,eax ;save time value lea eax,svthread invoke CreateThread,NULL,NULL,eax,NULL,NULL,svthreadid .endif ret svthread: invoke Sleep,sleep_time ;Wait a little ;) invoke Plugingetvalue,VAL_PROCESSID ;is something loaded ?? .if (eax!=0) ; invoke SetWindowText,hwmain,CTEXT("0llyDbg -") call get_byte_location mov byte_location,eax test eax,eax jz svthread ;1==Debugger 0==Clean ;) invoke Writememory,addr null_byte,byte_location,1,MM_RESTORE .if (eax!=1) ;ooopps invoke Error,CTEXT("Error WriteMemory failed") .elseif invoke Addtolist, 0, -1, CTEXT(" IsDebugPresent hidden") .endif invoke ExitThread,TRUE .endif ODBG_Pluginreset endp ; OllyDbg calls this optional function when user wants to terminate OllyDbg. ; All MDI windows created by plugins still exist. Function must return 0 if ; it is safe to terminate. Any non-zero return will stop closing sequence. Do ; not misuse this possibility! Always inform user about the reasons why ; termination is not good and ask for his decision! ODBG_Pluginclose proc C ; For automatical restoring of open windows, mark in .ini file whether ; Bookmarks window is still open. return 0 ODBG_Pluginclose endp ; Function adds items either to main OllyDbg menu (origin=PM_MAIN) or to popup ; menu in one of standard OllyDbg windows. When plugin wants to add own menu ; items, it gathers menu pattern in data and returns 1, otherwise it must ; return 0. Except for static main menu, plugin must not add inactive items. ; Item indices must range in 0..63. Duplicated indices are explicitly allowed. ODBG_Pluginmenu proc C uses ebx origin:dword, data:ptr byte, item:dword mov eax, origin ; Menu creation is very simple. You just fill in data with menu pattern. ; Some examples: ; 0 Aaa,2 Bbb|3 Ccc|,, - linear menu with 3 items, relative IDs 0, 2 and ; 3, separator between second and third item, last ; ; separator and commas are ignored; ; #A{0Aaa,B{1Bbb|2Ccc}} - unconditional separator, followed by popup menu ; A with two elements, second is popup with two ; elements and separator inbetween. .IF eax == PM_MAIN ; Plugin menu in main window invoke lstrcpy, data, CTEXT("0 &Hide,1 &Restore,2 &Option|3 &About|4 &Dumper") ;invoke lstrcpy, data, CTEXT("0 &Hide,1 &Restore|2 &About|3 &Dumper,4 &Initier") ; If your plugin is more than trivial, I also recommend to include Help. return 1 .ENDIF return 0 ODBG_Pluginmenu endp ; 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. ODBG_Pluginaction proc C origin:dword, action:dword, item:dword mov eax, origin .IF eax == PM_MAIN mov eax, action .IF !eax call get_byte_location mov byte_location,eax .if (eax) ;1==Debugger 0==Clean ;) invoke Writememory,addr null_byte,byte_location,1,MM_RESTORE .if (eax!=1) ;ooopps invoke Error,CTEXT("Error WriteMemory failed") .elseif invoke Addtolist, 0, -1, CTEXT(" IsDebugPresent hidden") .endif .endif .ELSEIF eax == 1 call get_byte_location mov byte_location,eax .if (eax) ;resore original code invoke Writememory,addr the_byte,byte_location,1,MM_RESTORE .if (eax!=1) ;ooopps invoke Error,CTEXT("Error WriteMemory failed") .elseif invoke Addtolist, 0, -1, CTEXT(" IsDebugPresent restored") .endif .endif .ELSEIF eax == 2 invoke DialogBoxParam, hinst, IDD_OPTION, hwmain, addr DlgOptionProc, NULL .ELSEIF eax == 3 ; Menu item "About", displays plugin info. invoke MessageBox, hwmain, CTEXT("IsDebuggerPresent plugin v1.4",13,10,"(IsDebuggerPresent byte Patcher)",13,10,"Copyright (C) 2oo3 SV",13,10,"MASM32 version"),\ CTEXT("IsDebuggerPresent plugin"),MB_OK or MB_ICONINFORMATION .ELSEIF eax == 4 invoke DialogBoxParam, hinst, IDD_DUMP, hwmain, addr DlgDumpProc, NULL .ENDIF .ENDIF ret ODBG_Pluginaction endp get_byte_location proc push ebx invoke Getcputhreadid .if (eax) invoke Findthread,eax ;retreive thread info assume eax:ptr t_thread push [eax].reg.base[4*4] ;base of FS pop ebx add ebx,30h invoke Readmemory,addr dw_buffer,ebx,4,MM_RESTORE mov eax,dw_buffer add eax,2h .endif pop ebx ret get_byte_location endp DlgDumpProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL dump_start:DWORD LOCAL dump_size:DWORD .IF uMsg == WM_INITDIALOG mov ofn.lStructSize,SIZEOF ofn push hWnd pop ofn.hWndOwner push hinst pop ofn.hInstance mov ofn.nMaxFile,MAXSIZE .ELSEIF uMsg == WM_CLOSE invoke SendMessage, hWnd, WM_COMMAND, IDC_BTCANCEL, 0 .ELSEIF uMsg==WM_COMMAND mov eax,wParam mov edx,wParam shr edx,16 .IF dx==BN_CLICKED .IF ax==IDC_BTCANCEL invoke EndDialog, hWnd, NULL .ELSEIF ax==IDC_BTDUMP invoke Plugingetvalue,VAL_PROCESSID ;is something loaded ?? .if (eax!=0) pushad invoke GetDlgItemText,hWnd,IDC_EDTOFFSET,addr textbuffer,10 invoke htodw,addr textbuffer mov dump_start,eax invoke GetDlgItemText,hWnd,IDC_EDTSIZE,addr textbuffer,10 invoke htodw,addr textbuffer mov dump_size,eax .if dump_start!=0 && dump_size!=0 ;Alloc Mem invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,dump_size mov hMemory_code,eax invoke GlobalLock,hMemory_code mov pMemory_code,eax ;Read in Mem invoke Readmemory,pMemory_code,dump_start,dump_size,MM_RESTORE .if (eax==dump_size) push hWnd pop ofn.hWndOwner mov ofn.Flags,OFN_OVERWRITEPROMPT mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrDefExt, OFFSET bin_extend mov ofn.lpstrFile, OFFSET textbuffer mov ofn.nMaxFile,MAXSIZE mov [textbuffer],0 ;filename buffer a vide invoke GetSaveFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR textbuffer,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,\ NULL mov hFileWrite,eax ;Save mem in file invoke WriteFile,hFileWrite,pMemory_code,dump_size,ADDR SizeWritten,NULL invoke CloseHandle,hFileWrite invoke Flash,CTEXT("File successfully writted !!") .endif .endif ;Free Mem invoke GlobalUnlock,pMemory_code invoke GlobalFree,hMemory_code .endif popad .else invoke Error,CTEXT("Error Nothing loaded") .endif .ENDIF .ENDIF .ELSE mov eax, FALSE ret .ENDIF mov eax, TRUE ret DlgDumpProc endp DlgOptionProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg == WM_INITDIALOG ;read params from ini & update windows invoke Pluginreadintfromini,hinst,addr str_idb_Autoload,0 mov auto_load,eax invoke Pluginreadintfromini,hinst,addr str_idb_Sleeptime,1000 mov sleep_time,eax invoke wsprintf,addr textbuffer,offset template,sleep_time invoke SetDlgItemText,hWnd,IDC_SLEEPTIME,addr textbuffer .if (auto_load!=0) invoke GetDlgItem,hWnd,IDC_CHK1 invoke SendMessage,eax,BM_SETCHECK,BST_CHECKED,0 .endif .ELSEIF uMsg == WM_CLOSE invoke SendMessage, hWnd, WM_COMMAND, IDC_BTCANCEL, 0 .ELSEIF uMsg==WM_COMMAND mov eax,wParam mov edx,wParam shr edx,16 .IF dx==BN_CLICKED .IF ax==IDC_BTN2 ;CANCEL invoke EndDialog, hWnd, NULL .ELSEIF ax==IDC_BTN1 ;SAVE invoke GetDlgItemText,hWnd,IDC_SLEEPTIME,addr textbuffer,10 invoke atodw,addr textbuffer mov sleep_time,eax ;save params to ini invoke Pluginwriteinttoini,hinst,addr str_idb_Sleeptime,sleep_time invoke GetDlgItem,hWnd,IDC_CHK1 invoke SendMessage,eax,BM_GETSTATE,0,0 .if eax==BST_CHECKED invoke Pluginwriteinttoini,hinst,addr str_idb_Autoload,1 .elseif invoke Pluginwriteinttoini,hinst,addr str_idb_Autoload,0 .endif invoke Flash,CTEXT("Option saved !!") .ENDIF .ENDIF .ELSE mov eax, FALSE ret .ENDIF mov eax, TRUE ret DlgOptionProc endp end DllEntryPoint