注入dll后测试闪退
本帖最后由 huchen 于 2024-6-13 23:58 编辑在学习滴水视频中,用lnline hook来实现对MessgeBoxA遇到的问题
首先我的测试程序,是用MFC写的一个简单的弹窗的代码,每点击按钮就会弹出弹窗
然后写上我dll代码
// _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:
mov DWORD ptr ss:,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 = {0xE9};
DWORD OldProtec = 0;
static BYTE OldCode = {0};
static BOOL HookFlag = FALSE;
//初始化JmpCode
memset(&JmpCode,0x90,PATCH_LEN);
//获取跳转的地址
*(DWORD*)&JmpCode = (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代码
// 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,
DWORDul_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++ 说实在的,这种inline hook都不记得多少年前玩过,光靠眼睛来找问题有难度,只能自己去调试了。
个人建议哈,这种WINAPI的拦截最好用detours,实现起来稳定可靠又方便。 用detours 好久没搞32位的hook程序了,MS的64位C++编译器都不支持 _asm 关键字了 注入之后,先不慌点击按钮触发消息框,拿调试器挂载上去看看MessageBoxA附近的指令,检查你的HOOK代码是否正确。
初步怀疑就是你的跳转距离可能计算错了,也许不应该使用DWORD类型,因为跳转距离可能是负数。 plottry 发表于 2024-6-14 08:06
好久没搞32位的hook程序了,MS的64位C++编译器都不支持 _asm 关键字了
Intel C++ Compiler 19.2 都是大神,完全看不懂 yes2 发表于 2024-6-14 08:59
注入之后,先不慌点击按钮触发消息框,拿调试器挂载上去看看MessageBoxA附近的指令,检查你的HOOK代码是否 ...
解决了,都是我太心浮气躁,没有去看MessageBoxA的汇编代码,前三行刚好是5个字节,我定义成6个,就把后面的字节给覆盖了,导致出错了 是的,调试一下是最快的解决方法,除非难以调试或者自己实在看不出原因再来论坛求助
页:
[1]