标签:lex ret arp oid app ati getc box assert
一、win32-dll
1、编写
代码例如以下:
Math.h
#ifdef MATH_EXPORTS #define MATH_API __declspec(dllexport) #else #define MATH_API __declspec(dllimport) #endif extern MATH_API double PI; MATH_API int Add(int a ,int b); MATH_API int Sub(int a, int b); MATH_API int Mod(int a, int b);Math.cpp
#include "stdafx.h" #include "Math.h" MATH_API double PI = 3.1415926; MATH_API int Add(int a,int b) { return a + b; } MATH_API int Sub(int a, int b) { return a - b; } MATH_API int Mod(int a, int b) { return a % b; }Math.def(这个须要自己手动新建项中加入)
LIBRARY "Math" DESCRIPTION "ADD SUB MOD" EXPORTS Add @1 Sub @2 Mod @3 PI DATA
初始化这些:
typedef int(*M_add)(int, int); typedef int(*M_sub)(int, int); typedef int(*M_mod)(int, int); M_add myadd; M_sub mysub; M_mod mymod;
hinst = ::LoadLibrary(_T("Math.dll"));
void CMathTestDlg::OnBnClickedAdd() { ASSERT(hinst); myadd = (M_add)::GetProcAddress(hinst,"Add"); int a = 15, b = 6; int res = myadd(a,b); CString str; str.Format(_T("a+b=%d"), res); AfxMessageBox(str); } void CMathTestDlg::OnBnClickedSub() { ASSERT(hinst); mysub = (M_sub)::GetProcAddress(hinst, "Sub"); int a = 15, b = 6; int res = mysub(a, b); CString str; str.Format(_T("a-b=%d"), res); AfxMessageBox(str); } void CMathTestDlg::OnBnClickedMod() { ASSERT(hinst); mymod = (M_mod)::GetProcAddress(hinst, "Mod"); int a = 15, b = 6; int res = mymod(a, b); CString str; str.Format(_T("a求余b=%d"), res); AfxMessageBox(str); }
二、MFC-dll
1、MFC-Dll会在载入的时候,调用InitInstance中的代码,退出载入时,调用ExitInstance中的代码
2、声明部分
//不同Instance共享的该变量hinst #pragma data_seg("SHARED") static HINSTANCE hinst = NULL; //本dll的实例句柄 (MFCMath.dll) #pragma data_seg() #pragma comment(linker, "/section:SHARED,RWS") HANDLE hProcess = NULL; //所处进程的句柄 BOOL bHook = FALSE; //是否Hook了函数 BOOL inject_status = FALSE; //是否对API进行了Hook BYTE OldCode[5]; //老的系统API入口代码 BYTE NewCode[5]; //要跳转的API代码 (jmp xxxx) typedef int (*M_add)(int a, int b); //Math.dll中的Add函数定义 M_add m_add; //Math.dll中的Add函数 FARPROC pf_add; //指向Add函数的远指针 void HookOn(); //开启钩子 void HookOff(); //关闭钩子 void Inject(); //详细进行注射,替换入口的函数 int Myadd(int a, int b); //我们定义的新的add()函数
BOOL CMFCMathApp::InitInstance() { hinst = AfxGetInstanceHandle(); //本dll句柄 hProcess = OpenProcess(PROCESS_ALL_ACCESS,NULL,::GetCurrentProcessId()); Inject(); return CWinApp::InitInstance(); }
int CMFCMathApp::ExitInstance() { if (bHook) HookOff(); return CWinApp::ExitInstance(); }
void Inject() { if (inject_status == FALSE) { inject_status = TRUE; HMODULE hmod = ::LoadLibrary(_T("Math.dll"));//加载原Math.dll m_add = (M_add)::GetProcAddress(hmod, "Add"); pf_add = (FARPROC)m_add; if (pf_add == NULL) { AfxMessageBox(L"注入失败"); } _asm { lea edi, OldCode mov esi, pf_add cld movsd movsb } NewCode[0] = 0xe9;//第一个字节0xe9相当于jmp指令 //获取Myadd()的相对地址 _asm { lea eax, Myadd mov ebx, pf_add sub eax, ebx sub eax, 5 mov dword ptr[NewCode + 1], eax } HookOn(); AfxMessageBox(L"注入成功"); } } void HookOn() { ASSERT(hProcess != NULL); DWORD dwTemp = 0; DWORD dwOldProtect; //将内存保护模式改为可写,老模式保存入dwOldProtect VirtualProtectEx(hProcess, pf_add, 5, PAGE_READWRITE, &dwOldProtect); //将所属进程中add的前5个字节改为Jmp Myadd WriteProcessMemory(hProcess, pf_add, NewCode, 5, 0); //将内存保护模式改回为dwOldProtect VirtualProtectEx(hProcess, pf_add, 5, dwOldProtect, &dwTemp); bHook = TRUE; } //将所属进程中add()的入口代码恢复 void HookOff() { ASSERT(hProcess != NULL); DWORD dwTemp = 0; DWORD dwOldProtect; VirtualProtectEx(hProcess, pf_add, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProcess, pf_add, OldCode, 5, 0); VirtualProtectEx(hProcess, pf_add, 5, dwOldProtect, &dwTemp); bHook = FALSE; } int Myadd(int a, int b) { //截获了对add()的调用,我们给a,b都加1 a = a + 1; b = b + 1; HookOff();//关掉Myadd()钩子防止死循环 int ret = m_add(a, b); HookOn();//开启Myadd()钩子 return ret; }
::LoadLibrary(_T("MFCMath.dll"));此时会把Math.dll的入口替换Myadd的入口
假设在Myadd中使用了Math.dll中的Add函数,记住把入口再换回来,就是HookOff。调用完以后,再HookOn换回来。
::FreeLibrary()。能够释放掉在载入的dll
三、恶搞MessageBoxW函数
//不同Instance共享的该变量hinst #pragma data_seg("SHARED") static HINSTANCE hinst = NULL; //本dll的实例句柄 (MFCMath.dll) #pragma data_seg() #pragma comment(linker, "/section:SHARED,RWS") HANDLE hProcess = NULL; //所处进程的句柄 BOOL bHook = FALSE; //是否Hook了函数 BOOL inject_status = FALSE; //是否对API进行了Hook BYTE OldCode[5]; //老的系统API入口代码 BYTE NewCode[5]; //要跳转的API代码 (jmp xxxx) typedef int (WINAPI *MyMsg)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); //Math.dll中的Add函数定义 MyMsg m_msg; //Math.dll中的Add函数 FARPROC pf_add; //指向Add函数的远指针 void HookOn(); //开启钩子 void HookOff(); //关闭钩子 void Inject(); //详细进行注射,替换入口的函数 int WINAPI Myadd(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); //我们定义的新的add()函数 BOOL CMFCMathApp::InitInstance() { hinst = AfxGetInstanceHandle(); //本dll句柄 hProcess = OpenProcess(PROCESS_ALL_ACCESS,NULL,::GetCurrentProcessId()); Inject(); return CWinApp::InitInstance(); } int CMFCMathApp::ExitInstance() { if (bHook) HookOff(); return CWinApp::ExitInstance(); } void Inject() { if (inject_status == FALSE) { inject_status = TRUE; HMODULE hmod = ::LoadLibrary(_T("User32.dll"));//加载原Math.dll m_msg = (MyMsg)::GetProcAddress(hmod, "MessageBoxW"); pf_add = (FARPROC)m_msg; _asm { lea edi, OldCode mov esi, pf_add cld movsd movsb } NewCode[0] = 0xe9;//第一个字节0xe9相当于jmp指令 //获取Myadd()的相对地址 _asm { lea eax, Myadd mov ebx, pf_add sub eax, ebx sub eax, 5 mov dword ptr[NewCode + 1], eax } HookOn(); } } void HookOn() { ASSERT(hProcess != NULL); DWORD dwTemp = 0; DWORD dwOldProtect; //将内存保护模式改为可写,老模式保存入dwOldProtect VirtualProtectEx(hProcess, pf_add, 5, PAGE_READWRITE, &dwOldProtect); //将所属进程中add的前5个字节改为Jmp Myadd WriteProcessMemory(hProcess, pf_add, NewCode, 5, 0); //将内存保护模式改回为dwOldProtect VirtualProtectEx(hProcess, pf_add, 5, dwOldProtect, &dwTemp); bHook = TRUE; } //将所属进程中add()的入口代码恢复 void HookOff() { ASSERT(hProcess != NULL); DWORD dwTemp = 0; DWORD dwOldProtect; VirtualProtectEx(hProcess, pf_add, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProcess, pf_add, OldCode, 5, 0); VirtualProtectEx(hProcess, pf_add, 5, dwOldProtect, &dwTemp); bHook = FALSE; } int WINAPI Myadd(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { lpText = _T("被掉包了,哈哈"); HookOff();//关掉Myadd()钩子防止死循环 int ret = m_msg(hWnd, lpText, lpCaption, uType); HookOn();//开启Myadd()钩子 return ret; }
标签:lex ret arp oid app ati getc box assert
原文地址:http://www.cnblogs.com/wzzkaifa/p/7105903.html