Guest User

Untitled

a guest
Jun 21st, 2010
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.79 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. /***************************************************************************************************/
  5. //  Function:
  6. //      Inject
  7. // 
  8. //  Parameters:
  9. //      HANDLE hProcess - The handle to the process to inject the DLL into.
  10. //
  11. //      const char* dllname - The name of the DLL to inject into the process.
  12. //     
  13. //      const char* funcname - The name of the function to call once the DLL has been injected.
  14. //
  15. //  Description:
  16. //      This function will inject a DLL into a process and execute an exported function
  17. //      from the DLL to "initialize" it. The function should be in the format shown below,
  18. //      not parameters and no return type. Do not forget to prefix extern "C" if you are in C++
  19. //
  20. //          __declspec(dllexport) void FunctionName(void)
  21. //
  22. //      The function that is called in the injected DLL
  23. //      -MUST- return, the loader waits for the thread to terminate before removing the
  24. //      allocated space and returning control to the Loader. This method of DLL injection
  25. //      also adds error handling, so the end user knows if something went wrong.
  26. /***************************************************************************************************/
  27.  
  28. void Inject(HANDLE hProcess, const char* dllname, const char* funcname)
  29. {
  30. //------------------------------------------//
  31. // Function variables.                      //
  32. //------------------------------------------//
  33.  
  34.     // Main DLL we will need to load
  35.     HMODULE kernel32    = NULL;
  36.  
  37.     // Main functions we will need to import
  38.     FARPROC loadlibrary     = NULL;
  39.     FARPROC getprocaddress  = NULL;
  40.     FARPROC exitprocess     = NULL;
  41.     FARPROC exitthread      = NULL;
  42.     FARPROC freelibraryandexitthread = NULL;
  43.  
  44.     // The workspace we will build the codecave on locally
  45.     LPBYTE workspace        = NULL;
  46.     DWORD workspaceIndex    = 0;
  47.  
  48.     // The memory in the process we write to
  49.     LPVOID codecaveAddress  = NULL;
  50.     DWORD dwCodecaveAddress = 0;
  51.  
  52.     // Strings we have to write into the process
  53.     char injectDllName[MAX_PATH + 1]    = {0};
  54.     char injectFuncName[MAX_PATH + 1]   = {0};
  55.     char injectError0[MAX_PATH + 1]     = {0};
  56.     char injectError1[MAX_PATH + 1]     = {0};
  57.     char injectError2[MAX_PATH + 1]     = {0};
  58.     char user32Name[MAX_PATH + 1]       = {0};
  59.     char msgboxName[MAX_PATH + 1]       = {0};
  60.  
  61.     // Placeholder addresses to use the strings
  62.     DWORD user32NameAddr    = 0;
  63.     DWORD user32Addr        = 0;
  64.     DWORD msgboxNameAddr    = 0;
  65.     DWORD msgboxAddr        = 0;
  66.     DWORD dllAddr           = 0;
  67.     DWORD dllNameAddr       = 0;
  68.     DWORD funcNameAddr      = 0;
  69.     DWORD error0Addr        = 0;
  70.     DWORD error1Addr        = 0;
  71.     DWORD error2Addr        = 0;
  72.  
  73.     // Where the codecave execution should begin at
  74.     DWORD codecaveExecAddr = 0;
  75.  
  76.     // Handle to the thread we create in the process
  77.     HANDLE hThread = NULL;
  78.  
  79.     // Temp variables
  80.     DWORD dwTmpSize = 0;
  81.  
  82.     // Old protection on page we are writing to in the process and the bytes written
  83.     DWORD oldProtect    = 0;   
  84.     DWORD bytesRet      = 0;
  85.  
  86. //------------------------------------------//
  87. // Variable initialization.                 //
  88. //------------------------------------------//
  89.  
  90.     // Get the address of the main DLL
  91.     kernel32    = LoadLibrary("kernel32.dll");
  92.  
  93.     // Get our functions
  94.     loadlibrary     = GetProcAddress(kernel32,  "LoadLibraryA");
  95.     getprocaddress  = GetProcAddress(kernel32,  "GetProcAddress");
  96.     exitprocess     = GetProcAddress(kernel32,  "ExitProcess");
  97.     exitthread      = GetProcAddress(kernel32,  "ExitThread");
  98.     freelibraryandexitthread = GetProcAddress(kernel32, "FreeLibraryAndExitThread");
  99.  
  100. // This section will cause compiler warnings on VS8,
  101. // you can upgrade the functions or ignore them
  102.  
  103.     // Build names
  104.     _snprintf(injectDllName, MAX_PATH, "%s", dllname);
  105.     _snprintf(injectFuncName, MAX_PATH, "%s", funcname);
  106.     _snprintf(user32Name, MAX_PATH, "user32.dll");
  107.     _snprintf(msgboxName, MAX_PATH, "MessageBoxA");
  108.  
  109.     // Build error messages
  110.     _snprintf(injectError0, MAX_PATH, "Error");
  111.     _snprintf(injectError1, MAX_PATH, "Could not load the dll: %s", injectDllName);
  112.     _snprintf(injectError2, MAX_PATH, "Could not load the function: %s", injectFuncName);
  113.  
  114.     // Create the workspace
  115.     workspace = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024);
  116.  
  117.     // Allocate space for the codecave in the process
  118.     codecaveAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  119.     dwCodecaveAddress = PtrToUlong(codecaveAddress);
  120.  
  121. // Note there is no error checking done above for any functions that return a pointer/handle.
  122. // I could have added them, but it'd just add more messiness to the code and not provide any real
  123. // benefit. It's up to you though in your final code if you want it there or not.
  124.  
  125. //------------------------------------------//
  126. // Data and string writing.                 //
  127. //------------------------------------------//
  128.  
  129.     // Write out the address for the user32 dll address
  130.     user32Addr = workspaceIndex + dwCodecaveAddress;
  131.     dwTmpSize = 0;
  132.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  133.     workspaceIndex += 4;
  134.  
  135.     // Write out the address for the MessageBoxA address
  136.     msgboxAddr = workspaceIndex + dwCodecaveAddress;
  137.     dwTmpSize = 0;
  138.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  139.     workspaceIndex += 4;
  140.  
  141.     // Write out the address for the injected DLL's module
  142.     dllAddr = workspaceIndex + dwCodecaveAddress;
  143.     dwTmpSize = 0;
  144.     memcpy(workspace + workspaceIndex, &dwTmpSize, 4);
  145.     workspaceIndex += 4;
  146.  
  147.     // User32 Dll Name
  148.     user32NameAddr = workspaceIndex + dwCodecaveAddress;
  149.     dwTmpSize = (DWORD)strlen(user32Name) + 1;
  150.     memcpy(workspace + workspaceIndex, user32Name, dwTmpSize);
  151.     workspaceIndex += dwTmpSize;
  152.  
  153.     // MessageBoxA name
  154.     msgboxNameAddr = workspaceIndex + dwCodecaveAddress;
  155.     dwTmpSize = (DWORD)strlen(msgboxName) + 1;
  156.     memcpy(workspace + workspaceIndex, msgboxName, dwTmpSize);
  157.     workspaceIndex += dwTmpSize;
  158.  
  159.     // Dll Name
  160.     dllNameAddr = workspaceIndex + dwCodecaveAddress;
  161.     dwTmpSize = (DWORD)strlen(injectDllName) + 1;
  162.     memcpy(workspace + workspaceIndex, injectDllName, dwTmpSize);
  163.     workspaceIndex += dwTmpSize;
  164.  
  165.     // Function Name
  166.     funcNameAddr = workspaceIndex + dwCodecaveAddress;
  167.     dwTmpSize = (DWORD)strlen(injectFuncName) + 1;
  168.     memcpy(workspace + workspaceIndex, injectFuncName, dwTmpSize);
  169.     workspaceIndex += dwTmpSize;
  170.  
  171.     // Error Message 1
  172.     error0Addr = workspaceIndex + dwCodecaveAddress;
  173.     dwTmpSize = (DWORD)strlen(injectError0) + 1;
  174.     memcpy(workspace + workspaceIndex, injectError0, dwTmpSize);
  175.     workspaceIndex += dwTmpSize;
  176.  
  177.     // Error Message 2
  178.     error1Addr = workspaceIndex + dwCodecaveAddress;
  179.     dwTmpSize = (DWORD)strlen(injectError1) + 1;
  180.     memcpy(workspace + workspaceIndex, injectError1, dwTmpSize);
  181.     workspaceIndex += dwTmpSize;
  182.  
  183.     // Error Message 3
  184.     error2Addr = workspaceIndex + dwCodecaveAddress;
  185.     dwTmpSize = (DWORD)strlen(injectError2) + 1;
  186.     memcpy(workspace + workspaceIndex, injectError2, dwTmpSize);
  187.     workspaceIndex += dwTmpSize;
  188.  
  189.     // Pad a few INT3s after string data is written for seperation
  190.     workspace[workspaceIndex++] = 0xCC;
  191.     workspace[workspaceIndex++] = 0xCC;
  192.     workspace[workspaceIndex++] = 0xCC;
  193.  
  194.     // Store where the codecave execution should begin
  195.     codecaveExecAddr = workspaceIndex + dwCodecaveAddress;
  196.  
  197. // For debugging - infinite loop, attach onto process and step over
  198.     //workspace[workspaceIndex++] = 0xEB;
  199.     //workspace[workspaceIndex++] = 0xFE;
  200.  
  201. //------------------------------------------//
  202. // User32.dll loading.                      //
  203. //------------------------------------------//
  204.  
  205. // User32 DLL Loading
  206.     // PUSH 0x00000000 - Push the address of the DLL name to use in LoadLibraryA
  207.     workspace[workspaceIndex++] = 0x68;
  208.     memcpy(workspace + workspaceIndex, &user32NameAddr, 4);
  209.     workspaceIndex += 4;
  210.  
  211.     // MOV EAX, ADDRESS - Move the address of LoadLibraryA into EAX
  212.     workspace[workspaceIndex++] = 0xB8;
  213.     memcpy(workspace + workspaceIndex, &loadlibrary, 4);
  214.     workspaceIndex += 4;
  215.  
  216.     // CALL EAX - Call LoadLibraryA
  217.     workspace[workspaceIndex++] = 0xFF;
  218.     workspace[workspaceIndex++] = 0xD0;
  219.  
  220. // MessageBoxA Loading
  221.     // PUSH 0x000000 - Push the address of the function name to load
  222.     workspace[workspaceIndex++] = 0x68;
  223.     memcpy(workspace + workspaceIndex, &msgboxNameAddr, 4);
  224.     workspaceIndex += 4;
  225.  
  226.     // Push EAX, module to use in GetProcAddress
  227.     workspace[workspaceIndex++] = 0x50;
  228.  
  229.     // MOV EAX, ADDRESS - Move the address of GetProcAddress into EAX
  230.     workspace[workspaceIndex++] = 0xB8;
  231.     memcpy(workspace + workspaceIndex, &getprocaddress, 4);
  232.     workspaceIndex += 4;
  233.  
  234.     // CALL EAX - Call GetProcAddress
  235.     workspace[workspaceIndex++] = 0xFF;
  236.     workspace[workspaceIndex++] = 0xD0;
  237.  
  238.     // MOV [ADDRESS], EAX - Save the address to our variable
  239.     workspace[workspaceIndex++] = 0xA3;
  240.     memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  241.     workspaceIndex += 4;
  242.  
  243. //------------------------------------------//
  244. // Injected dll loading.                    //
  245. //------------------------------------------//
  246.  
  247. /*
  248.     // This is the way the following assembly code would look like in C/C++
  249.  
  250.     // Load the injected DLL into this process
  251.     HMODULE h = LoadLibrary("mydll.dll");
  252.     if(!h)
  253.     {
  254.         MessageBox(0, "Could not load the dll: mydll.dll", "Error", MB_ICONERROR);
  255.         ExitProcess(0);
  256.     }
  257.  
  258.     // Get the address of the export function
  259.     FARPROC p = GetProcAddress(h, "Initialize");
  260.     if(!p)
  261.     {
  262.         MessageBox(0, "Could not load the function: Initialize", "Error", MB_ICONERROR);
  263.         ExitProcess(0);
  264.     }
  265.  
  266.     // So we do not need a function pointer interface
  267.     __asm call p
  268.  
  269.     // Exit the thread so the loader continues
  270.     ExitThread(0);
  271. */
  272.  
  273. // DLL Loading
  274.     // PUSH 0x00000000 - Push the address of the DLL name to use in LoadLibraryA
  275.     workspace[workspaceIndex++] = 0x68;
  276.     memcpy(workspace + workspaceIndex, &dllNameAddr, 4);
  277.     workspaceIndex += 4;
  278.  
  279.     // MOV EAX, ADDRESS - Move the address of LoadLibraryA into EAX
  280.     workspace[workspaceIndex++] = 0xB8;
  281.     memcpy(workspace + workspaceIndex, &loadlibrary, 4);
  282.     workspaceIndex += 4;
  283.  
  284.     // CALL EAX - Call LoadLibraryA
  285.     workspace[workspaceIndex++] = 0xFF;
  286.     workspace[workspaceIndex++] = 0xD0;
  287.  
  288. // Error Checking
  289.     // CMP EAX, 0
  290.     workspace[workspaceIndex++] = 0x83;
  291.     workspace[workspaceIndex++] = 0xF8;
  292.     workspace[workspaceIndex++] = 0x00;
  293.  
  294. // JNZ EIP + 0x1E to skip over eror code
  295.     workspace[workspaceIndex++] = 0x75;
  296.     workspace[workspaceIndex++] = 0x1E;
  297.  
  298. // Error Code 1
  299.     // MessageBox
  300.         // PUSH 0x10 (MB_ICONHAND)
  301.         workspace[workspaceIndex++] = 0x6A;
  302.         workspace[workspaceIndex++] = 0x10;
  303.  
  304.         // PUSH 0x000000 - Push the address of the MessageBox title
  305.         workspace[workspaceIndex++] = 0x68;
  306.         memcpy(workspace + workspaceIndex, &error0Addr, 4);
  307.         workspaceIndex += 4;
  308.  
  309.         // PUSH 0x000000 - Push the address of the MessageBox message
  310.         workspace[workspaceIndex++] = 0x68;
  311.         memcpy(workspace + workspaceIndex, &error1Addr, 4);
  312.         workspaceIndex += 4;
  313.  
  314.         // Push 0
  315.         workspace[workspaceIndex++] = 0x6A;
  316.         workspace[workspaceIndex++] = 0x00;
  317.  
  318.         // MOV EAX, [ADDRESS] - Move the address of MessageBoxA into EAX
  319.         workspace[workspaceIndex++] = 0xA1;
  320.         memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  321.         workspaceIndex += 4;
  322.  
  323.         // CALL EAX - Call MessageBoxA
  324.         workspace[workspaceIndex++] = 0xFF;
  325.         workspace[workspaceIndex++] = 0xD0;
  326.  
  327.     // ExitProcess
  328.         // Push 0
  329.         workspace[workspaceIndex++] = 0x6A;
  330.         workspace[workspaceIndex++] = 0x00;
  331.  
  332.         // MOV EAX, ADDRESS - Move the address of ExitProcess into EAX
  333.         workspace[workspaceIndex++] = 0xB8;
  334.         memcpy(workspace + workspaceIndex, &exitprocess, 4);
  335.         workspaceIndex += 4;
  336.  
  337.         // CALL EAX - Call MessageBoxA
  338.         workspace[workspaceIndex++] = 0xFF;
  339.         workspace[workspaceIndex++] = 0xD0;
  340.  
  341. //  Now we have the address of the injected DLL, so save the handle
  342.  
  343.     // MOV [ADDRESS], EAX - Save the address to our variable
  344.     workspace[workspaceIndex++] = 0xA3;
  345.     memcpy(workspace + workspaceIndex, &dllAddr, 4);
  346.     workspaceIndex += 4;
  347.  
  348. // Load the initilize function from it
  349.  
  350.     // PUSH 0x000000 - Push the address of the function name to load
  351.     workspace[workspaceIndex++] = 0x68;
  352.     memcpy(workspace + workspaceIndex, &funcNameAddr, 4);
  353.     workspaceIndex += 4;
  354.  
  355.     // Push EAX, module to use in GetProcAddress
  356.     workspace[workspaceIndex++] = 0x50;
  357.  
  358.     // MOV EAX, ADDRESS - Move the address of GetProcAddress into EAX
  359.     workspace[workspaceIndex++] = 0xB8;
  360.     memcpy(workspace + workspaceIndex, &getprocaddress, 4);
  361.     workspaceIndex += 4;
  362.  
  363.     // CALL EAX - Call GetProcAddress
  364.     workspace[workspaceIndex++] = 0xFF;
  365.     workspace[workspaceIndex++] = 0xD0;
  366.  
  367. // Error Checking
  368.     // CMP EAX, 0
  369.     workspace[workspaceIndex++] = 0x83;
  370.     workspace[workspaceIndex++] = 0xF8;
  371.     workspace[workspaceIndex++] = 0x00;
  372.  
  373. // JNZ EIP + 0x1C to skip eror code
  374.     workspace[workspaceIndex++] = 0x75;
  375.     workspace[workspaceIndex++] = 0x1C;
  376.  
  377. // Error Code 2
  378.     // MessageBox
  379.         // PUSH 0x10 (MB_ICONHAND)
  380.         workspace[workspaceIndex++] = 0x6A;
  381.         workspace[workspaceIndex++] = 0x10;
  382.  
  383.         // PUSH 0x000000 - Push the address of the MessageBox title
  384.         workspace[workspaceIndex++] = 0x68;
  385.         memcpy(workspace + workspaceIndex, &error0Addr, 4);
  386.         workspaceIndex += 4;
  387.  
  388.         // PUSH 0x000000 - Push the address of the MessageBox message
  389.         workspace[workspaceIndex++] = 0x68;
  390.         memcpy(workspace + workspaceIndex, &error2Addr, 4);
  391.         workspaceIndex += 4;
  392.  
  393.         // Push 0
  394.         workspace[workspaceIndex++] = 0x6A;
  395.         workspace[workspaceIndex++] = 0x00;
  396.  
  397.         // MOV EAX, ADDRESS - Move the address of MessageBoxA into EAX
  398.         workspace[workspaceIndex++] = 0xA1;
  399.         memcpy(workspace + workspaceIndex, &msgboxAddr, 4);
  400.         workspaceIndex += 4;
  401.  
  402.         // CALL EAX - Call MessageBoxA
  403.         workspace[workspaceIndex++] = 0xFF;
  404.         workspace[workspaceIndex++] = 0xD0;
  405.  
  406.     // ExitProcess
  407.         // Push 0
  408.         workspace[workspaceIndex++] = 0x6A;
  409.         workspace[workspaceIndex++] = 0x00;
  410.  
  411.         // MOV EAX, ADDRESS - Move the address of ExitProcess into EAX
  412.         workspace[workspaceIndex++] = 0xB8;
  413.         memcpy(workspace + workspaceIndex, &exitprocess, 4);
  414.         workspaceIndex += 4;
  415.  
  416. //  Now that we have the address of the function, we cam call it,
  417. // if there was an error, the messagebox would be called as well.
  418.  
  419.     // CALL EAX - Call ExitProcess -or- the Initialize function
  420.     workspace[workspaceIndex++] = 0xFF;
  421.     workspace[workspaceIndex++] = 0xD0;
  422.  
  423.     // If we get here, the Initialize function has been called,
  424.     // so it's time to close this thread and optionally unload the DLL.
  425.  
  426. //------------------------------------------//
  427. // Exiting from the injected dll.           //
  428. //------------------------------------------//
  429.  
  430. // Call ExitThread to leave the DLL loaded
  431. #if 1
  432.     // Push 0 (exit code)
  433.     workspace[workspaceIndex++] = 0x6A;
  434.     workspace[workspaceIndex++] = 0x00;
  435.  
  436.     // MOV EAX, ADDRESS - Move the address of ExitThread into EAX
  437.     workspace[workspaceIndex++] = 0xB8;
  438.     memcpy(workspace + workspaceIndex, &exitthread, 4);
  439.     workspaceIndex += 4;
  440.  
  441.     // CALL EAX - Call ExitThread
  442.     workspace[workspaceIndex++] = 0xFF;
  443.     workspace[workspaceIndex++] = 0xD0;
  444. #endif
  445.  
  446. // Call FreeLibraryAndExitThread to unload DLL
  447. #if 0
  448.     // Push 0 (exit code)
  449.     workspace[workspaceIndex++] = 0x6A;
  450.     workspace[workspaceIndex++] = 0x00;
  451.  
  452.     // PUSH [0x000000] - Push the address of the DLL module to unload
  453.     workspace[workspaceIndex++] = 0xFF;
  454.     workspace[workspaceIndex++] = 0x35;
  455.     memcpy(workspace + workspaceIndex, &dllAddr, 4);
  456.     workspaceIndex += 4;
  457.  
  458.     // MOV EAX, ADDRESS - Move the address of FreeLibraryAndExitThread into EAX
  459.     workspace[workspaceIndex++] = 0xB8;
  460.     memcpy(workspace + workspaceIndex, &freelibraryandexitthread, 4);
  461.     workspaceIndex += 4;
  462.  
  463.     // CALL EAX - Call FreeLibraryAndExitThread
  464.     workspace[workspaceIndex++] = 0xFF;
  465.     workspace[workspaceIndex++] = 0xD0;
  466. #endif
  467.  
  468. //------------------------------------------//
  469. // Code injection and cleanup.              //
  470. //------------------------------------------//
  471.  
  472.     // Change page protection so we can write executable code
  473.     VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, PAGE_EXECUTE_READWRITE, &oldProtect);
  474.  
  475.     // Write out the patch
  476.     WriteProcessMemory(hProcess, codecaveAddress, workspace, workspaceIndex, &bytesRet);
  477.  
  478.     // Restore page protection
  479.     VirtualProtectEx(hProcess, codecaveAddress, workspaceIndex, oldProtect, &oldProtect);
  480.  
  481.     // Make sure our changes are written right away
  482.     FlushInstructionCache(hProcess, codecaveAddress, workspaceIndex);
  483.  
  484.     // Free the workspace memory
  485.     HeapFree(GetProcessHeap(), 0, workspace);
  486.  
  487.     // Execute the thread now and wait for it to exit, note we execute where the code starts, and not the codecave start
  488.     // (since we wrote strings at the start of the codecave) -- NOTE: void* used for VC6 compatibility instead of UlongToPtr
  489.     hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((void*)codecaveExecAddr), 0, 0, NULL);
  490.     WaitForSingleObject(hThread, INFINITE);
  491.  
  492.     // Free the memory in the process that we allocated
  493.     VirtualFreeEx(hProcess, codecaveAddress, 0, MEM_RELEASE);
  494. }
  495.  
  496. // Program entry point
  497. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
  498. {
  499.     // Structures for creating the process
  500.     STARTUPINFO si = {0};
  501.     PROCESS_INFORMATION pi = {0};
  502.     BOOL result = FALSE;
  503.  
  504.     // Hardcoded just for a demo, you will need to use a game/program of your own to test
  505.     // It is not a good idea to use stuff in system32 due to the DEP enabled on those apps.
  506.     char* exeString = "C:\\Files\\Programming\\qt\\Hook\\debug\\Hook.exe";
  507.     char* workingDir = "C:\\Files\\Programming\\qt\\Hook\\debug\\";
  508.  
  509.     // Holds where the DLL should be
  510.     char dllPath[MAX_PATH + 1] = {0};
  511.  
  512.     // Set the static path of where the Inject DLL is, hardcoded just for a demo
  513.     _snprintf(dllPath, MAX_PATH, "C:\\Files\\Programming\\win32\\dll\\Release\\dll.dll");
  514.  
  515.     // Need to set this for the structure
  516.     si.cb = sizeof(STARTUPINFO);
  517.  
  518.     // Try to load our process
  519.     result = CreateProcess(NULL, exeString, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, workingDir, &si, &pi);
  520.     if(!result)
  521.     {
  522.         MessageBox(0, "Process could not be loaded!", "Error", MB_ICONERROR);
  523.         return -1;
  524.     }
  525.  
  526.     // Inject the DLL, the export function is named 'Initialize'
  527.     Inject(pi.hProcess, dllPath, "Initialize");
  528.  
  529.     // Resume process execution
  530.     ResumeThread(pi.hThread);
  531.  
  532.     // Standard return
  533.     return 0;
  534. }
Advertisement
Add Comment
Please, Sign In to add comment