Coder666

DLL Injection Test C++

Oct 22nd, 2022 (edited)
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.19 KB | Source Code | 0 0
  1. // DllInjectionTest.cpp
  2. // Tested on: Windows 11
  3. // platform x64
  4. // Develpment on C++ VS 2019
  5. //
  6. // Tip: on 64bit box Compile on 64bit archiecture!
  7. //
  8. ////////////////////////////////////
  9.  
  10. #include <iostream>
  11. #include <cstdio>
  12. #include <windows.h>
  13. #include <tlhelp32.h>
  14. #include <tchar.h>
  15. #include <TlHelp32.h>
  16.  
  17. #define NT_SUCCESS(x) ((x) >= 0)
  18.  
  19. typedef struct _CLIENT_ID {
  20.     HANDLE UniqueProcess;
  21.     HANDLE UniqueThread;
  22. } CLIENT_ID, * PCLIENT_ID;
  23.  
  24. typedef NTSTATUS(NTAPI* pfnRtlCreateUserThread)(
  25.     IN HANDLE ProcessHandle,
  26.     IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
  27.     IN BOOLEAN CreateSuspended,
  28.     IN ULONG StackZeroBits OPTIONAL,
  29.     IN SIZE_T StackReserve OPTIONAL,
  30.     IN SIZE_T StackCommit OPTIONAL,
  31.     IN PTHREAD_START_ROUTINE StartAddress,
  32.     IN PVOID Parameter OPTIONAL,
  33.     OUT PHANDLE ThreadHandle OPTIONAL,
  34.     OUT PCLIENT_ID ClientId OPTIONAL);
  35.  
  36.  
  37. typedef NTSTATUS(WINAPI* LPFUN_NtCreateThreadEx)
  38. (
  39.     OUT PHANDLE hThread,
  40.     IN ACCESS_MASK DesiredAccess,
  41.     IN LPVOID ObjectAttributes,
  42.     IN HANDLE ProcessHandle,
  43.     IN LPTHREAD_START_ROUTINE lpStartAddress,
  44.     IN LPVOID lpParameter,
  45.     IN BOOL CreateSuspended,
  46.     IN ULONG StackZeroBits,
  47.     IN ULONG SizeOfStackCommit,
  48.     IN ULONG SizeOfStackReserve,
  49.     OUT LPVOID lpBytesBuffer
  50.     );
  51.  
  52. //Buffer argument passed to NtCreateThreadEx function
  53.  
  54. struct NtCreateThreadExBuffer
  55. {
  56.     ULONG Size;
  57.     ULONG Unknown1;
  58.     ULONG Unknown2;
  59.     PULONG Unknown3;
  60.     ULONG Unknown4;
  61.     ULONG Unknown5;
  62.     ULONG Unknown6;
  63.     PULONG Unknown7;
  64.     ULONG Unknown8;
  65. };
  66.  
  67.  
  68. #define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
  69.  
  70. BOOL DllInject_1(UINT32 ProcessId, char *DLL_NAME)
  71. {
  72.     LPVOID LoadLibAddr, RemoteString;
  73.     HANDLE hThread;
  74.     DWORD dwWaitResult, dwExitResult = 0;
  75.  
  76.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
  77.  
  78.     if (hProcess == NULL)
  79.     {
  80.         std::cout << "Cannot get the Process ID " << ProcessId;
  81.         return (0);
  82.     }
  83.  
  84.     Sleep(2000);
  85.  
  86.     LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryA");
  87.     if (LoadLibAddr == NULL)
  88.     {
  89.         return (0);
  90.     }
  91.  
  92.     //Allocates a buffer for and writes the path to the DLL we want to inject inside of the target process's memory
  93.     RemoteString = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(DLL_NAME)+1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  94.     if (RemoteString == NULL)
  95.     {
  96.         return (0);
  97.     }
  98.    
  99.     if (!WriteProcessMemory(hProcess, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME)+1, NULL))
  100.     {
  101.         return (0);
  102.     }
  103.  
  104.     //Calls LoadLibrary on our specified DLL in the target process
  105.     hThread = CreateRemoteThread(
  106.         hProcess,
  107.         NULL,
  108.         NULL,
  109.         (LPTHREAD_START_ROUTINE)LoadLibAddr,
  110.         (LPVOID)RemoteString,
  111.         NULL,
  112.         NULL
  113.     );
  114.  
  115.     if (hThread != NULL) {
  116.         dwWaitResult = WaitForSingleObject(hThread, 10000); // keep the dll injection action for 10 seconds before free.
  117.         GetExitCodeThread(hThread, &dwExitResult);
  118.         CloseHandle(hThread);
  119.         VirtualFreeEx(hProcess, RemoteString, 0, MEM_RELEASE);
  120.         return (1);
  121.     }
  122.  
  123.     return (0);
  124. }
  125.  
  126. BOOL DllInject_2(UINT32 ProcessId, char* DLL_NAME)
  127. {
  128.     HANDLE ProcessHandle = NULL;
  129.  
  130.     ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
  131.  
  132.  
  133.     UINT32  DllFullPathLength = (strlen(DLL_NAME));
  134.     PVOID DllFullPathBufferData = VirtualAllocEx(ProcessHandle, NULL, DllFullPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  135.     if (DllFullPathBufferData == NULL)
  136.     {
  137.         CloseHandle(ProcessHandle);
  138.         return FALSE;
  139.     }
  140.  
  141.     SIZE_T  ReturnLength;
  142.     BOOL bOk = WriteProcessMemory(ProcessHandle, DllFullPathBufferData, DLL_NAME, strlen(DLL_NAME), &ReturnLength);
  143.  
  144.     LPTHREAD_START_ROUTINE  LoadLibraryAddress = NULL;
  145.     HMODULE                 Kernel32Module = GetModuleHandle(L"Kernel32");
  146.  
  147.     LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryA");
  148.  
  149.     pfnRtlCreateUserThread RtlCreateUserThread = (pfnRtlCreateUserThread)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlCreateUserThread");
  150.  
  151.    
  152.     HANDLE ThreadHandle = NULL;
  153.     NTSTATUS Status = RtlCreateUserThread(ProcessHandle, NULL, FALSE, 0, 0, 0, LoadLibraryAddress, DllFullPathBufferData, &ThreadHandle, NULL);
  154.     if (ThreadHandle == NULL)
  155.     {
  156.         CloseHandle(ProcessHandle);
  157.         return FALSE;
  158.     }
  159.     if (!NT_SUCCESS(Status))
  160.     {
  161.         CloseHandle(ProcessHandle);
  162.         return FALSE;
  163.     }
  164.  
  165.     if (WaitForSingleObject(ThreadHandle, INFINITE) == WAIT_FAILED)
  166.     {
  167.         return FALSE;
  168.     }
  169.  
  170.     CloseHandle(ProcessHandle);
  171.     CloseHandle(ThreadHandle);
  172.  
  173.     return TRUE;
  174. }
  175.  
  176.  
  177. int EnableSeDebugPrivilege(void) {
  178.     HANDLE hToken;
  179.     LUID Val;
  180.     TOKEN_PRIVILEGES tp;
  181.  
  182.     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  183.         return(GetLastError());
  184.  
  185.     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Val))
  186.         return(GetLastError());
  187.  
  188.     tp.PrivilegeCount = 1;
  189.     tp.Privileges[0].Luid = Val;
  190.     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  191.  
  192.     if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
  193.         return(GetLastError());
  194.  
  195.     CloseHandle(hToken);
  196.  
  197.     return 1;
  198. }
  199.  
  200.  
  201. int main(int argc, char *argv[])
  202. {
  203.     DWORD dwTargetProcessID = 0;
  204.     char DLL_NAME[512] = "";
  205.     int iMethod = 0;
  206.  
  207.     if (argc == 4)
  208.     {
  209.         iMethod = atoi(argv[1]);
  210.         if ((iMethod < 1) || (iMethod > 2))
  211.         {
  212.             std::cout << "** Arg(1) must be 1 or 2.";
  213.             return (-1);
  214.         }
  215.  
  216.         strcpy_s(DLL_NAME, argv[2]);
  217.         dwTargetProcessID = atoi(argv[3]);
  218.     }
  219.     else
  220.     {
  221.         std::cout << "** Usage: <1 | 2> <Full_DLL_Path_and_Filename> <ProcessID> ";
  222.         std::cout << "** Arg(1) is the method will be used for DLL injection.";
  223.         return -1;
  224.     }
  225.  
  226.     std::cout << "DLL Injection Test \n";
  227.  
  228.     if (EnableSeDebugPrivilege() == 1)
  229.         std::cout <<  "[+] Get All Privilege [ok!].\n";
  230.     else
  231.         std::cout << "[-]Cannot Get All Privilege.\n";
  232.  
  233.  
  234.     std::cout << "[+] Try to inject...";
  235.     /// //// ---------------------------------------------------------------------
  236.     DWORD CurrentSessionID, RemoteSessionID, RemoteProcessID;
  237.     if (!ProcessIdToSessionId(GetCurrentProcessId(), &CurrentSessionID))
  238.     {
  239.         std::cout << "\nFailed to get the current session with error" << GetLastError() ;
  240.         return -1;
  241.     }
  242.     if (!ProcessIdToSessionId(dwTargetProcessID, &RemoteSessionID))
  243.     {
  244.         std::cout << "\nFailed to get the remote session with error" << GetLastError() ;
  245.         return -2;
  246.     }
  247.  
  248.     BOOLEAN bResult = false;
  249.  
  250.  
  251.     (iMethod == 1) ? (bResult = DllInject_1(dwTargetProcessID, DLL_NAME)) : (bResult = DllInject_2(dwTargetProcessID, DLL_NAME));
  252.  
  253.     if (bResult)
  254.     {
  255.         std::cout << "\nSUCCESSFUL!\n";
  256.     }
  257.     else
  258.     {
  259.         std::cout << "\nFailed!\n";
  260.         return -3;
  261.     }
  262.  
  263.     return 1;
  264.  
  265. }
  266.  
Advertisement
Add Comment
Please, Sign In to add comment