1.首先编写一个 win32 dll工程.
#include "stdafx.h" int WINAPI add(int a,int b) { return a+b; } BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }
在def文件添加显式导出: (没找到def文件需要添加)
LIBRARY DESCRIPTION "ADD LA" EXPORTS add @1;
2.编写调用此dll的主程序 新建基于对话框的MFC工程
在dlg头文件里添加声明:
#include <windef.h> public: HINSTANCE hAddDll; typedef int (WINAPI*AddProc)(int a,int b); AddProc add;
在程序入口 编写加载函数:
if (hAddDll==NULL) hAddDll=::LoadLibrary("add.dll"); add=(AddProc)::GetProcAddress(hAddDll,"add");
添加一个按钮函数 调用:
int a=1; int b=2; int c=add(a,b); CString temp; temp.Format("%d+%d=%d",a,b,c); AfxMessageBox(temp);
到这里运行主程序 就会看到。弹窗 1+2 = 3的结果。
3.编写hook dll 新建一个MFC dll 工程。
在InitInstance函数中添加:
hinst=::AfxGetInstanceHandle(); DWORD dwPid=::GetCurrentProcessId(); hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); //调用注入函数 Inject(); return CWinApp::InitInstance();
所有的声明:
#pragma data_seg("SHARED") static HHOOK hhk=NULL; //鼠标钩子句柄 static HINSTANCE hinst=NULL; //本dll的实例句柄 (hook.dll) #pragma data_seg() #pragma comment(linker, "/section:SHARED,rws") CString temp; //用于显示错误的临时变量 bool bHook=false; //是否Hook了函数 bool m_bInjected=false; //是否对API进行了Hook BYTE OldCode[5]; //老的系统API入口代码 BYTE NewCode[5]; //要跳转的API代码 (jmp xxxx) typedef int (WINAPI*AddProc)(int a,int b);//add.dll中的add函数定义 AddProc add; //add.dll中的add函数 HANDLE hProcess=NULL; //所处进程的句柄 FARPROC pfadd; //指向add函数的远指针 DWORD dwPid; //所处进程ID://end of 变量定义 //函数定义 void HookOn(); void HookOff(); //关闭钩子 LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam); //鼠标钩子函数 void Inject(); //具体进行注射,替换入口的函数 int WINAPI Myadd(int a,int b); //我们定义的新的add()函数 BOOL InstallHook(); //安装钩子函数 void UninstallHook(); //卸载钩子函数
声明函数的实现:
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam) { LRESULT RetVal= CallNextHookEx(hhk,nCode,wParam,lParam); return RetVal; } BOOL InstallHook() { hhk=::SetWindowsHookEx(WH_MOUSE,MouseProc,hinst,0); return true; } void UninstallHook() { ::UnhookWindowsHookEx(hhk); } void Inject() { if (m_bInjected==false) { m_bInjected=true; HMODULE hmod=::LoadLibrary("add.dll"); add=(AddProc)::GetProcAddress(hmod,"add"); pfadd=(FARPROC)add; if (pfadd==NULL) { AfxMessageBox("cannot locate add()"); } // 将add()中的入口代码保存入OldCode[] _asm { lea edi,OldCode mov esi,pfadd cld movsd movsb } NewCode[0]=0xe9;//实际上0xe9就相当于jmp指令 //获取Myadd()的相对地址 _asm { lea eax,Myadd mov ebx,pfadd sub eax,ebx sub eax,5 mov dword ptr [NewCode+1],eax } //填充完毕,现在NewCode[]里的指令相当于Jmp Myadd HookOn(); //可以开启钩子了 } } void HookOn() { ASSERT(hProcess!=NULL); DWORD dwTemp=0; DWORD dwOldProtect; //将内存保护模式改为可写,老模式保存入dwOldProtect VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); //将所属进程中add()的前5个字节改为Jmp Myadd WriteProcessMemory(hProcess,pfadd,NewCode,5,0); //将内存保护模式改回为dwOldProtect VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp); bHook=true; } void HookOff()//将所属进程中add()的入口代码恢复 { ASSERT(hProcess!=NULL); DWORD dwTemp=0; DWORD dwOldProtect; VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); WriteProcessMemory(hProcess,pfadd,OldCode,5,0); VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp); bHook=false; } int WINAPI Myadd(int a,int b) { //截获了对add()的调用,我们给a,b都加1 a=a+1; b=b+1; HookOff();//关掉Myadd()钩子防止死循环 int ret; ret=add(a,b); HookOn();//开启Myadd()钩子 return ret; }
在def文件 添加显式导出:
InstallHook MouseProc Myadd UninstallHook
hook dll 就完成了。
4.回到主程序 添加2个按钮 一个注入 一个卸载:
注入:
hinst=LoadLibrary("hook.dll"); if(hinst==NULL) { AfxMessageBox("no hook.dll!"); return; } typedef BOOL (CALLBACK *inshook)(); inshook insthook; insthook=::GetProcAddress(hinst,"InstallHook"); if(insthook==NULL) { AfxMessageBox("func not found!"); return; DWORD pid=::GetCurrentProcessId(); BOOL ret=insthook();
卸载:
typedef BOOL (CALLBACK *UnhookProc)(); UnhookProc UninstallHook; UninstallHook=::GetProcAddress(hinst,"UninstallHook"); if(UninstallHook==NULL) UninstallHook(); if (hinst!=NULL) { ::FreeLibrary(hinst); } if (hAddDll!=NULL) { ::FreeLibrary(hAddDll); } CDialog::OnCancel();
运行主程序:
计算:显示1+2 =3
注入:显示 1+2=5
完。
有任何不明白的地方欢迎骚扰:0x7317AF28
时间: 2024-11-11 23:10:17