Исходник [C++] x64-x86 Thread Hijacking

ntharbinger

Потрачен
Автор темы
13
36
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Перехватывает поток от игры и выполняет в его контексте ваш код.

x64 архитектура
C++:
void HijackThreadContext(HANDLE hProcess, DWORD procID, DWORD64 struct_address, DWORD64 loader_address)
{
    BYTE SaveRegisters[23] = { 0x50, 0x51, 0x52, 0x53, 0x55, 0x56, 0x57,
    0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57 };
    BYTE LeaInRCX[7] = { 0x48, 0x8D, 0x0D, 0x25, 0x00, 0x00, 0x18 };
    BYTE CALL[5] = { 0xE8, 0x15, 0x25, 0x30, 0x00 };
    BYTE RestoreRegisters[23] = { 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58,
    0x5F, 0x5E, 0x5D, 0x5B, 0x5A, 0x59, 0x58 };
    BYTE SaveRAX[7] = { 0x48, 0x89, 0x05, 0xFF, 0xFF, 0xFF, 0xFF };
    BYTE MovInRAX[10] = { 0x48, 0xB8, 0xBC, 0xD2, 0x8B, 0x81, 0xFC, 0x7F, 0x00, 0x00 };
    BYTE PushRAX[1] = { 0x50 };
    BYTE RestoreRAX[7] = { 0x48, 0x8B, 0x05, 0xFF, 0xFF, 0xFF, 0xFF };
    BYTE Ret[1] = { 0xC3 };
    DWORD stub_size = (sizeof(SaveRegisters) + sizeof(LeaInRCX) +
    sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX) + sizeof(MovInRAX) +
    sizeof(PushRAX) + sizeof(RestoreRAX) + sizeof(Ret));
    DWORD64 rip_address = 0x0; DWORD ThreadID = 0x0;
    PVOID stub_address = VirtualAllocEx(hProcess, 0, stub_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    PVOID RAX = VirtualAllocEx(hProcess, 0, 8, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    THREADENTRY32 th32; HANDLE hSnapshot = NULL; th32.dwSize = sizeof(THREADENTRY32);
    auto GetThreadID = [procID]() -> DWORD
    {
        THREADENTRY32 th32; HANDLE hSnapshot = NULL; th32.dwSize = sizeof(THREADENTRY32);
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
        if (Thread32First(hSnapshot, &th32))
        {
            do
            {
                if (th32.th32OwnerProcessID != procID) continue;
                CloseHandle(hSnapshot);
                return th32.th32ThreadID;
            } while (Thread32Next(hSnapshot, &th32));
        }
        if (hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot);
        return 0;
    };
    ThreadID = GetThreadID();
    HANDLE pThread = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadID);
    if (pThread)
    {
        SuspendThread(pThread); CONTEXT ctx; ctx.ContextFlags = CONTEXT_CONTROL;
        GetThreadContext(pThread, &ctx, sizeof(ctx));
        rip_address = ctx.Rip;
        auto FindDelta = [](auto DestinyAddress, auto SourceAddress, size_t InstructionLength) -> uint32_t
        {
            return DestinyAddress - (SourceAddress + InstructionLength);
        };
        WriteProcessMemory(hProcess, stub_address, SaveRegisters, sizeof(SaveRegisters), FALSE);
        DWORD64 Delta = FindDelta(struct_address, (stub_address + sizeof(SaveRegisters)), sizeof(LeaInRCX));
        memcpy(&LeaInRCX[3], &Delta, 4);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters)), LeaInRCX, sizeof(LeaInRCX), FALSE);
        Delta = FindDelta(loader_address, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX)), sizeof(CALL));
        memcpy(&CALL[1], &Delta, 4);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX)), CALL, sizeof(CALL), FALSE);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) + sizeof(CALL)),
        RestoreRegisters, sizeof(RestoreRegisters), FALSE);
        Delta = FindDelta(RAX, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters)), sizeof(SaveRAX));
        memcpy(&SaveRAX[3], &Delta, 4);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters)), SaveRAX, sizeof(SaveRAX), FALSE);
        memcpy(&MovInRAX[2], &rip_address, 8);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX)), MovInRAX, sizeof(MovInRAX), FALSE);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX) + sizeof(MovInRAX)), PushRAX, sizeof(PushRAX), FALSE);
        Delta = FindDelta(RAX, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX) + sizeof(MovInRAX) + sizeof(PushRAX)), sizeof(RestoreRAX));
        memcpy(&RestoreRAX[3], &Delta, 4);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX) + sizeof(MovInRAX) + sizeof(PushRAX)), RestoreRAX, sizeof(RestoreRAX), FALSE);
        WriteProcessMemory(hProcess, (stub_address + sizeof(SaveRegisters) + sizeof(LeaInRCX) +
        sizeof(CALL) + sizeof(RestoreRegisters) + sizeof(SaveRAX) + sizeof(MovInRAX) + sizeof(PushRAX) + sizeof(RestoreRAX)), Ret, sizeof(Ret), FALSE);
        ctx.Rip = stub_address; BOOL rslt = SetThreadContext(hProcess, &ctx, sizeof(ctx));
        ResumeProcess(hProcess); CloseHandle(pThread);
    }
}

x86 архитектура
C++:
void HijackThreadContext(HANDLE hProcess, DWORD ProcID, DWORD struct_address, DWORD loader_address)
{
    DWORD retAddr = 0x0; LPVOID ShellCode = VirtualAllocEx(hProcess, 0, 20, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    auto GetThreadID = [&, ProcID]() -> DWORD
    {
        THREADENTRY32 th32; HANDLE hSnapshot = NULL; th32.dwSize = sizeof(THREADENTRY32);
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
        if (Thread32First(hSnapshot, &th32))
        {
            do
            {
                if (th32.th32OwnerProcessID != ProcID) continue;
                return th32.th32ThreadID;
            } while (Thread32Next(hSnapshot, &th32));
        }
        if (hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot);
        return 0;
    };
    HANDLE pThread = OpenThread(THREAD_ALL_ACCESS, FALSE, GetThreadID());
    if (pThread)
    {
        SuspendThread(pThread); CONTEXT ctx; ctx.ContextFlags = CONTEXT_ALL;
        GetThreadContext(pThread, &ctx); retAddr = ctx.Eip; ctx.Eip = (DWORD)ShellCode;
        BYTE SaveRegisters[] = { 0x60, 0x66, 0x60 };
        BYTE PushEAX[] = { 0x68, 0x90, 0x90, 0x90, 0x90 };
        BYTE CallDWORD[] = { 0xE8, 0x54, 0x50, 0xCE, 0x0F };
        BYTE RestoreRegisters[] = { 0x66, 0x61, 0x61 };
        BYTE JmpEIP[] = { 0xE9, 0x25, 0x00, 0xA8, 0xCE };
        auto FindDelta = [](DWORD DestinyAddress, DWORD SourceAddress, size_t InstructionLength) -> uint32_t
        {
            return DestinyAddress - (SourceAddress + InstructionLength);
        };
        memcpy(&PushEAX[1], &struct_address, 4); DWORD Delta = FindDelta(loader_address,
        ((DWORD)ShellCode + sizeof(SaveRegisters) + sizeof(PushEAX)), sizeof(CallDWORD));
        memcpy(&CallDWORD[1], &Delta, 4); Delta = FindDelta(retAddr, ((DWORD)ShellCode + sizeof(SaveRegisters) + sizeof(PushEAX) +
        sizeof(CallDWORD) + sizeof(RestoreRegisters)), sizeof(JmpEIP)); memcpy(&JmpEIP[1], &Delta, 4);
        WriteProcessMemory(hProcess, ShellCode, SaveRegisters, sizeof(SaveRegisters), NULL);
        WriteProcessMemory(hProcess, (PVOID)((DWORD)ShellCode + sizeof(SaveRegisters)), PushEAX, sizeof(PushEAX), NULL);
        WriteProcessMemory(hProcess, (PVOID)((DWORD)ShellCode + sizeof(SaveRegisters) + sizeof(PushEAX)), CallDWORD, sizeof(CallDWORD), NULL);
        WriteProcessMemory(hProcess, (PVOID)((DWORD)ShellCode + sizeof(SaveRegisters) + sizeof(PushEAX) + sizeof(CallDWORD)),
        RestoreRegisters, sizeof(RestoreRegisters), NULL); WriteProcessMemory(hProcess, (PVOID)((DWORD)ShellCode +
        sizeof(SaveRegisters) + sizeof(PushEAX) + sizeof(CallDWORD) + sizeof(RestoreRegisters)), JmpEIP, sizeof(JmpEIP), NULL);
        SetThreadContext(pThread, &ctx); ResumeThread(pThread); CloseHandle(pThread);
    }
}

hProcess - хендл целевого процесса
procID - ид целевого процесса
struct_address - адрес структуры загрузчика
loader_address - адрес загрузчика кода


Автор: ntharbinger
 
Последнее редактирование:

gedwadion

Известный
56
17
В Польше работы мало нынче? ;)

36808


да и тут скорее просто:
mov ecx, опкодер
xor ecx, ecx :ROFLMAO:
 
Последнее редактирование:

Cake_

Известный
Проверенный
263
313
Звучит круто . Где это можно применить? Какая разница между отдельным потоком ?