;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 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