- 13
- 37
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Перехватывает поток от игры и выполняет в его контексте ваш код.
x64 архитектура
x86 архитектура
hProcess - хендл целевого процесса
procID - ид целевого процесса
struct_address - адрес структуры загрузчика
loader_address - адрес загрузчика кода
Автор: ntharbinger
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
Последнее редактирование: