您的位置:首页 > 其它

hook后的重定位原理

2016-07-08 21:49 447 查看

前言

这几天学了ApiHook, 原理大概知道, 忙的没时间想.

消化了几天后, 突然想明白了.

ps : 在hook后的代码中使用CRT函数不靠谱, 使用API才好.

* 使用CRT函数无法判断这个函数在目标程序中是否一定存在

如果用API, 可以通过LoadLibrary + GetProcAddress来判断winapi是否可以使用

试验代码片段

;;================================================================================
;; HOOK处理开始 - WriteFile
;; WRITEFILE
;;================================================================================
INJECT_CODE_BLOCK_BEGIN_WRITEFILE:
fnHookProc_WriteFile Proc C  hFile:HANDLE,
lpBuffer:LPCVOID,
nNumberOfBytesToWrite:DWORD,
lpNumberOfBytesWritten:LPDWORD,
lpOverlapped:DWORD

LOCAL pLogFile:DWORD
LOCAL nStrLen:DWORD

; Hook处理函数
push ebx ; 保护ebx
xor eax, eax
mov pLogFile, eax

; hook后的重定位原理
; 未注入段orgSeg注入后的映像为注入段hookSeg
; a,c为orgSeg上的2点
; a',c'为hookSeg上对应a,c的2点
; a' - a = c' - c
; offset = c' -c
; c'= offset + c

call NEXT
NEXT:
pop ebx ; ebx是hook后的a'

; offset = a' - a
; a是hook前的 offset NEXT
sub ebx, offset NEXT ; ebx是注入方和被注入方的地址偏移
; 此时, ebx = a' - a = offset

; c点为orgSeg中的变量或函数
; 如果要访问hook后的c'点, 就是 ebx + offset c

; 写文件
.if ([ebx + offset g_IsMyLogFileDoing_forWriteFile] == FALSE)
mov [ebx + offset g_IsMyLogFileDoing_forWriteFile], TRUE
; 如果不是自己的日志文件操作, 记录日志

; 打开文件
; pFile = fopen("c:\\test2048.txt", "ab+");
push ebx
lea eax, [ebx + offset g_szFileMode_forWriteFile]
push eax
lea eax, [ebx + offset g_szMyLogFileName_forWriteFile]
push eax
call [ebx + offset g_pfn_fopen_forWriteFile]
add esp, sizeof(DWORD) * 2
pop ebx

mov pLogFile, eax
.if eax <= 0
jmp @@err
.endif

; 格式化Buf
; wsprintf(szBuf, "create file : %s\r\n", "Hello 测试");
; g_buffmt_forWriteFile db 'Write File : hFile = 0x%P, nNumberOfBytesToWrite = 0x%X, content : %X, %X, %X, %X, %X', 0dh, 0ah, 0,
push ebx
mov ecx, 5
@@push_content:
.if (nNumberOfBytesToWrite >= ecx)
mov al, byte ptr lpBuffer[ecx - 1]
movzx eax, al
.else
xor eax, eax
.endif
push eax
loop @@push_content

push nNumberOfBytesToWrite
push hFile

lea eax, [ebx + offset g_buffmt_forWriteFile]
push eax
lea eax, [ebx + offset g_szBuffer_forWriteFile]
push eax
call [ebx + offset g_pfn_sprintf_forWriteFile]
add esp, sizeof(DWORD) * 9

pop ebx

.if eax <= 0
jmp @@err
.endif

; 算出Buf中的字符串长度
; iLen = wcslen(szBuf);
lea eax, [ebx + offset g_szBuffer_forWriteFile]
push eax
call [ebx + offset g_pfn_strlen_forWriteFile]
add esp, sizeof(DWORD) * 1

.if eax <= 0
jmp @@err
.endif

mov nStrLen, eax

; 写文件
; fwrite(szBuf, sizeof(WCHAR), iLen, pFile);
push ebx
push pLogFile
push nStrLen
push sizeof(CHAR)
lea eax, [ebx + offset g_szBuffer_forWriteFile]
push eax
call [ebx + offset g_pfn_fwrite_forWriteFile]
add esp, sizeof(DWORD) * 4
pop ebx
@@err:
.if (pLogFile != NULL)
push ebx
push pLogFile
call [ebx + offset g_pfn_fclose_forWriteFile]
add esp, sizeof(DWORD) * 1
pop ebx
.endif
mov [ebx + offset g_IsMyLogFileDoing_forWriteFile], FALSE
.endif

; 恢复寄存器
pop ebx
leave
; 执行Hook点原始代码
push ebp
mov ebp, esp

JMP_CODE_WRITEFILE::
db 0e9h ; 跳转指令
g_JmpOffset_WriteFile dd 0 ; 算出的Hook点下面的指令地址

; JMP_CODE处跳走了, 这里定义变量是安全的
g_IsMyLogFileDoing_forWriteFile dd FALSE ; 我正在写日志文件
g_szBuffer_forWriteFile db 4000h dup(0) ; 缓冲区
g_szMyLogFileName_forWriteFile db 'd:\MyLogFile_WriteFile.txt', 0
g_szFileMode_forWriteFile db 'ab+', 0

g_buffmt_forWriteFile db 'Write File : hFile = %d, nNumberOfBytesToWrite = %d, content : %d, %d, %d, %d, %d', 0dh, 0ah, 0,

g_pfn_fopen_forWriteFile dd 0
g_szApiName_fopen_forWriteFile db 'crt_fopen', 0

g_pfn_fwrite_forWriteFile dd 0
g_szApiName_fwrite_forWriteFile db 'crt_fwrite', 0

g_pfn_fclose_forWriteFile dd 0
g_szApiName_fclose_forWriteFile db 'crt_fclose', 0

g_pfn_sprintf_forWriteFile dd 0
g_szApiName_sprintf_forWriteFile db 'crt_sprintf', 0

g_pfn_swprintf_forWriteFile dd 0
g_szApiName_swprintf_forWriteFile db 'crt_swprintf', 0

g_pfn_strlen_forWriteFile dd 0
g_szApiName_strlen_forWriteFile db 'crt_strlen', 0

g_pfn_wcslen_forWriteFile dd 0
g_szApiName_wcslen_forWriteFile db 'crt_wcslen', 0

g_szApiName_forWriteFile db 'WriteFile', 0 ; API名称

g_pfnMessageBox_forWriteFile dd 0
g_szApiNameMsgBox_forWriteFile db 'MessageBoxW', 0

g_cAryHookPtOrgCmd_forWriteFile db 8bh, 0ffh, 55h, 8bh, 0ech ; API特征码

fnHookProc_WriteFile endp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: