本帖最后由 huchen 于 2024-6-13 23:58 编辑
在学习滴水视频中,用lnline hook来实现对MessgeBoxA遇到的问题
首先我的测试程序,是用MFC写的一个简单的弹窗的代码,每点击按钮就会弹出弹窗
然后写上我dll代码
[C++] 纯文本查看 复制代码 // _hook2.cpp: implementation of the _hook class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "_hook2.h"
#define PATCH_LEN 6
DWORD szHookAddr = 0;
DWORD szRetAddr = 0;
char szString[] = "lnlinehook";
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void __declspec(naked) NewMessageBox()
{
_asm
{
//1.保存寄存器
pushad
pushfd
//2.修改数据
lea eax,DWORD ptr ds:[szString]
mov DWORD ptr ss:[esp+0x24+8],eax
//3.恢复寄存器
popfd
popad
//4.覆盖执行的代码
mov edi,edi
push ebp
mov ebp,esp
//5.返回执行
jmp szRetAddr
}
}
BOOL HookMessageBox(BOOL bOpen)
{
BOOL Ret = FALSE;
BYTE JmpCode[PATCH_LEN] = {0xE9};
DWORD OldProtec = 0;
static BYTE OldCode[PATCH_LEN] = {0};
static BOOL HookFlag = FALSE;
//初始化JmpCode
memset(&JmpCode[1],0x90,PATCH_LEN);
//获取跳转的地址
*(DWORD*)&JmpCode[1] = (DWORD)NewMessageBox - szHookAddr -5;
//备份原来的code
memcpy(OldCode,(LPVOID)szHookAddr,PATCH_LEN);
//开始patch
if(bOpen)
{
if(!HookFlag)
{
//修改属性
VirtualProtect((LPVOID)szHookAddr,PATCH_LEN,PAGE_EXECUTE_READWRITE,&OldProtec);
memcpy((LPVOID)szHookAddr,JmpCode,PATCH_LEN);
VirtualProtect((LPVOID)szHookAddr,PATCH_LEN,OldProtec,&OldProtec);
HookFlag = TRUE;
Ret = TRUE;
}
}
else
{
if(HookFlag)
{
VirtualProtect((LPVOID)szHookAddr,PATCH_LEN,PAGE_EXECUTE_READWRITE,&OldProtec);
memcpy((LPVOID)szHookAddr,OldCode,PATCH_LEN);
VirtualProtect((LPVOID)szHookAddr,PATCH_LEN,OldProtec,&OldProtec);
HookFlag = FALSE;
Ret = TRUE;
}
}
return Ret;
}
void SetMessageBoxAHook()
{
//获取要hook的地址
szHookAddr = (DWORD)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA");
szRetAddr = szHookAddr + PATCH_LEN;
//安装hook
HookMessageBox(TRUE);
}
然后我的dllmain代码
[C++] 纯文本查看 复制代码 // Inline_hook.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "_hook2.h"
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
SetMessageBoxAHook();
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//MessageBoxA(0,0,0,0);
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,NULL);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
每当注入的时候,在Process Explorer 中,可以看到注入进去了,但是当点击按钮的时候,测试程序就直接闪退了
望大佬们解答一下
我的测试环境:虚拟机win xp VC6++ |