#include #include #include void Inject(HANDLE hProcess, const char* dllname, const char* funcname, const char* str) { HMODULE kernel32 = NULL; FARPROC loadlibrary = NULL; FARPROC getprocaddress = NULL; FARPROC exitprocess = NULL; FARPROC exitthread = NULL; FARPROC freelibraryandexitthread = NULL; LPBYTE workspace = NULL; DWORD workspaceIndex = 0; LPVOID codecaveAddress = NULL; DWORD dwCodecaveAddress = 0; char injectDllName[MAX_PATH + 1] = {0}; char injectFuncName[MAX_PATH + 1] = {0}; char injectError0[MAX_PATH + 1] = {0}; char injectError1[MAX_PATH + 1] = {0}; char injectError2[MAX_PATH + 1] = {0}; char user32Name[MAX_PATH + 1] = {0}; char msgboxName[MAX_PATH + 1] = {0}; DWORD user32NameAddr = 0; DWORD user32Addr = 0; DWORD msgboxNameAddr = 0; DWORD msgboxAddr = 0; DWORD dllAddr = 0; DWORD dllNameAddr = 0; DWORD funcNameAddr = 0; DWORD error0Addr = 0; DWORD error1Addr = 0; DWORD error2Addr = 0; DWORD codecaveExecAddr = 0; HANDLE hThread = NULL; DWORD dwTmpSize = 0; DWORD oldProtect = 0; DWORD bytesRet = 0; kernel32 = LoadLibrary("kernel32.dll"); loadlibrary = GetProcAddress(kernel32, "LoadLibraryA"); getprocaddress = GetProcAddress(kernel32, "GetProcAddress"); exitprocess = GetProcAddress(kernel32, "ExitProcess"); exitthread = GetProcAddress(kernel32, "ExitThread"); freelibraryandexitthread = GetProcAddress(kernel32, "FreeLibraryAndExitThread"); _snprintf(injectDllName, MAX_PATH, "%s", dllname); _snprintf(injectFuncName, MAX_PATH, "%s", funcname); _snprintf(user32Name, MAX_PATH, "user32.dll"); _snprintf(msgboxName, MAX_PATH, "MessageBoxA"); _snprintf(injectError0, MAX_PATH, "Error"); _snprintf(injectError1, MAX_PATH, "Could not load the dll: %s", injectDllName); _snprintf(injectError2, MAX_PATH, "Could not load the function: %s", injectFuncName); workspace = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024); codecaveAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); dwCodecaveAddress = PtrToUlong(codecaveAddress); user32Addr = workspaceIndex + dwCodecaveAddress; dwTmpSize = 0; memcpy(workspace + workspaceIndex, &dwTmpSize, 4); workspaceIndex += 4; msgboxAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = 0; memcpy(workspace + workspaceIndex, &dwTmpSize, 4); workspaceIndex += 4; dllAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = 0; memcpy(workspace + workspaceIndex, &dwTmpSize, 4); workspaceIndex += 4; user32NameAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(user32Name) + 1; memcpy(workspace + workspaceIndex, user32Name, dwTmpSize); workspaceIndex += dwTmpSize; msgboxNameAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(msgboxName) + 1; memcpy(workspace + workspaceIndex, msgboxName, dwTmpSize); workspaceIndex += dwTmpSize; dllNameAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(injectDllName) + 1; memcpy(workspace + workspaceIndex, injectDllName, dwTmpSize); workspaceIndex += dwTmpSize; funcNameAddr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(injectFuncName) + 1; memcpy(workspace + workspaceIndex, injectFuncName, dwTmpSize); workspaceIndex += dwTmpSize; error0Addr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(injectError0) + 1; memcpy(workspace + workspaceIndex, injectError0, dwTmpSize); workspaceIndex += dwTmpSize; error1Addr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(injectError1) + 1; memcpy(workspace + workspaceIndex, injectError1, dwTmpSize); workspaceIndex += dwTmpSize; error2Addr = workspaceIndex + dwCodecaveAddress; dwTmpSize = (DWORD)strlen(injectError2) + 1; memcpy(workspace + workspaceIndex, injectError2, dwTmpSize); workspaceIndex += dwTmpSize; workspace[workspaceIndex++] = 0xCC; workspace[workspaceIndex++] = 0xCC; workspace[workspaceIndex++] = 0xCC; codecaveExecAddr = workspaceIndex + dwCodecaveAddress; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &user32NameAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &loadlibrary, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &msgboxNameAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x50; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &getprocaddress, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0xA3; memcpy(workspace + workspaceIndex, &msgboxAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &dllNameAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &loadlibrary, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0x83; workspace[workspaceIndex++] = 0xF8; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0x75; workspace[workspaceIndex++] = 0x1E; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x10; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &error0Addr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &error1Addr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xA1; memcpy(workspace + workspaceIndex, &msgboxAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &exitprocess, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0xA3; memcpy(workspace + workspaceIndex, &dllAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &funcNameAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x50; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &getprocaddress, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0x83; workspace[workspaceIndex++] = 0xF8; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0x75; workspace[workspaceIndex++] = 0x1C; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x10; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &error0Addr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x68; memcpy(workspace + workspaceIndex, &error2Addr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xA1; memcpy(workspace + workspaceIndex, &msgboxAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &exitprocess, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; #if 1 workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &exitthread, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; #endif #if 0 workspace[workspaceIndex++] = 0x6A; workspace[workspaceIndex++] = 0x00; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0x35; memcpy(workspace + workspaceIndex, &dllAddr, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xB8; memcpy(workspace + workspaceIndex, &freelibraryandexitthread, 4); workspaceIndex += 4; workspace[workspaceIndex++] = 0xFF; workspace[workspaceIndex++] = 0xD0; #endif VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, PAGE_EXECUTE_READWRITE, &oldProtect); UINT result = WriteProcessMemory(hProcess, codecaveAddress, workspace, workspaceIndex, &bytesRet); VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, oldProtect, &oldProtect); FlushInstructionCache(hProcess, codecaveAddress, workspaceIndex); HeapFree(GetProcessHeap(), 0, workspace); LPVOID argumentAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); WriteProcessMemory(hProcess, argumentAddress, (LPVOID)str, sizeof(str), &bytesRet); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((void*)codecaveExecAddr), (LPVOID)argumentAddress, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); FreeLibrary(kernel32); VirtualFreeEx(hProcess, codecaveAddress, 0, MEM_RELEASE); } int main(int argc, char* argv[]) { if ( argc != 3 ) { printf("Invalid number of arguments.\r\nUsage: test.exe \r\n"); return 1; } PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Process32First(snapshot, &entry) == TRUE) { while (Process32Next(snapshot, &entry) == TRUE) { if (stricmp(entry.szExeFile, argv[1]) == 0) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); char dllPath[MAX_PATH + 1] = {0}; _snprintf(dllPath, MAX_PATH, "C:\\dll.dll"); Inject(hProcess, dllPath, "TestFunction", argv[2]); } } } CloseHandle(snapshot); return 0; }