I am trying to do a local api hook for the purposes of debuging. I thought it would be as simple as replacing the address of the imported function with the address of the hook procedure (in the import table). When I try to write to the the import table I am getting an access violation. Is this the correct way to hook apis locally? or is there a better way?
OS is windows xp pro
Posted on 2004-02-08 23:04:20 by ENF
That should work, as long as you don't need to hook GetProcAddress'ed imports... sounds a bit weird that you get access violations while modyfying the IAT, though? Sure you're patching the correct address? Otherwise, try WriteProcessMemory, or temporarily using VirtualProtect - I don't think I've ever seen the IAT in non-writable sections though...
Posted on 2004-02-09 02:45:47 by f0dder
Maybe this help... using seh
Posted on 2004-02-09 07:23:15 by comrade
comrade
Nice example code :alright:
I wonder what would happen if this tenique where used on a 9x system, since DLL memory is shared then would other apps calling MessageBoxIndirectA generate an exception as well?

f0dder
As far as I know I'm writing to the correct address.


Here is the code I was using to hook the api
.386                    

.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib

.data
szText db "Local API Hook",0
szUser32 db "user32.dll",0
NameMessageBoxA db "MessageBoxA", 0
.data?
ImageBase dd ?
.code
start:
invoke GetModuleHandle, NULL
mov ImageBase, eax
mov esi, ImageBase
assume esi:PTR IMAGE_DOS_HEADER
cmp [esi].e_magic, 'ZM'
jne Quit
add esi, [esi].e_lfanew
assume esi:PTR IMAGE_NT_HEADERS
cmp [esi].Signature, 'EP'
jne Quit
mov esi, [esi].OptionalHeader.DataDirectory.VirtualAddress+8
add esi, ImageBase
assume esi:PTR IMAGE_IMPORT_DESCRIPTOR
@@:
mov ecx, 11
mov edi, [esi].Name1
add edi, ImageBase
push edi
push esi
mov esi, offset szUser32
cld
repz cmpsb
pop esi
pop edi
je @f
add esi, SIZEOF IMAGE_IMPORT_DESCRIPTOR
jmp @b
@@:
mov edi, [esi].OriginalFirstThunk
add edi, ImageBase ;edi pointer to IMAGE_THUNK_DATA array
mov esi, [esi].FirstThunk
add esi, ImageBase ;esi points to IMAGE_THUNK_DATA array
assume esi:NOTHING
assume edi:NOTHING
;@@:
call HookAPI
add edi, 4
add esi, 4
cmp BYTE PTR [esi], 0
jnz @b
Quit:
invoke MessageBox, NULL, addr szText, NULL, MB_OK
invoke ExitProcess, 0
HookAPI:
push edi
push esi

mov esi, [edi]
add esi, ImageBase
;esi pointer to IMAGE_IMPORT_BY_NAME
add esi, 2
mov edi, offset NameMessageBoxA
mov ecx, 12
cld
repe cmpsb
pop esi
pop edi
jne NoPatch
mov eax, offset HookMessageBoxA
mov [esi], eax; crash here
NoPatch:
retn 0
HookMessageBoxA PROC hwnd:DWORD, lpText:DWORD, lpTitle:DWORD, dwFlag:DWORD
;hook proc code
ret
HookMessageBoxA ENDP

end start


EDIT
Works after calling VirtualProtect on the address.
Posted on 2004-02-09 13:47:03 by ENF

comrade
Nice example code :alright:
I wonder what would happen if this tenique where used on a 9x system, since DLL memory is shared then would other apps calling MessageBoxIndirectA generate an exception as well?



yeah, its pretty lame
Posted on 2004-02-09 19:43:18 by comrade
Of course this is only for debugging propourses as you need, then and only then this is better, but anyway this is very easy to understand, and is very simple and short code.
Posted on 2004-05-16 02:50:05 by mauricioprado