废话不多说,线奉上代码工程:https://download.csdn.net/download/xundao255/12573085
本文讲解了在知道DLL接口函数调用规则的情况下,如何劫持DLL,使程序调用自己开发的DLL,从而改变程序的一些行为。这种方法经常用在破解收费软件上。
下图是基本原理:EXE原定调用“a.dll”,但是“b.dll”改名为“a.dll”,又将原来的“a.dll”改名为“a1.dll”,并在自己开发的“b.dll”中加入了调用“a1.dll”的代码,从而实现了一种“中继”的效果。一旦劫持成功,自己开发的“b.dll”中就能获取EXE到DLL之间交互的数据。待解读完这些数据后,自己便可以开发这个DLL,从而实现破解的目的。
在这里我写了一个VS2005的解决方案,包含三个工程:EXE主调程序、DLL被调程序、DLL劫持程序。
- EXE主调程序
#include <stdio.h> #include <Windows.h> typedef HANDLE (__stdcall *TestFunction_TYPE) (int, char *); TestFunction_TYPE TestFunction_b; int main() { int iFlag = 0; char pcStr[100] = {0}; HMODULE TheDll = LoadLibraryA("a.dll"); TestFunction_b = (TestFunction_TYPE)GetProcAddress(TheDll, "TestFunction"); if(TestFunction_b!=NULL) { TestFunction_b(iFlag, pcStr); printf("%s", pcStr); } system("pause"); return 0; }
- DLL被调程序
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <Windows.h> #pragma comment(linker, "/EXPORT:TestFunction=_TestFunction_b@8,@123") void WINAPI TestFunction_b(int iFlag, char *pcStr) { switch (iFlag) { case 0: sprintf(pcStr, "传参有效:iFlag = 0\n"); break; default: sprintf(pcStr, "传参无效:iFlag = %d\n", iFlag); break; } return ; }
- DLL劫持程序
#include <Windows.h> typedef HANDLE (__stdcall *TestFunction_TYPE) (int, char *); TestFunction_TYPE TestFunction_b; #pragma comment(linker, "/EXPORT:TestFunction=_TestFunction_a@8,@123") int g_iInit = 0; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { /* 只运行一次:加载DLL */ if (g_iInit == 0) { HMODULE TheDll = LoadLibraryA("b.dll"); TestFunction_b = (TestFunction_TYPE)GetProcAddress(TheDll, "TestFunction"); g_iInit = 1; } return TRUE; } HANDLE WINAPI TestFunction_a(int iLen, char *pcStr) { HANDLE hRet = NULL; if(TestFunction_b!=NULL) { strcpy(pcStr, "The DLL has been hijacked ---> "); //字符串长度:31 hRet = TestFunction_b(iLen, pcStr + 31); } return hRet; }