adafcaefc

Apxaey's Thread Spoofer

Feb 23rd, 2021 (edited)
580
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cinttypes>
  2. #include <time.h>
  3.  
  4. typedef struct _CLIENT_ID
  5. {
  6.     PVOID UniqueProcess;
  7.     PVOID UniqueThread;
  8. } CLIENT_ID, * PCLIENT_ID;
  9.  
  10. typedef NTSTATUS(NTAPI* RtlCreateUserThread_t)
  11. (
  12.     IN      HANDLE               ProcessHandle,
  13.     IN      PSECURITY_DESCRIPTOR SecurityDescriptor,
  14.     IN      BOOLEAN              CreateSuspended,
  15.     IN      ULONG                StackZeroBits,
  16.     IN OUT  PULONG               StackReserved,
  17.     IN OUT  PULONG               StackCommit,
  18.     IN      PVOID                StartAddress,
  19.     IN      PVOID                StartParameter,
  20.     OUT     PHANDLE              ThreadHandle,
  21.     OUT     PCLIENT_ID           ClientID
  22. );
  23.  
  24. HANDLE CreateSpoofedThread(void* thread, HMODULE hMod)
  25. {
  26.     srand(time(NULL));
  27.     SIZE_T DEFAULT_THREAD_SIZE = 0x400;
  28.  
  29.     // Load ntdll
  30.     LoadLibraryA("ntdll");
  31.     auto hNtdll = GetModuleHandleA("ntdll");
  32.     if (!hNtdll) return nullptr;
  33.     auto _RtlCreateUserThread = GetProcAddress(hNtdll, "RtlCreateUserThread");
  34.     if (!_RtlCreateUserThread) return nullptr;
  35.  
  36.     // Spoofed address
  37.     std::uintptr_t tAddress = NULL;
  38.  
  39.     // Generate random memory address
  40.     for (int i = 1; i < 4; ++i)
  41.         for (int j = 1; j < 4; j++)
  42.             tAddress |= (rand() & 0xFF) << i * 8;
  43.  
  44.     // Make sure it's not out-of-bounds
  45.     while (tAddress < INT32_MAX)
  46.         tAddress -= INT16_MAX;
  47.  
  48.     // VP the memory address
  49.     VirtualProtect(reinterpret_cast<LPVOID>(tAddress), DEFAULT_THREAD_SIZE, PAGE_EXECUTE_READWRITE, nullptr);
  50.  
  51.     CONTEXT tContext;
  52.     HANDLE tHandle = nullptr;
  53.  
  54.     RtlCreateUserThread_t RtlCreateUserThread_f = reinterpret_cast<RtlCreateUserThread_t>(_RtlCreateUserThread);
  55.     RtlCreateUserThread_f(GetCurrentProcess(), nullptr, TRUE, NULL, nullptr, nullptr, (PTHREAD_START_ROUTINE)tAddress, hMod, &tHandle, nullptr);
  56.     if (!tHandle) return nullptr;
  57.  
  58.     tContext.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
  59.  
  60.     GetThreadContext(tHandle, &tContext);
  61.  
  62. #ifdef _WIN32
  63.     tContext.Eax = reinterpret_cast<ULONG32>(thread);
  64. #else
  65.     tContext.Rcx = reinterpret_cast<ULONG64>(thread);
  66. #endif
  67.     tContext.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
  68.  
  69.     SetThreadContext(tHandle, &tContext);
  70.     ResumeThread(tHandle);
  71.  
  72.     return tHandle;
  73. }
RAW Paste Data