首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

远程DLL中怎么设置全局钩子

2012-01-12 
远程DLL中如何设置全局钩子。我写了个DLL,然后用另一个程序将它当作远程线程注入到NOTEPAD.exe中,在DLL实现

远程DLL中如何设置全局钩子。
我写了个DLL,然后用另一个程序将它当作远程线程注入到NOTEPAD.exe中,在DLL实现全局HOOK,在HOOKPROC中实现替换MESSAGEBOXA的前5字节为跳转到新API。
DLL代码如下:

//   Test_DLL.cpp   :   Defines   the   entry   point   for   the   DLL   application.
//
#include   <windows.h>
#include   "stdafx.h "

#pragma   comment(lib, "ImageHlp ")   //定义全局共享数据段  
#pragma   data_seg( "Shared ")  

HMODULE   g_hinstDll=NULL;
HHOOK   g_hHook=NULL;

#pragma   data_seg()  
#pragma   comment(linker, "/Section:Shared,rws ")   //设置全局共享数据段的属性  

FARPROC   pfMessageBoxA;
int   WINAPI   MyMessageBoxA(HWND   hWnd,   LPCTSTR   lpText,   LPCTSTR   lpCaption,   UINT   uType);

BYTE   OldMessageBoxACode[5],NewMessageBoxACode[5];//新旧API内存镜像前5字节
HMODULE   hModule;
DWORD   dwIdOld,dwIdNew;
BOOL   bHook=false;

BOOL   InstallHook();
BOOL   UnInstallHook();

BOOL   HookOn();
BOOL   HookOff();

LRESULT   WINAPI   HookProc(int   nCode,WPARAM   wParam,LPARAM   lParam);

/////////////////////////
//   DllMain
/////////////////////////
BOOL   APIENTRY   DllMain(   HANDLE   hModule,   DWORD   ul_reason_for_call,   LPVOID   lpReserved   )  
{
switch   (ul_reason_for_call)  
{
case   DLL_PROCESS_ATTACH:  
if(!InstallHook())  
{
MessageBoxA(NULL, "Error ", "InstallHook ",MB_OK);
return(false);
}
case   DLL_THREAD_ATTACH:  

case   DLL_THREAD_DETACH:  
case   DLL_PROCESS_DETACH:  
if(g_hHook)   UnInstallHook();
break;
}
return   TRUE;
}

/////////////////////////
//   InstallHook   安装一个全局消息钩子
/////////////////////////
BOOL   InstallHook()//输出安装空的钩子函数  
{
g_hinstDll=LoadLibrary( "Test_DLL.dll ");//远程线程中不能再载入DLL,所以此处使用DLL中Hook()
g_hHook=SetWindowsHookEx   (   WH_GETMESSAGE,(HOOKPROC)HookProc,g_hinstDll,0   );//钩子所监视的线程的线程号。0为全局钩子,监视全部线程
if   (!g_hHook)  
{
MessageBoxA(NULL, "SET   ERROR ", "SET   ERROR ",MB_OK);
return(false);
}
return(true);
}

/////////////////////////
//   HookProc   在进程内准备好跳转到新API地址的代码
/////////////////////////
LRESULT   WINAPI   HookProc(int   nCode,WPARAM   wParam,LPARAM   lParam)//空的钩子函数  
{
hModule=LoadLibrary( "user32.dll ");
pfMessageBoxA=GetProcAddress(hModule, "MessageBoxA ");//   获取目标API的地址
NewMessageBoxACode[0]=0xe9;//jmp   MyMessageBoxA的相对地址的指令
_asm
{
lea   eax,MyMessageBoxA
mov   ebx,pfMessageBoxA
sub   eax,ebx
sub   eax,5
mov   dword   ptr   [NewMessageBoxACode+1],eax
}//写入地址到替换代码的缓存
dwIdNew=GetCurrentProcessId();//得到所属进程的ID*/

if   (!HookOn())
MessageBoxA   (   NULL,   "HookOn失败 ",   "HookOn失败 ",   MB_OK   );
return(CallNextHookEx(g_hHook,nCode,wParam,lParam));
}

/////////////////////////
//   HookOn   修改进程中API的前5个字节,写入跳转到新API的代码
/////////////////////////
BOOL   HookOn()
{
MessageBoxA(NULL, "开始修改 ", "HookOn开始修改 ",MB_OK);
HANDLE   hProc;



//dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄  

//修改所属进程中MessageBoxA的前5个字节的属性为可写
if   (!VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld)){
MessageBoxA(NULL, "HookOn1修改为可写时失败 ", "HookOn1修改为可写时失败 ",MB_OK);
return   false;
}

//将所属进程中MessageBoxA的前5个字节改为JMP   到MyMessageBoxA  
if   (!WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0)){
MessageBoxA(NULL, "HookOn2修改字节时失败 ", "HookOn2修改字节时失败 ",MB_OK);
return   false;
}

//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性
if   (!VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld)){
MessageBoxA(NULL, "HookOn3恢复属性时失败 ", "HookOn3恢复属性时失败 ",MB_OK);
return   false;
}

bHook=true;
return   true;
}
/////////////////////////
//   UninstallHook
/////////////////////////
BOOL   UnInstallHook()//输出御载钩子函数  
{
return(UnhookWindowsHookEx(g_hHook));
}

/////////////////////////
//   MyMessageBoxA
/////////////////////////  
int   WINAPI   MyMessageBoxA(HWND   hWnd,   LPCTSTR   lpText,LPCTSTR   lpCaption,   UINT   uType   )//首先关闭拦截,然后才能调用被拦截的Api   函数  
{
int   nReturn=0;
dwIdNew=GetCurrentProcessId();//得到所属进程的ID
HookOff();//改回地址
nReturn=MessageBoxA(hWnd, "Hook成功 ",lpCaption,uType);
dwIdNew=GetCurrentProcessId();//得到所属进程的ID
HookOn();//改写地址
return(nReturn);
}

/////////////////////////
//   HookOff  
/////////////////////////
BOOL   HookOff()//将所属进程中JMP   MyMessageBoxA的代码改为Jmp   MessageBoxA  
{
HANDLE   hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0);
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);
bHook=false;
return   true;
}

注入后,用ICDSWORD查到NOTEPAD.EXE进程中确实有我这个DLL,但我在NOTEPAD.exe中写几个字再作新建时,弹出的MessageBox窗口并没有改变,而且我设的是全局钩子,打开其它加载有MessageBox所在的DLL的程序,也没见修改后的MessageBox出现。

我感觉是HOOKPROC没有起作用,请问是为什么?

[解决办法]
学习
帮顶
[解决办法]
调试下,看看有没有正确跳转啊,另外MessageBoxW也hook一下看看
[解决办法]
InstallHook()函数里面使用的SetWindowsHookEx函数的第三个参数hMod,直接使用DllMain函数的hModule参数就可以了,而不能使用LoadLibrary函数来得到模块句柄值。具体原因请参考MSDN里面的DllMain入口函数部分。这里我就不多讲了。

热点排行