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 }