1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <tlhelp32.h>
  4.  
  5. void Inject(HANDLE hProcess, const char* dllname, const char* funcname, const char* str)
  6. {
  7.     HMODULE kernel32 = NULL;
  8.  
  9.     FARPROC loadlibrary     = NULL;
  10.     FARPROC getprocaddress  = NULL;
  11.     FARPROC exitprocess     = NULL;
  12.     FARPROC exitthread      = NULL;
  13.  
  14.     FARPROC freelibraryandexitthread = NULL;
  15.  
  16.     LPBYTE workspace        = NULL;
  17.     DWORD workspaceIndex    = 0;
  18.  
  19.     LPVOID codecaveAddress  = NULL;
  20.     DWORD dwCodecaveAddress = 0;
  21.  
  22.     char injectDllName[MAX_PATH + 1]    = {0};
  23.     char injectFuncName[MAX_PATH + 1]   = {0};
  24.     char injectError0[MAX_PATH + 1]     = {0};
  25.     char injectError1[MAX_PATH + 1]     = {0};
  26.     char injectError2[MAX_PATH + 1]     = {0};
  27.     char user32Name[MAX_PATH + 1]       = {0};
  28.     char msgboxName[MAX_PATH + 1]       = {0};
  29.  
  30.     DWORD user32NameAddr    = 0;
  31.     DWORD user32Addr        = 0;
  32.     DWORD msgboxNameAddr    = 0;
  33.     DWORD msgboxAddr        = 0;
  34.     DWORD dllAddr           = 0;
  35.     DWORD dllNameAddr       = 0;
  36.     DWORD funcNameAddr      = 0;
  37.     DWORD error0Addr        = 0;
  38.     DWORD error1Addr        = 0;
  39.     DWORD error2Addr        = 0;
  40.  
  41.     DWORD codecaveExecAddr = 0;
  42.     HANDLE hThread = NULL;
  43.     DWORD dwTmpSize = 0;
  44.     DWORD oldProtect    = 0;   
  45.     DWORD bytesRet      = 0;
  46.  
  47.     kernel32 = LoadLibrary("kernel32.dll");
  48.  
  49.     loadlibrary     = GetProcAddress(kernel32,  "LoadLibraryA");
  50.     getprocaddress  = GetProcAddress(kernel32,  "GetProcAddress");
  51.     exitprocess     = GetProcAddress(kernel32,  "ExitProcess");
  52.     exitthread      = GetProcAddress(kernel32,  "ExitThread");
  53.     freelibraryandexitthread = GetProcAddress(kernel32, "FreeLibraryAndExitThread");
  54.  
  55.     _snprintf(injectDllName, MAX_PATH, "%s", dllname);
  56.     _snprintf(injectFuncName, MAX_PATH, "%s", funcname);
  57.     _snprintf(user32Name, MAX_PATH, "user32.dll");
  58.     _snprintf(msgboxName, MAX_PATH, "MessageBoxA");
  59.    
  60.     _snprintf(injectError0, MAX_PATH, "Error");
  61.     _snprintf(injectError1, MAX_PATH, "Could not load the dll: %s", injectDllName);
  62.     _snprintf(injectError2, MAX_PATH, "Could not load the function: %s", injectFuncName);
  63.  
  64.     workspace = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024);
  65.     codecaveAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  66.     dwCodecaveAddress = PtrToUlong(codecaveAddress);
  67.  
  68.     user32Addr = workspaceIndex + dwCodecaveAddress;
  69.     dwTmpSize = 0;
  70.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  71.     workspaceIndex += 4;
  72.  
  73.     msgboxAddr = workspaceIndex + dwCodecaveAddress;
  74.     dwTmpSize = 0;
  75.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  76.     workspaceIndex += 4;
  77.  
  78.     dllAddr = workspaceIndex + dwCodecaveAddress;
  79.     dwTmpSize = 0;
  80.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  81.     workspaceIndex += 4;
  82.  
  83.     user32NameAddr = workspaceIndex + dwCodecaveAddress;
  84.     dwTmpSize = (DWORD)strlen(user32Name) + 1;
  85.     memcpy(workspace + workspaceIndex, user32Name, dwTmpSize);
  86.     workspaceIndex += dwTmpSize;
  87.  
  88.     msgboxNameAddr = workspaceIndex + dwCodecaveAddress;
  89.     dwTmpSize = (DWORD)strlen(msgboxName) + 1;
  90.     memcpy(workspace + workspaceIndex, msgboxName, dwTmpSize);
  91.     workspaceIndex += dwTmpSize;
  92.  
  93.     dllNameAddr = workspaceIndex + dwCodecaveAddress;
  94.     dwTmpSize = (DWORD)strlen(injectDllName) + 1;
  95.     memcpy(workspace + workspaceIndex, injectDllName, dwTmpSize);
  96.     workspaceIndex += dwTmpSize;
  97.  
  98.     funcNameAddr = workspaceIndex + dwCodecaveAddress;
  99.     dwTmpSize = (DWORD)strlen(injectFuncName) + 1;
  100.     memcpy(workspace + workspaceIndex, injectFuncName, dwTmpSize);
  101.     workspaceIndex += dwTmpSize;
  102.  
  103.     error0Addr = workspaceIndex + dwCodecaveAddress;
  104.     dwTmpSize = (DWORD)strlen(injectError0) + 1;
  105.     memcpy(workspace + workspaceIndex, injectError0, dwTmpSize);
  106.     workspaceIndex += dwTmpSize;
  107.  
  108.     error1Addr = workspaceIndex + dwCodecaveAddress;
  109.     dwTmpSize = (DWORD)strlen(injectError1) + 1;
  110.     memcpy(workspace + workspaceIndex, injectError1, dwTmpSize);
  111.     workspaceIndex += dwTmpSize;
  112.  
  113.     error2Addr = workspaceIndex + dwCodecaveAddress;
  114.     dwTmpSize = (DWORD)strlen(injectError2) + 1;
  115.     memcpy(workspace + workspaceIndex, injectError2, dwTmpSize);
  116.     workspaceIndex += dwTmpSize;
  117.  
  118.     workspace[workspaceIndex++] = 0xCC;
  119.     workspace[workspaceIndex++] = 0xCC;
  120.     workspace[workspaceIndex++] = 0xCC;
  121.  
  122.     codecaveExecAddr = workspaceIndex + dwCodecaveAddress;
  123.    
  124.     workspace[workspaceIndex++] = 0x68;
  125.     memcpy(workspace + workspaceIndex, &user32NameAddr, 4);
  126.     workspaceIndex += 4;
  127.  
  128.     workspace[workspaceIndex++] = 0xB8;
  129.     memcpy(workspace + workspaceIndex, &loadlibrary, 4);
  130.     workspaceIndex += 4;
  131.  
  132.     workspace[workspaceIndex++] = 0xFF;
  133.     workspace[workspaceIndex++] = 0xD0;
  134.    
  135.     workspace[workspaceIndex++] = 0x68;
  136.     memcpy(workspace + workspaceIndex, &msgboxNameAddr, 4);
  137.     workspaceIndex += 4;
  138.  
  139.     workspace[workspaceIndex++] = 0x50;
  140.  
  141.     workspace[workspaceIndex++] = 0xB8;
  142.     memcpy(workspace + workspaceIndex, &getprocaddress, 4);
  143.     workspaceIndex += 4;
  144.  
  145.     workspace[workspaceIndex++] = 0xFF;
  146.     workspace[workspaceIndex++] = 0xD0;
  147.  
  148.     workspace[workspaceIndex++] = 0xA3;
  149.     memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  150.     workspaceIndex += 4;
  151.  
  152.     workspace[workspaceIndex++] = 0x68;
  153.     memcpy(workspace + workspaceIndex, &dllNameAddr, 4);
  154.     workspaceIndex += 4;
  155.  
  156.     workspace[workspaceIndex++] = 0xB8;
  157.     memcpy(workspace + workspaceIndex, &loadlibrary, 4);
  158.     workspaceIndex += 4;
  159.  
  160.     workspace[workspaceIndex++] = 0xFF;
  161.     workspace[workspaceIndex++] = 0xD0;
  162.  
  163.     workspace[workspaceIndex++] = 0x83;
  164.     workspace[workspaceIndex++] = 0xF8;
  165.     workspace[workspaceIndex++] = 0x00;
  166.  
  167.     workspace[workspaceIndex++] = 0x75;
  168.     workspace[workspaceIndex++] = 0x1E;
  169.  
  170.     workspace[workspaceIndex++] = 0x6A;
  171.     workspace[workspaceIndex++] = 0x10;
  172.  
  173.     workspace[workspaceIndex++] = 0x68;
  174.     memcpy(workspace + workspaceIndex, &error0Addr, 4);
  175.     workspaceIndex += 4;
  176.  
  177.     workspace[workspaceIndex++] = 0x68;
  178.     memcpy(workspace + workspaceIndex, &error1Addr, 4);
  179.     workspaceIndex += 4;
  180.  
  181.     workspace[workspaceIndex++] = 0x6A;
  182.     workspace[workspaceIndex++] = 0x00;
  183.  
  184.     workspace[workspaceIndex++] = 0xA1;
  185.     memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  186.     workspaceIndex += 4;
  187.  
  188.     workspace[workspaceIndex++] = 0xFF;
  189.     workspace[workspaceIndex++] = 0xD0;
  190.  
  191.     workspace[workspaceIndex++] = 0x6A;
  192.     workspace[workspaceIndex++] = 0x00;
  193.  
  194.     workspace[workspaceIndex++] = 0xB8;
  195.     memcpy(workspace + workspaceIndex, &exitprocess, 4);
  196.     workspaceIndex += 4;
  197.  
  198.     workspace[workspaceIndex++] = 0xFF;
  199.     workspace[workspaceIndex++] = 0xD0;
  200.  
  201.     workspace[workspaceIndex++] = 0xA3;
  202.     memcpy(workspace + workspaceIndex, &dllAddr, 4);
  203.     workspaceIndex += 4;
  204.  
  205.     workspace[workspaceIndex++] = 0x68;
  206.     memcpy(workspace + workspaceIndex, &funcNameAddr, 4);
  207.     workspaceIndex += 4;
  208.  
  209.     workspace[workspaceIndex++] = 0x50;
  210.  
  211.     workspace[workspaceIndex++] = 0xB8;
  212.     memcpy(workspace + workspaceIndex, &getprocaddress, 4);
  213.     workspaceIndex += 4;
  214.  
  215.     workspace[workspaceIndex++] = 0xFF;
  216.     workspace[workspaceIndex++] = 0xD0;
  217.  
  218.     workspace[workspaceIndex++] = 0x83;
  219.     workspace[workspaceIndex++] = 0xF8;
  220.     workspace[workspaceIndex++] = 0x00;
  221.  
  222.     workspace[workspaceIndex++] = 0x75;
  223.     workspace[workspaceIndex++] = 0x1C;
  224.  
  225.     workspace[workspaceIndex++] = 0x6A;
  226.     workspace[workspaceIndex++] = 0x10;
  227.  
  228.     workspace[workspaceIndex++] = 0x68;
  229.     memcpy(workspace + workspaceIndex, &error0Addr, 4);
  230.     workspaceIndex += 4;
  231.  
  232.     workspace[workspaceIndex++] = 0x68;
  233.     memcpy(workspace + workspaceIndex, &error2Addr, 4);
  234.     workspaceIndex += 4;
  235.  
  236.     workspace[workspaceIndex++] = 0x6A;
  237.     workspace[workspaceIndex++] = 0x00;
  238.  
  239.     workspace[workspaceIndex++] = 0xA1;
  240.     memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  241.     workspaceIndex += 4;
  242.  
  243.     workspace[workspaceIndex++] = 0xFF;
  244.     workspace[workspaceIndex++] = 0xD0;
  245.  
  246.     workspace[workspaceIndex++] = 0x6A;
  247.     workspace[workspaceIndex++] = 0x00;
  248.  
  249.     workspace[workspaceIndex++] = 0xB8;
  250.     memcpy(workspace + workspaceIndex, &exitprocess, 4);
  251.     workspaceIndex += 4;
  252.  
  253.     workspace[workspaceIndex++] = 0xFF;
  254.     workspace[workspaceIndex++] = 0xD0;
  255.  
  256. #if 1
  257.     workspace[workspaceIndex++] = 0x6A;
  258.     workspace[workspaceIndex++] = 0x00;
  259.  
  260.     workspace[workspaceIndex++] = 0xB8;
  261.     memcpy(workspace + workspaceIndex, &exitthread, 4);
  262.     workspaceIndex += 4;
  263.  
  264.     workspace[workspaceIndex++] = 0xFF;
  265.     workspace[workspaceIndex++] = 0xD0;
  266. #endif
  267.  
  268. #if 0
  269.     workspace[workspaceIndex++] = 0x6A;
  270.     workspace[workspaceIndex++] = 0x00;
  271.  
  272.     workspace[workspaceIndex++] = 0xFF;
  273.     workspace[workspaceIndex++] = 0x35;
  274.     memcpy(workspace + workspaceIndex, &dllAddr, 4);
  275.     workspaceIndex += 4;
  276.  
  277.     workspace[workspaceIndex++] = 0xB8;
  278.     memcpy(workspace + workspaceIndex, &freelibraryandexitthread, 4);
  279.     workspaceIndex += 4;
  280.  
  281.     workspace[workspaceIndex++] = 0xFF;
  282.     workspace[workspaceIndex++] = 0xD0;
  283. #endif
  284.  
  285.     VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, PAGE_EXECUTE_READWRITE, &oldProtect);
  286.     UINT result =  WriteProcessMemory(hProcess, codecaveAddress, workspace, workspaceIndex, &bytesRet);
  287.  
  288.     VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, oldProtect, &oldProtect);
  289.     FlushInstructionCache(hProcess, codecaveAddress, workspaceIndex);
  290.  
  291.     HeapFree(GetProcessHeap(), 0, workspace);
  292.  
  293.     LPVOID argumentAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  294.     WriteProcessMemory(hProcess, argumentAddress, (LPVOID)str, sizeof(str), &bytesRet);
  295.  
  296.     hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((void*)codecaveExecAddr), (LPVOID)argumentAddress, 0, NULL);
  297.  
  298.     WaitForSingleObject(hThread, INFINITE);
  299.     CloseHandle(hThread);
  300.     FreeLibrary(kernel32);
  301.     VirtualFreeEx(hProcess, codecaveAddress, 0, MEM_RELEASE);
  302. }
  303.  
  304. int main(int argc, char* argv[])
  305. {
  306.     if ( argc != 3 )
  307.     {
  308.         printf("Invalid number of arguments.\r\nUsage: test.exe <process name> <some string>\r\n");
  309.         return 1;
  310.     }
  311.  
  312.     PROCESSENTRY32 entry;
  313.     entry.dwSize = sizeof(PROCESSENTRY32);
  314.  
  315.     HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
  316.  
  317.     if (Process32First(snapshot, &entry) == TRUE)
  318.     {
  319.         while (Process32Next(snapshot, &entry) == TRUE)
  320.         {
  321.             if (stricmp(entry.szExeFile, argv[1]) == 0)
  322.             {  
  323.                 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
  324.  
  325.                 char dllPath[MAX_PATH + 1] = {0};
  326.                 _snprintf(dllPath, MAX_PATH, "C:\\dll.dll");   
  327.                 Inject(hProcess, dllPath, "TestFunction", argv[2]);            
  328.             }
  329.         }
  330.     }
  331.  
  332.     CloseHandle(snapshot);
  333.  
  334.     return 0;
  335. }