![]() |
#2
你们都要疼我哦2010-01-01 18:30
|
只有本站会员才能查看附件,请 登录
如上图,[随手画的,可能不对,以我理解解释一下]
PE文件给加载到内存后FirstThunk指向真实的函数地址,即是IAT[导入地址表]
HOOK IAT就是要把IAT里的函数地址换为自己的函数地址。
我这里假设的是OriginalFirstThunk是存在的,[听说有些PE格式构建是把OriginalFirstThuk清零的]
;;;;;;;;;;;
先查找导入表结构中是否有user32.dll这个,若是找到,再在OriginalFirstThuk里查找是否有想要HOOK的函数
若找到了,就替换自己的函数地址
这里FirstThuk里的函数序号是与OriginalFirstThuk里的是一样的。
上代码,程序看附件。[写好就没改了,代码很差,入门的兄弟可以看看,高手指点下。]

;IAT HOOK
;onepc 153785587
;ml /c /coff dll.asm
;Link /subsystem:windows /Dll /Def:dll.def dll.obj ;/section:.bss,S
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include shell32.inc
includelib shell32.lib
.data
szTitle db 'Hook',0
szConten db 'Hook MessageBox OK',0
szMesg db 'MessageBoxA',0
szDll db 'user32.dll',0
szWZ db 'http://bbs.',0
szFmatN db '%08x',0
szFmat db '%s',0
.data?
hModule dd ?
hdllModule dd ?
;oldFunAddr dd ?;旧函数地址
newFunAddr dd ?;新函数地址
dwNum dd ?
dwoldAccess dd ?
dwNewAccess dd ?
dwFirstuck dd ?
dwProcess dd ?
szBuffer db 250 dup (?)
.code
_MyHookFun proc
pop eax
add esp,10h
push eax
invoke ShellExecute,0,0,addr szWZ,0,0,SW_NORMAL
ret
_MyHookFun endp
;;;;;;;;;;;;;;;;;;;;;;;;;;
_SetApiHook proc
invoke GetModuleHandle,NULL ;得到的是exe进程的实例句柄
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,eax
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov hModule,eax
mov esi,eax
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov ebx,[esi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
add ebx,hModule;RVA+hModule=在内存的实际地址
mov esi,ebx ;指向内存中的导入表地址
assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
.while [esi].OriginalFirstThunk || [esi].TimeDateStamp || [esi].ForwarderChain || [esi].FirstThunk || [esi].Name1
mov edi,[esi].Name1 ;指向DLL NAME 的RVA
add edi,hModule ;在内存中实际的地址
invoke lstrcmpi,edi,addr szDll ;比较不区分大小写 返回0表示相等
.if !eax ;表示找到dll文件
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,edi
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov edx,hModule
add edx,[esi].FirstThunk ;在内存中找到dll这个结构的,指向真实的函数入口地址。[FirstThunk偏移+内存地址]
mov dwFirstuck,edx ;第一个地址
; cmp [esi].OriginalFirstThunk,0
; jz _exit
mov edi,hModule
add edi,[esi].OriginalFirstThunk ;指向IMAGE_THUNK_DATA结构数组[OriginalFirstThunk没有给清零的话]
mov dwNum,0
.while DWORD PTR [edi]!=0
.if DWORD ptr [edi] & 80000000h ;当双字最高位为0时[表示函数以字符串类型的函数名方式导入],这时低位是一个RVA指向IMAGE_IMPORT_BY_NAME
inc dwNum ;计数加1
.else
inc dwNum ;计数加1
mov ebx,hModule
add ebx,DWORD PTR [edi] ;edi是一个RVA值
assume ebx:ptr IMAGE_IMPORT_BY_NAME
invoke lstrcmpi,addr [ebx].Name1,addr szMesg
.if !eax ;找到相等的函数
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,addr [ebx].Name1
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
; pushad
; invoke wsprintf,addr szBuffer,addr szFmatN,dwNum
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov eax,dwNum
dec eax
mov ecx,4
mul ecx
mov edx,dwFirstuck
add edx,eax ;序号与OriginalFirstThunk相同
; pushad
; invoke wsprintf,addr szBuffer,addr szFmatN,edx
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov dwFirstuck,edx
invoke VirtualProtect,edx, sizeof DWORD, PAGE_WRITECOPY, addr dwoldAccess;设为可写
invoke GetCurrentProcess;当前进程伪句柄,需要当前进程的时候可以用
mov dwProcess,eax
mov edx,dwFirstuck
mov eax,offset _MyHookFun
mov newFunAddr,eax
invoke WriteProcessMemory,dwProcess,edx,addr newFunAddr,sizeof DWORD,NULL
mov edx,dwFirstuck
invoke VirtualProtect,edx, sizeof DWORD, dwoldAccess, addr dwNewAccess; 恢复之前的访问属性
jmp _exit
.endif
.endif
add edi,4
.endw
jmp _exit
.endif
add esi,sizeof IMAGE_IMPORT_DESCRIPTOR ;指向下个结构
.endw
_exit:
ret
assume esi:nothing
_SetApiHook endp
DLLEntry proc _hInstance,_dwReason,_dwReserved ;_hInstance动态链接库的实例句柄
local @dwThreadID
mov eax,_dwReason
.if eax == DLL_PROCESS_ATTACH
push _hInstance
pop hdllModule ;保存DLL的句柄
invoke CreateThread,NULL,0,offset _SetApiHook,NULL,\
NULL,addr @dwThreadID
invoke CloseHandle,eax
.endif
mov eax,TRUE ;
ret
DLLEntry endp
End DLLEntry
;onepc 153785587
;ml /c /coff dll.asm
;Link /subsystem:windows /Dll /Def:dll.def dll.obj ;/section:.bss,S
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include shell32.inc
includelib shell32.lib
.data
szTitle db 'Hook',0
szConten db 'Hook MessageBox OK',0
szMesg db 'MessageBoxA',0
szDll db 'user32.dll',0
szWZ db 'http://bbs.',0
szFmatN db '%08x',0
szFmat db '%s',0
.data?
hModule dd ?
hdllModule dd ?
;oldFunAddr dd ?;旧函数地址
newFunAddr dd ?;新函数地址
dwNum dd ?
dwoldAccess dd ?
dwNewAccess dd ?
dwFirstuck dd ?
dwProcess dd ?
szBuffer db 250 dup (?)
.code
_MyHookFun proc
pop eax
add esp,10h
push eax
invoke ShellExecute,0,0,addr szWZ,0,0,SW_NORMAL
ret
_MyHookFun endp
;;;;;;;;;;;;;;;;;;;;;;;;;;
_SetApiHook proc
invoke GetModuleHandle,NULL ;得到的是exe进程的实例句柄
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,eax
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov hModule,eax
mov esi,eax
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
mov ebx,[esi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
add ebx,hModule;RVA+hModule=在内存的实际地址
mov esi,ebx ;指向内存中的导入表地址
assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
.while [esi].OriginalFirstThunk || [esi].TimeDateStamp || [esi].ForwarderChain || [esi].FirstThunk || [esi].Name1
mov edi,[esi].Name1 ;指向DLL NAME 的RVA
add edi,hModule ;在内存中实际的地址
invoke lstrcmpi,edi,addr szDll ;比较不区分大小写 返回0表示相等
.if !eax ;表示找到dll文件
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,edi
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov edx,hModule
add edx,[esi].FirstThunk ;在内存中找到dll这个结构的,指向真实的函数入口地址。[FirstThunk偏移+内存地址]
mov dwFirstuck,edx ;第一个地址
; cmp [esi].OriginalFirstThunk,0
; jz _exit
mov edi,hModule
add edi,[esi].OriginalFirstThunk ;指向IMAGE_THUNK_DATA结构数组[OriginalFirstThunk没有给清零的话]
mov dwNum,0
.while DWORD PTR [edi]!=0
.if DWORD ptr [edi] & 80000000h ;当双字最高位为0时[表示函数以字符串类型的函数名方式导入],这时低位是一个RVA指向IMAGE_IMPORT_BY_NAME
inc dwNum ;计数加1
.else
inc dwNum ;计数加1
mov ebx,hModule
add ebx,DWORD PTR [edi] ;edi是一个RVA值
assume ebx:ptr IMAGE_IMPORT_BY_NAME
invoke lstrcmpi,addr [ebx].Name1,addr szMesg
.if !eax ;找到相等的函数
; pushad
; invoke wsprintf,addr szBuffer,addr szFmat,addr [ebx].Name1
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
; pushad
; invoke wsprintf,addr szBuffer,addr szFmatN,dwNum
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov eax,dwNum
dec eax
mov ecx,4
mul ecx
mov edx,dwFirstuck
add edx,eax ;序号与OriginalFirstThunk相同
; pushad
; invoke wsprintf,addr szBuffer,addr szFmatN,edx
; invoke MessageBox,NULL,addr szBuffer,addr szConten,0
; popad
mov dwFirstuck,edx
invoke VirtualProtect,edx, sizeof DWORD, PAGE_WRITECOPY, addr dwoldAccess;设为可写
invoke GetCurrentProcess;当前进程伪句柄,需要当前进程的时候可以用
mov dwProcess,eax
mov edx,dwFirstuck
mov eax,offset _MyHookFun
mov newFunAddr,eax
invoke WriteProcessMemory,dwProcess,edx,addr newFunAddr,sizeof DWORD,NULL
mov edx,dwFirstuck
invoke VirtualProtect,edx, sizeof DWORD, dwoldAccess, addr dwNewAccess; 恢复之前的访问属性
jmp _exit
.endif
.endif
add edi,4
.endw
jmp _exit
.endif
add esi,sizeof IMAGE_IMPORT_DESCRIPTOR ;指向下个结构
.endw
_exit:
ret
assume esi:nothing
_SetApiHook endp
DLLEntry proc _hInstance,_dwReason,_dwReserved ;_hInstance动态链接库的实例句柄
local @dwThreadID
mov eax,_dwReason
.if eax == DLL_PROCESS_ATTACH
push _hInstance
pop hdllModule ;保存DLL的句柄
invoke CreateThread,NULL,0,offset _SetApiHook,NULL,\
NULL,addr @dwThreadID
invoke CloseHandle,eax
.endif
mov eax,TRUE ;
ret
DLLEntry endp
End DLLEntry
只有本站会员才能查看附件,请 登录