我的学习笔记之三——inline使用DLL进行全局HOOK(ring3_inline_dll_hook_Messagebox)
来源:互联网 发布:网络直播评论 编辑:程序博客网 时间:2024/05/16 16:10
前一篇学习了修改导入表来HOOK API,虽然是自己HOOK自己,但稍改一下,变成DLL就可以全局HOOK,因为windows有数据执行保护会拦截,所以就不再深入。
还有一种HOOKAPI法叫INLINE HOOK就是采用JMP法。长话短说,所谓的API HOOK指的就是 :系统函数接口的钩子。当系统函数进行调用时,首先进入我们指定的函数,然后再执行系统的函数。IAT是修改EXE的导入地址,而JMP修改的是DLL中函数中的内容。我们知道,系统函数都是以DLL封装起来的,应用程序应用到系统函数时,应首先把该DLL加载到当前的进程空间中,调用的系统函数的入口地址,可以通过GetProcAddress函数进行获取。当系统函数进行调用的时候,首先把所必要的信息保存下来(包括参数和返回地址,等一些别的信息),然后就跳转到函数的入口地址,继续执行。其实函数地址,就是系统函数“可执行代码”的开始地址。那么怎么才能让函数首先执行我们的函数呢?呵呵,应该明白了吧,把开始的那段可执行代码替换为我们自己定制的一小段可执行代码,这样系统函数调用时,不就按我们的意图乖乖行事了吗?其实,就这么简单。
也就是说:如果我们已经挂钩好了系统函数。那么当系统进行系统调用时,进入DLL对应的函数,首先就碰到我们的JmpXXXX指令,而这条指令作用就是跳到我们的函数中去执行。总体流程应该如下:
保存系统函数入口-等待进入我们的函数-恢复系统函数入口-可以做一些我们想做的操作-调用系统函数-挂接系统函数-保存系统函数入口
有几点很重要(1)JMP后面是我们函数的地址,此处要准确,计算公式为XXXX= 我的函数入口指针(地址)- 系统函数入口指针(地址)- sizeof (Jmp XXXX指令的大小);(2)替换掉的代码一定要保存好,以便随时恢复,否则肯定出错(3)拦截函数中返回值要和正确调用正确函数一至,以无逢提交给系统
下面给出具体的DLL代码
#include<windows.h>
HHOOKg_hHook;
HINSTANCEg_hinstDll;
FARPROCfpMessageBoxA;
HMODULEhModule;
BYTEOldMessageBoxACode[5],NewMessageBoxACode[5];
DWORDdwIdOld,dwIdNew;
BOOLbHook=false;
voidHookOn();
voidHookOff();
BOOLInit();
intWINAPI MyMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
//---------------------------------------------------------------------------
//空的钩子函数
LRESULTWINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)
{
return(CallNextHookEx(g_hHook,nCode,wParam,lParam));
}
//---------------------------------------------------------------------------
//输出,安装空的钩子函数
extern"C"__declspec(dllexport)bool InstallHook()
{
g_hinstDll=LoadLibrary("dll.dll"); // 这里的文件名为Dll本身的文件名
g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0);
if (!g_hHook)
{
MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK);
return(false);
}
return(true);
}
//---------------------------------------------------------------------------
//输出,Uninstall钩子函数
extern"C"__declspec(dllexport)bool UninstallHook()
{
HookOff()
return(UnhookWindowsHookEx(g_hHook));
}
//---------------------------------------------------------------------------
//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令
BOOLInit()
{
hModule=LoadLibrary("user32.dll");
fpMessageBoxA=GetProcAddress(hModule,"MessageBoxA");
if(fpMessageBoxA==NULL) return false;
_asm
{
pushad
lea edi,OldMessageBoxACode
mov esi,fpMessageBoxA
cld
movsd
movsb
popad
}
NewMessageBoxACode[0] = 0xe9; // jmp MyMessageBoxA的相对地址的指令
_asm
还有一种HOOK
也就是说:如果我们已经挂钩好了系统函数。那么当系统进行系统调用时,进入DLL对应的函数,首先就碰到我们的Jmp
保存系统函数入口-等待进入我们的函数-恢复系统函数入口-可以做一些我们想做的操作-调用系统函数
有几点很重要(1)JMP后面是我们函数的地址,此处要准确,计算公式为XXXX
下面给出具体的DLL代码
#include
HHOOK
HINSTANCE
FARPROC
HMODULE
BYTE
DWORD
BOOL
void
void
BOOL
int
//---------------------------------------------------------------------------
//
LRESULT
{
}
//---------------------------------------------------------------------------
//
extern"C"__declspec(dllexport)
{
}
//---------------------------------------------------------------------------
//
extern"C"__declspec(dllexport)
{
}
//---------------------------------------------------------------------------
//
BOOL
{