#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
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 <process name> <some string>\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;
}