标 题: 【原创】必备绝技--Hook大法( 上 )
【作者声明】: 这没有什么新鲜东西,其内容全部来自于前辈,姑且当作学习笔记。文字用自己的话写出,四段代码均出自别人(知道作者的,以注明),但短小精悍,就写在一起了,便于察看。欢迎指正。 -------------------------------------------------------------------------------- 【详细过程】
hook概念:是一种通过更改程序的数据结构或代码结构从而改变程序运行路线的一种方法。(纯属本人自己观点)
分类:从上面的概念来看,一种是改变程序的数据结构,如:IAT-hook,Dll-inject及Direct Kernel Object Manipulation(DKOM)。一种是Inline Function Hooking。
用途:现在这种方法普遍运用于各类程序中,如加壳,杀软,病毒,Rootkits等等。
本文从难以程度上主要分三块详细介绍:一.用户模式Hook:IAT-hook,Dll-inject二.内核模式Hook:ssdt-hook,idt-hook,int 2e/sysenter-hook三.Inline Function Hook; 这次先来看第一部分 Ⅰ.用户模式Hook 一.IAT-hooking
(一)一般原理:IAT是Import Address Table(输入地址表)的简写,这需要你知道关于win PE格式的了解。现在应用程序中的大多数函数都是windows api,而这些函数一般都由几个系统dll导出,如user32.dll,kernel32.dll,advapi32.dll等。如果程序要运用这些函数,就的从这些dll文件中导入,程序会把导入的函数放到一个叫IAT的数据结构中。我们可以先找到自己需要hook的函数,然后把目标函数的地址改成我们自己的hook函数,最后在恢复到目标函数的地址。这样一来,目标函数被调用时,我们的hook函数也就别调用了。如果这个hook函数是病毒,是后门,是。。。。。。。。由于是在目标函数进程的空间内,所以这个hook函数也就不会被发现。
关于WIN PE格式的详细知识可参见:http://bbs.pediy.com/showthread.php?t=31840及<<加密与解密>>。 (二)大体框架:这里用伪码给个一般框架,以便有个大体印象。 文件1:myhookfun() {
可以创建一个新的线程,去执行木马或后门等功能 }
文件2: include <文件1>
寻找目标模块(GetModuleHandle) if(目标模块找到)
根据pe结构,在目标模块中定位目标函数的IAT地址(这个地址在加载时就确定了) if (目标函数在IAT中的地址找到) 用我们的myhookfun()地址取代 esle 退出 esle 退出
当然也可以合成一个文件,但这样分开的好处是可以实现模块化,可以分别关心各自的功能,也便于以后重用。
(三)代码实例: .486
.model flat, stdcall option casemap:none
include windows.inc include kernel32.inc includelib kernel32.lib include user32.inc includelib user32.lib .data
szMsgTitle db \T Hook\ szModule db \
szTargetFunc db \
szHooked db \hooked function - Seems to have worked.\ szFail db \ .data?
IATHook PROTO STDCALL :DWORD, :DWORD, :DWORD HookProc PROTO STDCALL :LPVOID .code
HookProc proc Arg1:LPVOID
invoke MessageBox, NULL, addr szHooked, addr szMsgTitle, MB_OK ret HookProc endp
IATHook proc pDLLName:LPVOID, pOldAddr:LPVOID, pNewAddr:LPVOID LOCAL hModule:HANDLE LOCAL dwVirtualAddr:DWORD LOCAL dwOrigProtect:DWORD LOCAL dwDllFound:DWORD LOCAL dwFunctionFound:DWORD ;Local variables
.if pDLLName == NULL ;Check for NULL pointer xor eax, eax ret .endif
.if pOldAddr == NULL ;Check for NULL pointer xor eax, eax ret .endif
.if pOldAddr == NULL
;Check for NULL pointer xor eax, eax ret .endif
mov dwDllFound, 0 mov dwFunctionFound, 0 ;Initialize
invoke GetModuleHandle, NULL ;Get the main module's base address mov hModule, eax ;Copy it into hModule
mov edi, hModule
assume edi:ptr IMAGE_DOS_HEADER ;Make edi act as IMAGE_DOS_HEADER struct .if edi == NULL
;Check for NULL pointer xor eax, eax ret ;Return 0 .endif
.if [edi].e_magic != IMAGE_DOS_SIGNATURE ;0x4D 0x5A (MZ) xor eax, eax ret ;Return 0 .endif
add edi, [edi].e_lfanew
;pNtHeader = (IMAGE_NT_HEADERS*)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
assume edi:ptr IMAGE_NT_HEADERS ;Make edi act as IMAGE_NT_HEADERS struct .if edi == NULL
;Check for NULL pointer xor eax, eax ret ;Return 0 .endif
.if [edi].Signature != IMAGE_NT_SIGNATURE
;If it's an invalid NT header ;0x50 0x45 0x00 0x00 (PE\\0\\0) xor eax, eax ret ;Return 0 .endif
mov edx, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress mov dwVirtualAddr, edx
;Copy the VirtualAddress into dwVirtualAddr
.if dwVirtualAddr == 0 ;Invalid virtual address xor eax, eax ret ;Return 0 .endif
mov edi, hModule add edi, dwVirtualAddr
;pImportHeader = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)pDosHeader + dwVirtualAddr);
assume edi:ptr IMAGE_IMPORT_DESCRIPTOR ;Make edi act as IMAGE_IMPORT_DESCRIPTOR struct .if edi == NULL
;Check for NULL pointer xor eax, eax ret ;Return 0 .endif
.while [edi].Name1 != NULL mov ecx, hModule add ecx, [edi].Name1
;pModuleLabel = (char*)((DWORD)pDosHeader + (DWORD)pImportHeader->Name);
mov edx, pDLLName invoke lstrcmpi, ecx, edx
;Check if this is the DLL we are looking for
.if eax == 0
;This is the DLL we are looking for mov dwDllFound, 1
;Set ecx to 0, so we know later if the DLL was found
.break .endif
add edi, sizeof IMAGE_IMPORT_DESCRIPTOR ;Next DLL .endw
.if dwDllFound != 1 ;If the DLL wasn't found xor eax, eax ret ;Return 0 .endif
mov edi, [edi].FirstThunk add edi, hModule
;pThunkData = (IMAGE_THUNK_DATA*)((DWORD)pDosHeader + (DWORD)pImportHeader->FirstThunk);
assume edi:ptr IMAGE_THUNK_DATA ;Make edi act as IMAGE_THUNK_DATA struct
.while [edi].u1.Function != NULL mov ecx, hModule add ecx, [edi].u1.Function
mov edx, [edi].u1.Function
;Copies the current functions address (in the IAT table) into edx
.if pOldAddr == edx
;If this is the function we are going to hook lea ebx, [edi].u1.Function
;Copy the address in the table that the function is stored in, into ebx
invoke VirtualProtect, ebx, 4, PAGE_WRITECOPY, addr dwOrigProtect
;Unprotect the memory where we are going to overwrite (We need 4 bytes --- DWORD = 4 bytes)
mov eax, pNewAddr
;Copy the address we are going to replace it with into eax mov [ebx], eax ;Patch the address
invoke VirtualProtect, ebx, 4, addr dwOrigProtect, NULL ;Restore the original protection level
搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新教学研究必备绝技--Hook大法( 上) 全文阅读和word下载服务。
相关推荐: