PDA

Просмотр полной версии : [C++] x64-x86 Thread Hijacking


ntharbinger
07.07.2019, 20:51
Перехватывает поток от игры и выполняет в его контексте ваш код.

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
09.08.2019, 01:42
В Польше работы мало нынче? ;)

https://forum.antichat.xyz/attachments/27382056/


да и тут скорее просто:

mov ecx, опкодер

xor ecx, ecx

Cake_
09.08.2019, 02:18
Звучит круто . Где это можно применить? Какая разница между отдельным потоком ?

atizoff
09.08.2019, 14:51
Звучит круто . Где это можно применить? Какая разница между отдельным потоком ?


в инжекторе

vadimka0216
28.10.2019, 15:48
Какие заголовочные файлы используешь?

клешь рояль
28.10.2019, 15:49
Какие заголовочные файлы используешь?


я не уверен что он тебе ответит