huchen 发表于 2024-6-13 23:56

注入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++

plauger 发表于 2024-6-14 00:52

说实在的,这种inline hook都不记得多少年前玩过,光靠眼睛来找问题有难度,只能自己去调试了。

个人建议哈,这种WINAPI的拦截最好用detours,实现起来稳定可靠又方便。

fire9 发表于 2024-6-14 05:29

用detours      

plottry 发表于 2024-6-14 08:06

好久没搞32位的hook程序了,MS的64位C++编译器都不支持 _asm 关键字了

yes2 发表于 2024-6-14 08:59

注入之后,先不慌点击按钮触发消息框,拿调试器挂载上去看看MessageBoxA附近的指令,检查你的HOOK代码是否正确。
初步怀疑就是你的跳转距离可能计算错了,也许不应该使用DWORD类型,因为跳转距离可能是负数。

77341991 发表于 2024-6-14 09:01

plottry 发表于 2024-6-14 08:06
好久没搞32位的hook程序了,MS的64位C++编译器都不支持 _asm 关键字了

Intel C++ Compiler 19.2

xiaoSeven 发表于 2024-6-14 09:30

都是大神,完全看不懂

huchen 发表于 2024-6-15 11:14

yes2 发表于 2024-6-14 08:59
注入之后,先不慌点击按钮触发消息框,拿调试器挂载上去看看MessageBoxA附近的指令,检查你的HOOK代码是否 ...

解决了,都是我太心浮气躁,没有去看MessageBoxA的汇编代码,前三行刚好是5个字节,我定义成6个,就把后面的字节给覆盖了,导致出错了

yes2 发表于 2024-6-15 16:31

是的,调试一下是最快的解决方法,除非难以调试或者自己实在看不出原因再来论坛求助
页: [1]
查看完整版本: 注入dll后测试闪退