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 }