1 // Win32Project2.cpp : 定义 DLL 应用程序的导出函数。
2 //
3 ///////////////////////////////////////////////////////////////////////////////////////////////////////
4 /*
5
6 DLL名称劫持注入法
7
8 当游戏运行加载一个重要的的DLL模块时,我们让他来加载我们需要注入的DLL和原来那个必须加载的游戏DLL模块。
9
10 比如说一些游戏加载游戏本身DLL“client.dll”。
11 游戏DLL“client.dll”重命名为“client- original.dll”。
12 把我们需要注入的DLL重命名成“client.dll”,并把2个DLL放在一起。
13 把下面源码的client.exe更换成你需要注入的游戏的进程名。
14
15 原理:
16 游戏运行时先加载我们伪造的DLL“client.dll”,但由于关键函数还在原来的client.dll中。
17 所以先将自身复制为临时文件“client - temp.dll”
18 加载后然后卸载本身。替换原来的“client.dll”并加载。
19 然后,它运行一个bat脚本,将等待游戏退出,一旦游戏退出。
20 bat脚本将复制临时文件“client - temp.dll”到“client.dll”,
21 这样它就会在下次游戏启动时继续加载。
22
23
24 */
25 #include "stdafx.h"
26 #include "fstream"
27 using namespace std;
28
29
30 void 替换(char* szBuffer, size_t bufferSize, char* from, char* to)
31 {
32 char* szpTemp,
33 *szpTempBuffer,
34 *szpCurrentBuffer;
35
36
37 szpCurrentBuffer = szBuffer;
38 szpTempBuffer = new char[bufferSize];
39
40 while (true)
41 {
42 szpTemp = strstr(szpCurrentBuffer, from);
43
44 if (szpTemp != NULL)
45 {
46 if (strlen(szBuffer) - strlen(from) + strlen(to) < bufferSize)
47 {
48 strcpy(szpTempBuffer, szpTemp + strlen(from));
49
50 *szpTemp = '\0';
51 strcat(szpTemp, to);
52 szpCurrentBuffer = szpTemp + strlen(to);
53 strcat(szpTemp, szpTempBuffer);
54 }
55 else
56 break;
57 }
58 else
59 break;
60 }
61
62 delete[] szpTempBuffer;
63 }
64
65 DWORD WINAPI ThreadMain(LPVOID lpvParam)
66 {
67 MessageBox(0, "劫持注入成功", "hello", 0);
68
69 return 0;
70 }
71
72 BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
73 {
74 BYTE* pCave;
75
76 ifstream in;
77
78 ofstream out;
79
80 BOOL bLoad;
81
82 FARPROC targetFunction;
83
84 HMODULE hTargetModule;
85
86 char* szpName;
87
88 char szFileName[MAX_PATH],
89 szBuffer[MAX_PATH],
90 szTempBuffer[MAX_PATH];
91
92 char* szpTargetModule;
93
94 STARTUPINFO si = { sizeof(STARTUPINFO) };
95
96 PROCESS_INFORMATION pi;
97
98 char szCmdLine[MAX_PATH];
99
100
101 bLoad = FALSE;
102
103
104 if (dwReason == DLL_PROCESS_ATTACH)
105 {
106 GetModuleFileName(hModule, szFileName, sizeof(szFileName));
107 strcpy(szBuffer, szFileName);
108
109 // 判断自身是否为临时文件,如果不是临时文件将创建并加载
110 if (strstr(szFileName, " - temp.dll") == NULL)
111 {
112 替换(szBuffer, sizeof(szBuffer), ".dll", " - temp.dll");
113
114 if (CopyFile(szFileName, szBuffer, FALSE) != NULL)
115 {
116 szpTargetModule = (char*)VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
117
118 strcpy(szpTargetModule, szBuffer);
119
120 hTargetModule = GetModuleHandle("Kernel32.dll");
121 targetFunction = GetProcAddress(hTargetModule, "LoadLibraryA");
122
123 pCave = (BYTE*)VirtualAlloc(NULL, 0x10, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
124 *pCave++ = 0x68;
125 *(DWORD*)pCave = (DWORD)szpTargetModule;
126 pCave += 4;
127 *pCave++ = 0xe8;
128 *(DWORD*)pCave = (DWORD)((DWORD)targetFunction - (DWORD)pCave - 4);
129 pCave += 4;
130 *pCave++ = 0xc2;
131 *pCave++ = 0x04;
132 *pCave++ = 0x00;
133 pCave -= 13;
134
135 CreateThread(0, 0, (LPTHREAD_START_ROUTINE)pCave, 0, 0, 0);
136 }
137 }
138 else
139 {
140 // 如果是临时的DLL
141 替换(szBuffer, sizeof(szBuffer), " - temp.dll", ".dll");
142
143 // 等待遊戲主進程是否佔用此DLL 等待寫入權限
144 do
145 {
146 in.open(szBuffer, ios::out);
147
148 if (in.is_open() == true)
149 {
150 in.close();
151 break;
152 }
153
154 Sleep(1000);
155 } while (true);
156
157
158
159 // 写一个bat脚本,一旦游戏退出,恢复自身文件名,下次可以继续加载
160 //// 把下面的client.exe改成你需要注入的游戏进程名
161 out.open("bat.bat", ios::out);
162
163 if (out.is_open() == true)
164 {
165 out << ":WAITLOOP" << endl;
166 out << "tasklist /FI \"IMAGENAME eq Client.exe\" 2>NUL | find /I /N \"Client.exe\">NUL" << endl;
167 out << "if \"%ERRORLEVEL%\"==\"0\" goto RUNNING" << endl;
168 out << "goto NOTRUNNING" << endl;
169
170 out << ":RUNNING" << endl;
171 out << "timeout /t 2" << endl;
172 out << "goto WAITLOOP" << endl;
173
174 out << ":NOTRUNNING" << endl;
175 out << "copy \"" << szFileName << "\" \"" << szBuffer << "\"" << endl;
176 out.close();
177
178 strcpy(szTempBuffer, szFileName);
179 *strrchr(szTempBuffer, '\\') = '\0';
180
181 sprintf(szCmdLine, "cmd.exe /C \"%s\\bat.bat\"", szTempBuffer);
182
183 CreateProcess(NULL, szCmdLine, 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT, NULL, 0, &si, &pi);
184 }
185
186 替换(szFileName, sizeof(szFileName), " - temp.dll", " - original.dll");
187 CopyFile(szFileName, szBuffer, FALSE);
188
189 LoadLibrary(szBuffer);
190
191 CreateThread(0, 0, ThreadMain, 0, 0, 0);
192 bLoad = TRUE;
193 }
194 }
195
196 return bLoad;
197 }