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
相关文章推荐
- CSS3 Media Queries详细介绍和使用实例
- VS2015 +EF6 连接MYSQL数据库生成实体
- 百度地图搜索经纬度代码
- mysqldump原理5
- 2016年7月8日公司集体的集会,巴南区的樵坪度假村
- [C#6] 6-表达式形式的成员函数
- (OK) 手动 添加 删除 bridge tap — tunctl — brctl
- 启动hadoop 2.6遇到的datanode启动不了
- linux分区工具parted使用
- CodeForces 682B Alyona and Mex
- MySQL 开启二进制日志记录
- Android平台下使用OpenCV绘制图形
- 如何进行前后端分离
- Jenkins+SVN+Maven+Shell 实现项目一键发布
- ADO.net:数据库的增删改查的练习题
- python基础——使用dict和set
- 实现Nginx Upload 模块 功能上传文件。
- CSS3知识
- 华为OJ 初级:进制转换
- mysqldump原理4