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 }
View Code

 

posted on 2016-01-08 14:51  王庆东mas  阅读(1101)  评论(0编辑  收藏  举报