HooK原理简析
来源:互联网 发布:mac电脑磁盘在哪里 编辑:程序博客网 时间:2024/06/06 03:16
通过反汇编代码的跟进,了解Hook的工作原理(使用Detours库实现Hook)
示例代码
#include "stdafx.h"#include <windows.h>#include <detours.h>#pragma comment(lib,"detours.lib")//1.拿到需要Hook的地址 操作系统里面MessageboxA里面的地址static int (WINAPI* OldMessageBoxA)( HWND, LPCSTR, LPCSTR, UINT) = MessageBoxA;//2.需要跳至的地方int WINAPI NewMessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType){ if (strcmp(lpText, "This is zy") != 0) { return OldMessageBoxA(hWnd, "You are ugly!", "Sorry", MB_OK); } return OldMessageBoxA(hWnd, "This is zy", "Everyone", MB_OK);}//3.开始进行Hook地址bool Hook() { // 相关的初始化信息 DetourTransactionBegin(); // 更新线程信息 DetourUpdateThread(GetCurrentThread()); // 挂载我们的hook函数(NeeMessagwBoxA)到MessageBoxA函数的地址上 DetourAttach(&(PVOID&)OldMessageBoxA, NewMessageBoxA); return NO_ERROR == DetourTransactionCommit();}// 卸载Hookbool UnHook(){ DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)OldMessageBoxA, NewMessageBoxA); return NO_ERROR == DetourTransactionCommit();}int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd ){ //跨进程改不了 //因为我们当前的这个Hook就是我们本进程 //如果想跨进程,在Dll中Hook,然后注入 全局Hook //Hook在哪个地方 //检测Hook CRC、 //Hook后如何让保证系统的稳定,这个做的Hook实在R3层,R0也能Hook MessageBoxA(NULL, "This is Hook", "Hook", MB_OK); Hook(); MessageBoxA(NULL, "This is Hook", "Hook", MB_OK); UnHook(); MessageBoxA(NULL, "This is Hook", "Hook", MB_OK);// 加载Hook的Dll文件// HMODULE hModule = LoadLibraryA("HooKDll.dll");// if (hModule == NULL)// {// printf("LoadLibraryA faild!\n");// }// MessageBoxA(NULL, "This is Hook", "Hook", MB_OK);// FreeLibrary(hModule); return 0;}
运行结果:
反汇编解析
接下来我们进入到反汇编格式查看下实现
第一句MessageBoxA(NULL, “This is Hook”, “Hook”, MB_OK);
// 压栈数据,调用MessageBoxA该API0124280E mov esi,esp 01242810 push 0 01242812 push offset string "Hook" (0124AC64h) 01242817 push offset string "This is Hook" (0124BD88h) 0124281C push 0 0124281E call dword ptr [__imp__MessageBoxA@16 (0124F0C8h)] // 查看MessageBox函数的首地址76EEFDAE mov edi,edi 76EEFDB0 push ebp 76EEFDB1 mov ebp,esp 76EEFDB3 push 0 76EEFDB5 push dword ptr [ebp+14h] 76EEFDB8 push dword ptr [ebp+10h] 76EEFDBB push dword ptr [ebp+0Ch] 76EEFDBE push dword ptr [ebp+8] 76EEFDC1 call 76EEFD66 76EEFDC6 pop ebp 76EEFDC7 ret 10h
具体指令的作用就不一一解释了,这不是重点。
可以看到MessageBox的函数首地址为76A7FDAE,该处的汇编指令为
mov edi,edi->不难看出,该指令的作用就是没有作用!只是为了方面扩展
经过Hook后
第二句MessageBoxA(NULL, “This is Hook”, “Hook”, MB_OK);
// 1、压栈数据,调用MessageBoxA该API01242830 mov esi,esp 01242832 push 0 01242834 push offset string "Hook" (0124AC64h) 01242839 push offset string "This is Hook" (0124BD88h) 0124283E push 0 01242840 call dword ptr [__imp__MessageBoxA@16 (0124F0C8h)] // 2、跟进查看MessageBox函数的首地址,此处原本应该是 mov edi,edi76EEFDAE jmp NewMessageBoxA (01241424h) 76EEFDB3 push 0 76EEFDB5 push dword ptr [ebp+14h] 76EEFDB8 push dword ptr [ebp+10h] 76EEFDBB push dword ptr [ebp+0Ch] 76EEFDBE push dword ptr [ebp+8] 76EEFDC1 call 76EEFD66 76EEFDC6 pop ebp 76EEFDC7 ret 10h // 3、在01241424h地址处,进行跳转到012426C0h(我们真正的函数首地址)01241424h jmp NewMwssageBoxA (012426C0h) int WINAPI NewMwssageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType){012426C0 push ebp 012426C1 mov ebp,esp 012426C3 sub esp,0C0h 012426C9 push ebx 012426CA push esi 012426CB push edi 012426CC lea edi,[ebp-0C0h] 012426D2 mov ecx,30h 012426D7 mov eax,0CCCCCCCCh 012426DC rep stos dword ptr es:[edi] if (strcmp(lpText, "This is zy") != 0)012426DE push offset string "This is zy" (0124AC30h) 012426E3 mov eax,dword ptr [lpText] 012426E6 push eax 012426E7 call _strcmp (01241136h) 012426EC add esp,8 012426EF test eax,eax 012426F1 je NewMwssageBoxA+54h (01242714h) { return OldMwssageBoxA(hWnd, "You are ugly!", "Sorry", MB_OK);//进行数据的压栈012426F3 mov esi,esp 012426F5 push 0 012426F7 push offset string "Sorry" (0124AC40h) 012426FC push offset string "You are ugly!" (0124AC48h) 01242701 mov eax,dword ptr [hWnd] 01242704 push eax // 我们的程序将从此处跳转01242705 call dword ptr [OldMwssageBoxA (0124E2D0h)] // 进行 RTC 运行时检错0124270B cmp esi,esp 0124270D call __RTC_CheckEsp (012411AEh) 01242712 jmp NewMwssageBoxA+73h (01242733h) } return OldMwssageBoxA(hWnd, "This is zy", "Everyone", MB_OK);01242714 mov esi,esp 01242716 push 0 01242718 push offset string "Everyone" (0124AC58h) 0124271D push offset string "This is zy" (0124AC30h) 01242722 mov eax,dword ptr [hWnd] 01242725 push eax 01242726 call dword ptr [OldMwssageBoxA (0124E2D0h)] 0124272C cmp esi,esp 0124272E call __RTC_CheckEsp (012411AEh) }01242733 pop edi 01242734 pop esi 01242735 pop ebx 01242736 add esp,0C0h 0124273C cmp ebp,esp 0124273E call __RTC_CheckEsp (012411AEh) 01242743 mov esp,ebp 01242745 pop ebp 01242746 ret 10h// 4、经过在NewMwssageBoxA中的跳转,进入到36ED00D8地址处36ED00D8 mov edi,edi 36ED00DA push ebp 36ED00DB mov ebp,esp 36ED00DD jmp 76EEFDB3 // 5、很明显,此时我们又跳转回来了(此处和第二点是同一位置)76EEFDB3 push 0 76EEFDB5 push dword ptr [ebp+14h] 76EEFDB8 push dword ptr [ebp+10h] 76EEFDBB push dword ptr [ebp+0Ch] 76EEFDBE push dword ptr [ebp+8] 76EEFDC1 call 76EEFD66 76EEFDC6 pop ebp 76EEFDC7 ret 10h
通过该汇编指令的理解,可以发现:经过Hook后,改变了原来的函数首地址的指令mov edi,edi,使得该地址先跳转到我们Hook后的地址上,先实现我们的函数,完成之后再跳转到原来的地址上执行(当然,你也可以不用再跳回到原来的地址中执行),这也是Hook的原理
注意的是,该Hook仅仅是在本进程进行的,而且是Hook的ring3层
经过UnHook后,将会将我们的地址改变为原来的mov edi,edi,和第三句
MessageBoxA(NULL, “This is Hook”, “Hook”, MB_OK);一样
// 压栈数据,调用MessageBoxA该API01242852 mov esi,esp 01242854 push 0 01242858 push offset string "Hook" (0124AC64h) 0124285D push offset string "This is Hook" (0124BD88h) 01242863 push 0 01242865 call dword ptr [__imp__MessageBoxA@16 (0124F0C8h)] // 查看MessageBox函数的首地址76EEFDAE mov edi,edi 76EEFDB0 push ebp 76EEFDB1 mov ebp,esp 76EEFDB3 push 0 76EEFDB5 push dword ptr [ebp+14h] 76EEFDB8 push dword ptr [ebp+10h] 76EEFDBB push dword ptr [ebp+0Ch] 76EEFDBE push dword ptr [ebp+8] 76EEFDC1 call 76EEFD66 76EEFDC6 pop ebp 76EEFDC7 ret 10h
总结下(Hook前后的对比):
示例代码需要Detours库的支持,Detours下载地址
本文难免有所错误,如有问题欢迎留言
阅读全文
0 0
- HooK原理简析
- SSDT-hook,IDT-hook原理
- API HOOK 原理
- API Hook 原理
- COM Hook原理
- API Hook 原理
- COM HOOK的原理
- COM Hook原理
- HOOK自绘原理
- COM Hook原理
- Hook API 原理 解析
- IAT Hook的原理
- D3D9 HOOK [透视原理]
- Hook原理分析
- ELF Hook原理
- HOOK框架原理实现
- ServiceManager Hook原理
- LoactionManager Hook原理
- MySQL TEXT数据类型的最大长度
- Servlet文件下载例子详解及response的contentType类型大全
- VMware安装KaliLinux2.0
- 蓝桥杯 基础练习 数的读法 【模拟】
- MAVEN SSH的框架整合
- HooK原理简析
- 计算机视觉研究群体及专家主页汇总
- 循环结构
- pytorch学习笔记(十七):python 端扩展 pytorch
- 手写死锁
- 解决在eclipse中删除tomcat server后导致无法重新添加服务器的问题
- ubuntu下忘记mysql密码
- mysql could not read contents of failed to open no such file or directory
- LeetCode-2-Add Two Nuns(C语言实现)