<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; FileName: msgbox2.asm ; Function: Demo how to hook MessageBoxA locally ; Author: Purple Endurer ; ; log ;-------------------------------------------------- ; 2006-07-10 Optimized code ; 2006-07-08 Created, success under Windows XP +SP1 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .586p .model flat, stdcall option casemap: none include /masm32/ include/windows.inc include /masm32/ include/kernel32.inc include /masm32/ include/user32.inc includelib /masm32/ lib/kernel32.lib includelib /masm32/ lib/user32.lib m_m2m MACRO d1, d2 push d2 pop d1 ENDM MEMORY_BASIC_INFORMATION_SIZE EQU 28 .data g_szUser32dll DB "user32.dll", 0 g_szMsgBox DB "MessageBoxA", 0 g_szHookedOK db " has been hooked OK!", 0 .data? g_dwOld_protect DD ? g_lpfnMessagBox dword ? g_dbOldCode db 10 dup(?) g_dwReaded dword ? g_hCurProc HANDLE ? .code start: do_hook: invoke GetModuleHandle, ADDR g_szUser32dll invoke GetProcAddress, eax, ADDR g_szMsgBox mov edi, eax ;finally got MessageBoxA address mov g_lpfnMessagBox, eax push 0 push OFFSET g_szMsgBox push OFFSET g_szMsgBox push 0 call g_lpfnMessagBox ;确认得到MessageBoxA的地址 invoke GetCurrentProcess mov g_hCurProc, eax ; BOOL ReadProcessMemory( ; HANDLE hProcess, // handle of the process whose memory is read ; LPCVOID lpBaseAddress, // address to start reading ; LPVOID lpBuffer, // address of buffer to place read data ; DWORD nSize, // number of bytes to read ; LPDWORD lpNumberOfBytesRead // address of number of bytes read ; ); invoke ReadProcessMemory, eax, g_lpfnMessagBox, ADDR g_dbOldCode, 10, ADDR g_dwReaded test eax, eax jz @FinalMsgBox invoke VirtualAlloc, 0, MEMORY_BASIC_INFORMATION_SIZE, MEM_COMMIT, PAGE_READWRITE test eax, eax jz @FinalMsgBox mov esi, eax ;allocation for MBI invoke VirtualQuery, edi, esi, MEMORY_BASIC_INFORMATION_SIZE ;typedef struct _MEMORY_BASIC_INFORMATION { // mbi ; PVOID BaseAddress; // base address of region ; PVOID AllocationBase; // allocation base address ; DWORD AllocationProtect; // initial access protection ; DWORD RegionSize; // size, in bytes, of region ; DWORD State; // committed, reserved, free ; DWORD Protect; // current access protection ; DWORD Type; // type of pages ;} MEMORY_BASIC_INFORMATION; test eax, eax jz @free_mem invoke FlushInstructionCache, g_hCurProc, edi, 5 ;just to be sure lea eax,[ esi+014h] push eax push PAGE_EXECUTE_READWRITE lea eax, [ esi+0Ch] push [ eax] push [ esi] call VirtualProtect ;we will change protection for a moment, so we will be able to write there test eax, eax jz @free_mem mov byte ptr [ edi], 0E9h ;写入jmp跳转指令 mov eax, OFFSET @newMsgBox ;计算跳转地址 sub eax, edi sub eax, 5 inc edi stosd ;传送32位跳转地址 push OFFSET g_dwOld_protect lea eax, [ esi+014h] push [ eax] lea eax, [ esi+0Ch] push [ eax] push [ esi] call VirtualProtect ;return back the protection of page @free_mem: push MEM_RELEASE push 0 push esi call VirtualFree ;free memory @FinalMsgBox: invoke MessageBoxA, 0, ADDR g_szMsgBox, ADDR g_szMsgBox, 0 invoke ExitProcess, 0 @newMsgBox: ;004010CD ;mov [esp+16], MB_ICONINFORMATION ;修改信息ICON m_m2m [ esp+16], MB_ICONINFORMATION ;mov [esp+12], OFFSET g_szHookedOK ;修改标题 mov eax, [ esp+8] ;修改信息内容 invoke lstrcat, eax, ADDR g_szHookedOK ; BOOL WriteProcessMemory( ; HANDLE hProcess, // handle to process whose memory is written to ; LPVOID lpBaseAddress, // address to start writing to ; LPVOID lpBuffer, // pointer to buffer to write data to ; DWORD nSize, // number of bytes to write ; LPDWORD lpNumberOfBytesWritten // actual number of bytes written ; ); invoke WriteProcessMemory, g_hCurProc, g_lpfnMessagBox, ADDR g_dbOldCode, 10, ADDR g_dwReaded jmp g_lpfnMessagBox ;push g_lpfnMessagBox ;ret; 10H end