Advertisement
Guest User

Untitled

a guest
Mar 7th, 2012
1,400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.50 KB | None | 0 0
  1. unsigned char codeToInject[] =
  2. {
  3.     // Placeholder for the return address
  4.     0x68, 0xAA, 0xAA, 0xAA, 0xAA,           // push 0AAAAAAAAh
  5.     // Save the flags
  6.     0x9c,                                   // pushfq                
  7.     // Save the registers
  8.     0x50,                                   // push rax
  9.     0x51,                                   // push rcx
  10.     0x52,                                   // push rdx
  11.     0x53,                                   // push rbx
  12.     0x55,                                   // push rbp
  13.     0x56,                                   // push rsi
  14.     0x57,                                   // push rdi
  15.     0x41, 0x50,                             // push r8
  16.     0x41, 0x51,                             // push r9
  17.     0x41, 0x52,                             // push r10
  18.     0x41, 0x53,                             // push r11
  19.     0x41, 0x54,                             // push r12
  20.     0x41, 0x55,                             // push r13
  21.     0x41, 0x56,                             // push r14
  22.     0x41, 0x57,                             // push r15
  23.     // Placeholder for the string address and LoadLibrary
  24.     0x48, 0xB9, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, // mov rcx, 0BBBBBBBBBBBBBBBBh
  25.     0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // mov rax, 0CCCCCCCCCCCCCCCCh
  26.     // Call LoadLibrary with the string parameter
  27.     0xFF, 0xD0,                // call rax
  28.     // Restore the registers
  29.     0x41, 0x5F,                             // pop r15
  30.     0x41, 0x5E,                             // pop r14
  31.     0x41, 0x5D,                             // pop r13
  32.     0x41, 0x5C,                             // pop r12
  33.     0x41, 0x5B,                             // pop r11
  34.     0x41, 0x5A,                             // pop r10
  35.     0x41, 0x59,                             // pop r9
  36.     0x41, 0x58,                             // pop r8
  37.     0x5F,                                   // pop rdi
  38.     0x5E,                                   // pop rsi
  39.     0x5D,                                   // pop rbp
  40.     0x5B,                                   // pop rbx
  41.     0x5A,                                   // pop rdx
  42.     0x59,                                   // pop rcx
  43.     0x58,                                   // pop rax
  44.     // Restore the flags
  45.     0x9D,                                   // popfq
  46.     0xC3                                    // ret
  47. };
  48.  
  49. bool InjectDLL64(__in const DWORD& dwProcessID, __in const WCHAR* const pwszDLLName)
  50. {
  51.     HANDLE hProcess = NULL;
  52.     LPVOID pRemoteMemDllName = NULL;
  53.     LPVOID pRemoteMemFunction = NULL;
  54.     SIZE_T nDllNameBuffSize = NULL;
  55.     DWORD64 nFunctionBuffSize = sizeof(codeToInject);
  56.     HANDLE hThread = NULL;
  57.     DWORD  dwThreadSuspendCount = -1;
  58.  
  59.     std::wstring strModuleFilePath = pwszDLLName;
  60.     bool bRet = false;
  61.  
  62.     // get process handle of the desktop
  63.     hProcess = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION  | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwProcessID);
  64.     if(!hProcess)
  65.     {
  66.         std::wcout << L"Error : Failed to open process" << std::endl;
  67.         return false;
  68.     }
  69.  
  70.     // Check if the process is running
  71.     DWORD dwExitCode = 0;
  72.     GetExitCodeProcess(hProcess, &dwExitCode);
  73.     if(dwExitCode != STILL_ACTIVE)
  74.     {
  75.         std::wcout << L"Error : The following process does not exist" << std::endl;
  76.         goto cleanup;
  77.     }
  78.  
  79.     // Allocate memory on the target process with current DLL path
  80.     nDllNameBuffSize = (strModuleFilePath.size()+1) * sizeof(WCHAR);
  81.     pRemoteMemDllName = ::VirtualAllocEx(hProcess, NULL, nDllNameBuffSize, MEM_COMMIT, PAGE_READWRITE);
  82.     if(!pRemoteMemDllName)
  83.     {
  84.         std::wcout << L"Error: Failed to allocate data on target process" << std::endl;
  85.         goto cleanup;
  86.     }
  87.  
  88.     SIZE_T nNumBytesWritten = 0;
  89.     ::WriteProcessMemory(hProcess, pRemoteMemDllName, (void*)strModuleFilePath.data(), nDllNameBuffSize, &nNumBytesWritten);
  90.     if(nNumBytesWritten != nDllNameBuffSize)
  91.     {
  92.         std::wcout << L"Error: Failed to write data on target process" << std::endl;
  93.         goto cleanup;
  94.     }
  95.  
  96.     // Allocate memory for the stub
  97.     pRemoteMemFunction = ::VirtualAllocEx(hProcess, NULL, nFunctionBuffSize, MEM_COMMIT, PAGE_READWRITE);
  98.  
  99.     // Get proc address of LoadLibrary
  100.     HMODULE hKernel32 = ::GetModuleHandleW(L"Kernel32");
  101.     if(!hKernel32)
  102.     {
  103.         std::wcout << L"Error : Failed to load kernel32" << std::endl;
  104.         goto cleanup;
  105.     }
  106.  
  107.     DWORD64 fnLocLoadLibrary = (DWORD64)::GetProcAddress(hKernel32, "LoadLibraryW");
  108.     if(!fnLocLoadLibrary)
  109.     {
  110.         std::wcout << L"Error : Failed to get LoadLibraryW proc address" << std::endl;
  111.         goto cleanup;
  112.     }
  113.  
  114.     DWORD dwThreadID = GetTargetThreadID(dwProcessID);
  115.     hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, false, dwThreadID);
  116.     if(!hThread)
  117.     {
  118.         std::wcout << L"Error : Failed to open main thread ID" << std::endl;
  119.         goto cleanup;
  120.     }
  121.  
  122.     // Suspend the thread
  123.     dwThreadSuspendCount = SuspendThread(hThread);
  124.     if(dwThreadSuspendCount == -1)
  125.     {
  126.         std::wcout << L"Error : Failed to suspend the main thread" << std::endl;
  127.         goto cleanup;
  128.     }
  129.  
  130.     // Set the instruction pointer to point to our function
  131.     CONTEXT ctx;
  132.     ctx.ContextFlags = CONTEXT_CONTROL;
  133.     if(!GetThreadContext(hThread, &ctx))
  134.     {
  135.         std::wcout << L"Error : Failed to get the thread context" << std::endl;
  136.         goto cleanup;
  137.     }
  138.  
  139.     DWORD dwOldIP = (DWORD)ctx.Rip;
  140.     ctx.Rip = (DWORD)pRemoteMemFunction;
  141.     ctx.ContextFlags = CONTEXT_CONTROL;
  142.  
  143.     // Replace placeholders
  144.     memcpy(codeToInject + 1, &dwOldIP, sizeof(dwOldIP));
  145.     memcpy(codeToInject + 31, &pRemoteMemDllName, sizeof(pRemoteMemDllName));
  146.     memcpy(codeToInject + 41, &fnLocLoadLibrary, sizeof(fnLocLoadLibrary));
  147.  
  148.     if(!WriteProcessMemory(hProcess, pRemoteMemFunction, codeToInject, nFunctionBuffSize, NULL))
  149.     {
  150.         std::wcout << L"Error: Failed to write the code cave" << std::endl;
  151.         goto cleanup;
  152.     }
  153.  
  154.     if(!SetThreadContext(hThread, &ctx))
  155.     {
  156.         std::wcout << L"Error: Failed to modify the thread context" << std::endl;
  157.         goto cleanup;
  158.     }
  159.  
  160.     // DLL Injection is successful
  161.     bRet = true;
  162.  
  163. cleanup:
  164.     // Cleanup allocated data
  165.     if(dwThreadSuspendCount != -1)
  166.         ResumeThread(hThread);
  167.  
  168.     // Sleep to allow the process loading the DLL.
  169.     if(bRet)
  170.         Sleep(1000);
  171.  
  172.     if(pRemoteMemDllName)
  173.         VirtualFreeEx(hProcess, pRemoteMemDllName, nDllNameBuffSize, MEM_RELEASE);
  174.  
  175.     if(pRemoteMemFunction)
  176.         VirtualFreeEx(hProcess, pRemoteMemFunction, nFunctionBuffSize, MEM_RELEASE);
  177.  
  178.     ::CloseHandle(hProcess);
  179.     ::CloseHandle(hThread);
  180.  
  181.     return bRet;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement