PDA

Просмотр полной версии : [C++] MTA:SA 1.5.6 | Process Handle Hijacker (Обход античита)


ntharbinger
07.07.2019, 15:34
Ворует хендл процесса игры прямо с под UserMode не взирая на их драйверный античит FairPlay.

Плюсы:

~ Не трогает системных процессов.

~ Работает с user-mode.

~ Способ адаптивен под любой кастом клиент MTA:SA.

Минусы:

~ Из-за особенностей хайжакера имеет ряд требований для его успешного использования.

~ Иногда работает не сразу а через раз.

Требования:

~ МТА в обязательном порядке должна запускаться с админ правами как и сам HandleHijacker

~ В папке с игрой не должно находится никаких .asi плагинов и модификаций.

~ МТА не должна иметь каких либо проблем с запуском (никаких Warning табличек).

~ Для успешного использования ваш хак должен быть запущен ещё до запуска лаунчера игры.

# Утиль #

Registry.h (Работа с реестром by SR_Team)




C++:






#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
class
CRegistry
{
protected
:
HKEY _hKey
;
bool
error_success
;
bool
GetRegister
(
LPCSTR lpName
,
DWORD dwType
,
void
*
outBuf
,
DWORD size
)
;
bool
SetRegister
(
LPCSTR lpName
,
DWORD dwType
,
void
*
inBuf
,
DWORD size
)
;
bool
GetRegisterDefault
(
LPSTR outBuf
,
LONG maxSize
)
;
bool
SetRegisterDefault
(
LPCSTR inBuf
)
;
bool
DeleteRegister
(
LPCSTR lpName
)
;
bool
AutoSizeWrite
(
DWORD dwType
,
void
*
inBuf
,
DWORD
&
size
)
;
bool
AutoSizeRead
(
DWORD dwType
,
void
*
outBuf
,
DWORD
&
size
)
;
CRegistry
(
HKEY hKey
,
LPCSTR lpSubKey
,
bool
mode
)
;
~
CRegistry
(
)
;
}
;
class
CEasyRegistry
:
CRegistry
{
public
:
bool
no_error
;
bool
ErrorSuccess
(
)
;
void
WriteString
(
LPCSTR lpName
,
LPSTR lpString
,
.
.
.
)
;
std
::
string
ReadString
(
LPCSTR lpName
)
;
void
WriteInteger
(
LPCSTR lpName
,
int
value
)
;
int
ReadInteger
(
LPCSTR lpName
)
;
void
WriteFloat
(
LPCSTR lpName
,
float
value
)
;
float
ReadFloat
(
LPCSTR lpName
)
;
void
WriteLongLong
(
LPCSTR lpName
,
long
long
value
)
;
long
long
ReadLongLong
(
LPCSTR lpName
)
;
void
WriteDouble
(
LPCSTR lpName
,
double
value
)
;
double
ReadDouble
(
LPCSTR lpName
)
;
void
DeleteKey
(
LPCSTR lpName
)
;
bool
IsError
(
)
;
CEasyRegistry
(
HKEY hKey
,
LPCSTR lpSubKey
,
bool
mode
)
;
~
CEasyRegistry
(
)
;
}
;







Registry.cpp




C++:






#include "Registry.h"
#include
#pragma comment (lib, "advapi32")
#pragma warning(disable : 4267)
CRegistry
::
CRegistry
(
HKEY hKey
,
LPCSTR lpSubKey
,
bool
mode
)
{
_hKey
=
0
;
if
(
RegOpenKeyExA
(
hKey
,
lpSubKey
,
0
,
KEY_ALL_ACCESS
,
&
_hKey
)
!=
ERROR_SUCCESS
)
{
if
(
mode
==
true
)
RegCreateKeyExA
(
hKey
,
lpSubKey
,
0
,
NULL
,
REG_OPTION_NON_VOLATILE
,
KEY_ALL_ACCESS
,
NULL
,
&
_hKey
,
NULL
)
;
}
else
error_success
=
true
;
}
CRegistry
::
~
CRegistry
(
)
{
if
(
_hKey
!=
NULL
)
RegCloseKey
(
_hKey
)
;
}
bool
CRegistry
::
GetRegister
(
LPCSTR lpName
,
DWORD dwType
,
void
*
outBuf
,
DWORD size
)
{
if
(
outBuf
==
nullptr
||
_hKey
==
NULL
)
return
false
;
if
(
!
strlen
(
lpName
)
)
return
false
;
if
(
!
AutoSizeRead
(
dwType
,
outBuf
,
size
)
)
return
false
;
return
!
RegQueryValueExA
(
_hKey
,
lpName
,
NULL
,
&
dwType
,
(
byte
*
)
outBuf
,
&
size
)
;
}
bool
CRegistry
::
SetRegister
(
LPCSTR lpName
,
DWORD dwType
,
void
*
inBuf
,
DWORD size
)
{
if
(
inBuf
==
nullptr
||
_hKey
==
NULL
)
return
false
;
if
(
!
strlen
(
lpName
)
)
return
false
;
if
(
!
AutoSizeWrite
(
dwType
,
inBuf
,
size
)
)
return
false
;
return
!
RegSetValueExA
(
_hKey
,
lpName
,
0
,
dwType
,
(
byte
*
)
inBuf
,
size
)
;
}
bool
CRegistry
::
GetRegisterDefault
(
LPSTR outBuf
,
LONG maxSize
)
{
if
(
outBuf
==
nullptr
||
_hKey
==
NULL
)
return
false
;
return
!
RegQueryValueA
(
_hKey
,
NULL
,
(
LPSTR
)
outBuf
,
&
maxSize
)
;
}
bool
CRegistry
::
SetRegisterDefault
(
LPCSTR inBuf
)
{
if
(
inBuf
==
nullptr
||
_hKey
==
NULL
)
return
false
;
return
!
RegSetValueA
(
_hKey
,
NULL
,
REG_SZ
,
inBuf
,
strlen
(
inBuf
)
)
;
}
bool
CRegistry
::
DeleteRegister
(
LPCSTR lpName
)
{
if
(
_hKey
==
NULL
)
return
false
;
if
(
!
strlen
(
lpName
)
)
return
false
;
return
!
RegDeleteKeyEx
(
_hKey
,
lpName
,
KEY_WOW64_32KEY
,
NULL
)
;
}
bool
CRegistry
::
AutoSizeWrite
(
DWORD dwType
,
void
*
inBuf
,
DWORD
&
size
)
{
if
(
!
size
)
{
switch
(
dwType
)
{
case
REG_BINARY
:
size
=
1
;
break
;
case
REG_DWORD
:
case
REG_DWORD_BIG_ENDIAN
:
size
=
4
;
break
;
case
REG_QWORD
:
size
=
8
;
break
;
case
REG_EXPAND_SZ
:
case
REG_LINK
:
case
REG_MULTI_SZ
:
case
REG_SZ
:
size
=
strlen
(
(
LPCSTR
)
inBuf
)
;
break
;
case
REG_NONE
:
default
:
return
false
;
}
}
return
true
;
}
bool
CRegistry
::
AutoSizeRead
(
DWORD dwType
,
void
*
outBuf
,
DWORD
&
size
)
{
if
(
!
size
)
{
switch
(
dwType
)
{
case
REG_BINARY
:
size
=
1
;
break
;
case
REG_DWORD
:
case
REG_DWORD_BIG_ENDIAN
:
size
=
4
;
break
;
case
REG_QWORD
:
size
=
8
;
break
;
case
REG_EXPAND_SZ
:
case
REG_LINK
:
case
REG_MULTI_SZ
:
case
REG_SZ
:
case
REG_NONE
:
default
:
return
false
;
}
}
return
true
;
}
CEasyRegistry
::
CEasyRegistry
(
HKEY hKey
,
LPCSTR lpSubKey
,
bool
mode
)
:
CRegistry
(
hKey
,
lpSubKey
,
mode
)
{
no_error
=
true
;
}
CEasyRegistry
::
~
CEasyRegistry
(
)
{
}
void
CEasyRegistry
::
DeleteKey
(
LPCSTR lpName
)
{
no_error
=
DeleteRegister
(
lpName
)
;
}
void
CEasyRegistry
::
WriteString
(
LPCSTR lpName
,
LPSTR lpString
,
.
.
.
)
{
va_list ap
;
char
*
szStr
=
new
char
[
strlen
(
lpString
)
*
2
+
1024
]
;
va_start
(
ap
,
lpString
)
;
vsprintf
(
szStr
,
lpString
,
ap
)
;
va_end
(
ap
)
;
no_error
=
SetRegister
(
lpName
,
REG_SZ
,
szStr
,
strlen
(
szStr
)
)
;
delete
[
]
szStr
;
}
std
::
string CEasyRegistry
::
ReadString
(
LPCSTR lpName
)
{
char
szStr
[
0x1000
]
;
no_error
=
GetRegister
(
lpName
,
REG_SZ
,
szStr
,
0x1000
)
;
return
szStr
;
}
void
CEasyRegistry
::
WriteInteger
(
LPCSTR lpName
,
int
value
)
{
no_error
=
SetRegister
(
lpName
,
REG_DWORD
,
&
value
,
0
)
;
}
int
CEasyRegistry
::
ReadInteger
(
LPCSTR lpName
)
{
int
value
;
no_error
=
GetRegister
(
lpName
,
REG_DWORD
,
&
value
,
0
)
;
return
value
;
}
void
CEasyRegistry
::
WriteFloat
(
LPCSTR lpName
,
float
value
)
{
no_error
=
SetRegister
(
lpName
,
REG_DWORD
,
&
value
,
0
)
;
}
float
CEasyRegistry
::
ReadFloat
(
LPCSTR lpName
)
{
float
value
;
no_error
=
GetRegister
(
lpName
,
REG_DWORD
,
&
value
,
0
)
;
return
value
;
}
void
CEasyRegistry
::
WriteLongLong
(
LPCSTR lpName
,
long
long
value
)
{
no_error
=
SetRegister
(
lpName
,
REG_QWORD
,
&
value
,
0
)
;
}
long
long
CEasyRegistry
::
ReadLongLong
(
LPCSTR lpName
)
{
long
long
value
;
no_error
=
GetRegister
(
lpName
,
REG_QWORD
,
&
value
,
0
)
;
return
value
;
}
void
CEasyRegistry
::
WriteDouble
(
LPCSTR lpName
,
double
value
)
{
no_error
=
SetRegister
(
lpName
,
REG_QWORD
,
&
value
,
0
)
;
}
double
CEasyRegistry
::
ReadDouble
(
LPCSTR lpName
)
{
double
value
;
no_error
=
GetRegister
(
lpName
,
REG_QWORD
,
&
value
,
0
)
;
return
value
;
}
bool
CEasyRegistry
::
IsError
(
)
{
return
!
no_error
;
}
bool
CEasyRegistry
::
ErrorSuccess
(
)
{
if
(
error_success
==
true
)
return
true
;
return
false
;
}







DLL`ка для воровства хендла

dllmain.cpp




C++:






#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4244)
#pragma warning(disable : 4005)
#pragma warning(disable : 4477)
#pragma warning(disable : 4311)
#pragma warning(disable : 4302)
#pragma warning(disable : 4313)
#include
#include
#include
#include
#include
#include
#include "Registry.h"
#pragma comment(lib, "Psapi.lib")
using
namespace
std
;
DWORD_PTR hookAddr
,
origAddr
;
DWORD __stdcall
ExceptionFilter
(
EXCEPTION_POINTERS
*
pExceptionInfo
)
{
if
(
pExceptionInfo
->
ExceptionRecord
->
ExceptionCode
==
STATUS_GUARD_PAGE_VIOLATION
)
{
#ifdef _WIN64
if
(
pExceptionInfo
->
ContextRecord
->
Rip
==
origAddr
)
pExceptionInfo
->
ContextRecord
->
Rip
=
hookAddr
;
#else
if
(
pExceptionInfo
->
ContextRecord
->
Eip
==
origAddr
)
pExceptionInfo
->
ContextRecord
->
Eip
=
hookAddr
;
#endif
pExceptionInfo
->
ContextRecord
->
EFlags
|=
0x100
;
return
EXCEPTION_CONTINUE_EXECUTION
;
}
if
(
pExceptionInfo
->
ExceptionRecord
->
ExceptionCode
==
STATUS_SINGLE_STEP
)
{
DWORD dwOld
;
VirtualProtect
(
(
void
*
)
origAddr
,
1
,
PAGE_EXECUTE
|
PAGE_GUARD
,
&
dwOld
)
;
return
EXCEPTION_CONTINUE_EXECUTION
;
}
return
EXCEPTION_CONTINUE_SEARCH
;
}
void
SetupVEH
(
DWORD_PTR funcAddr
,
DWORD_PTR hookedFunc
)
{
hookAddr
=
hookedFunc
;
origAddr
=
funcAddr
;
AddVectoredExceptionHandler
(
true
,
(
PVECTORED_EXCEPTION_HANDLER
)
ExceptionFilter
)
;
DWORD dwOld
;
VirtualProtect
(
(
void
*
)
origAddr
,
1
,
PAGE_EXECUTE
|
PAGE_GUARD
,
&
dwOld
)
;
}
void
DeleteVEH
(
)
{
DWORD dwOld
;
VirtualProtect
(
(
void
*
)
origAddr
,
1
,
PAGE_EXECUTE_READWRITE
,
&
dwOld
)
;
RemoveVectoredExceptionHandler
(
ExceptionFilter
)
;
}
typedef
HANDLE
(
__stdcall
*
CallRemoteThread
)
(
HANDLE hProcess
,
LPSECURITY_ATTRIBUTES lpThreadAttributes
,
SIZE_T dwStackSize
,
LPTHREAD_START_ROUTINE lpStartAddress
,
LPVOID lpParameter
,
DWORD dwCreationFlags
,
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList
,
LPDWORD lpThreadId
)
;
CallRemoteThread CRT
=
nullptr
;
HANDLE __stdcall
HookRemoteThread
(
HANDLE hProcess
,
LPSECURITY_ATTRIBUTES lpThreadAttributes
,
SIZE_T dwStackSize
,
LPTHREAD_START_ROUTINE lpStartAddress
,
LPVOID lpParameter
,
DWORD dwCreationFlags
,
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList
,
LPDWORD lpThreadId
)
{
auto
strdel
=
[
]
(
char
*
s
,
size_t offset
,
size_t count
)
->
char
*
{
size_t len
=
strlen
(
s
)
;
if
(
offset
>
len
)
return
s
;
if
(
(
offset
+
count
)
>
len
)
count
=
len
-
offset
;
strcpy
(
s
+
offset
,
s
+
offset
+
count
)
;
return
s
;
}
;
auto
GetExternalProcName
=
[
&
,
strdel
]
(
HANDLE hProc
)
->
string
{
CHAR szFileName
[
MAX_PATH
+
1
]
;
K32GetModuleFileNameExA
(
hProc
,
NULL
,
szFileName
,
MAX_PATH
+
1
)
;
char
fname
[
256
]
;
char
*
ipt
=
strrchr
(
szFileName
,
'\\'
)
;
memset
(
fname
,
0
,
sizeof
(
fname
)
)
;
strdel
(
szFileName
,
0
,
(
ipt
-
szFileName
+
1
)
)
;
strncpy
(
fname
,
szFileName
,
strlen
(
szFileName
)
)
;
std
::
string
ProcName
(
fname
)
;
return
ProcName
;
}
;
DeleteVEH
(
)
;
HANDLE hRet
=
CRT
(
hProcess
,
lpThreadAttributes
,
dwStackSize
,
lpStartAddress
,
lpParameter
,
dwCreationFlags
,
lpAttributeList
,
lpThreadId
)
;
if
(
!
strcmp
(
GetExternalProcName
(
hProcess
)
.
c_str
(
)
,
"proxy_sa.exe"
)
||
!
strcmp
(
GetExternalProcName
(
hProcess
)
.
c_str
(
)
,
"gta_sa.exe"
)
)
{
HANDLE hProc
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
GetCurrentProcessId
(
)
)
;
if
(
hProc
)
{
CEasyRegistry
*
reg
=
new
CEasyRegistry
(
HKEY_CURRENT_USER
,
"Software\\MftJacker"
,
false
)
;
reg
->
WriteInteger
(
"Hijacked"
,
0x1
)
;
CloseHandle
(
hProc
)
;
}
}
else
SetupVEH
(
(
DWORD
)
CRT
,
(
DWORD
)
&
HookRemoteThread
)
;
return
hRet
;
}
void
EntryPoint
(
)
{
auto
EnableDebugPrivilege
=
[
]
(
bool
fEnable
)
->
bool
{
HANDLE hToken
;
if
(
OpenProcessToken
(
GetCurrentProcess
(
)
,
TOKEN_ADJUST_PRIVILEGES
,
&
hToken
)
)
{
TOKEN_PRIVILEGES tp
;
tp
.
PrivilegeCount
=
1
;
LookupPrivilegeValue
(
NULL
,
SE_DEBUG_NAME
,
&
tp
.
Privileges
[
0
]
.
Luid
)
;
tp
.
Privileges
[
0
]
.
Attributes
=
fEnable
?
SE_PRIVILEGE_ENABLED
:
0
;
AdjustTokenPrivileges
(
hToken
,
false
,
&
tp
,
sizeof
(
tp
)
,
NULL
,
NULL
)
;
CloseHandle
(
hToken
)
;
}
return
true
;
}
;
EnableDebugPrivilege
(
true
)
;
CRT
=
(
CallRemoteThread
)
GetProcAddress
(
GetModuleHandleA
(
"kernelbase.dll"
)
,
"CreateRemoteThreadEx"
)
;
SetupVEH
(
(
DWORD
)
CRT
,
(
DWORD
)
&
HookRemoteThread
)
;
}
int
__stdcall
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
EntryPoint
(
)
;
break
;
case
DLL_THREAD_ATTACH
:
break
;
case
DLL_THREAD_DETACH
:
break
;
case
DLL_PROCESS_DETACH
:
DeleteVEH
(
)
;
break
;
}
return
1
;
}







HandleHijacker.cpp (Сам хендл-хайжекер на примере консольной программы)




C++:






#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4244)
#pragma warning(disable : 4005)
#pragma warning(disable : 4477)
#pragma warning(disable : 4311)
#pragma warning(disable : 4302)
#pragma warning(disable : 4313)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Registry.h"
using
namespace
std
;
string
RandomString
(
int
len
)
{
srand
(
time
(
0
)
)
;
string str
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn opqrstuvwxyz"
;
string newstr
;
int
pos
;
while
(
newstr
.
size
(
)
!=
len
)
{
pos
=
(
rand
(
)
%
61
)
;
newstr
+=
str
.
substr
(
pos
,
1
)
;
}
return
newstr
;
}
DWORD
GetProcId
(
const
char
*
ProcName
)
{
PROCESSENTRY32 pe32
;
HANDLE hSnapshot
=
NULL
;
pe32
.
dwSize
=
sizeof
(
PROCESSENTRY32
)
;
hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPPROCESS
,
0
)
;
if
(
Process32First
(
hSnapshot
,
&
pe32
)
)
{
do
{
if
(
strstr
(
pe32
.
szExeFile
,
ProcName
)
!=
nullptr
)
{
return
pe32
.
th32ProcessID
;
}
}
while
(
Process32Next
(
hSnapshot
,
&
pe32
)
)
;
}
if
(
hSnapshot
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
hSnapshot
)
;
return
-
1
;
}
#ifndef byte
typedef
unsigned
char
byte
;
#endif
typedef
DWORD COMPATIBLE_DWORD
;
typedef
uint32_t
uint_compatible
;
typedef
HMODULE
(
WINAPI
*
pLoadLibraryA
)
(
LPCSTR
)
;
typedef
FARPROC
(
WINAPI
*
pGetProcAddress
)
(
HMODULE
,
LPCSTR
)
;
typedef
BOOL
(
WINAPI
*
PDLL_MAIN
)
(
HMODULE
,
DWORD
,
PVOID
)
;
typedef
struct
_MANUAL_INJECT
{
PVOID ImageBase
;
PIMAGE_NT_HEADERS NtHeaders
;
PIMAGE_BASE_RELOCATION BaseRelocation
;
PIMAGE_IMPORT_DESCRIPTOR ImportDirectory
;
pLoadLibraryA fnLoadLibraryA
;
pGetProcAddress fnGetProcAddress
;
}
MANUAL_INJECT
,
*
PMANUAL_INJECT
;
static
DWORD __stdcall
CustomEntryPoint
(
PVOID p
)
{
PMANUAL_INJECT ManualInject
;
HMODULE hModule
=
NULL
;
DWORD i
,
Function
,
count
,
delta
;
PDWORD ptr
;
PWORD list
;
PIMAGE_BASE_RELOCATION pIBR
;
PIMAGE_IMPORT_DESCRIPTOR pIID
;
PIMAGE_IMPORT_BY_NAME pIBN
;
PIMAGE_THUNK_DATA FirstThunk
,
OrigFirstThunk
;
PDLL_MAIN EntryPoint
;
ManualInject
=
(
PMANUAL_INJECT
)
p
;
pIBR
=
ManualInject
->
BaseRelocation
;
delta
=
(
DWORD
)
(
(
LPBYTE
)
ManualInject
->
ImageBase
-
ManualInject
->
NtHeaders
->
OptionalHeader
.
ImageBase
)
;
while
(
pIBR
->
VirtualAddress
)
{
if
(
pIBR
->
SizeOfBlock
>=
sizeof
(
IMAGE_BASE_RELOCATION
)
)
{
count
=
(
pIBR
->
SizeOfBlock
-
sizeof
(
IMAGE_BASE_RELOCATION
)
)
/
sizeof
(
WORD
)
;
list
=
(
PWORD
)
(
pIBR
+
1
)
;
for
(
i
=
0
;
i

ImageBase
+
(
pIBR
->
VirtualAddress
+
(
list
[
i
]
&
0xFFF
)
)
)
;
*
ptr
+=
delta
;
}
}
}
pIBR
=
(
PIMAGE_BASE_RELOCATION
)
(
(
LPBYTE
)
pIBR
+
pIBR
->
SizeOfBlock
)
;
}
pIID
=
ManualInject
->
ImportDirectory
;
while
(
pIID
->
Characteristics
)
{
OrigFirstThunk
=
(
PIMAGE_THUNK_DATA
)
(
(
LPBYTE
)
ManualInject
->
ImageBase
+
pIID
->
OriginalFirstThunk
)
;
FirstThunk
=
(
PIMAGE_THUNK_DATA
)
(
(
LPBYTE
)
ManualInject
->
ImageBase
+
pIID
->
FirstThunk
)
;
hModule
=
ManualInject
->
fnLoadLibraryA
(
(
LPCSTR
)
ManualInject
->
ImageBase
+
pIID
->
Name
)
;
if
(
!
hModule
)
{
return
FALSE
;
}
while
(
OrigFirstThunk
->
u1
.
AddressOfData
)
{
if
(
OrigFirstThunk
->
u1
.
Ordinal
&
IMAGE_ORDINAL_FLAG
)
{
Function
=
(
DWORD
)
ManualInject
->
fnGetProcAddress
(
hModule
,
(
LPCSTR
)
(
OrigFirstThunk
->
u1
.
Ordinal
&
0xFFFF
)
)
;
if
(
!
Function
)
{
return
FALSE
;
}
FirstThunk
->
u1
.
Function
=
Function
;
}
else
{
pIBN
=
(
PIMAGE_IMPORT_BY_NAME
)
(
(
LPBYTE
)
ManualInject
->
ImageBase
+
OrigFirstThunk
->
u1
.
AddressOfData
)
;
Function
=
(
DWORD
)
ManualInject
->
fnGetProcAddress
(
hModule
,
(
LPCSTR
)
pIBN
->
Name
)
;
if
(
!
Function
)
{
return
FALSE
;
}
FirstThunk
->
u1
.
Function
=
Function
;
}
OrigFirstThunk
++
;
FirstThunk
++
;
}
pIID
++
;
}
if
(
ManualInject
->
NtHeaders
->
OptionalHeader
.
AddressOfEntryPoint
)
{
EntryPoint
=
(
PDLL_MAIN
)
(
(
LPBYTE
)
ManualInject
->
ImageBase
+
ManualInject
->
NtHeaders
->
OptionalHeader
.
AddressOfEntryPoint
)
;
return
EntryPoint
(
(
HMODULE
)
ManualInject
->
ImageBase
,
DLL_PROCESS_ATTACH
,
NULL
)
;
}
return
TRUE
;
}
static
DWORD __stdcall
EntryPointEnd
(
)
{
return
0
;
}
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
)
;
}
}
int
main
(
)
{
SetConsoleTitleA
(
RandomString
(
rand
(
)
%
16
+
1
)
.
c_str
(
)
)
;
setlocale
(
LC_ALL
,
"russian"
)
;
system
(
"color 03"
)
;
DWORD ProcessId
=
-
1
;
char
dllname
[
256
]
;
memset
(
dllname
,
0
,
256
)
;
_getcwd
(
dllname
,
256
)
;
strcat
(
dllname
,
"\\Hijacker.dll"
)
;
// указываем путь DLL хайжакера
char
procName
[
]
=
{
"Multi Theft Auto.exe"
}
;
printf
(
"\nSearch of target process...\n"
)
;
auto
EnableDebugPrivilege
=
[
]
(
bool
fEnable
)
->
bool
{
HANDLE hToken
;
if
(
OpenProcessToken
(
GetCurrentProcess
(
)
,
TOKEN_ADJUST_PRIVILEGES
,
&
hToken
)
)
{
TOKEN_PRIVILEGES tp
;
tp
.
PrivilegeCount
=
1
;
LookupPrivilegeValue
(
NULL
,
SE_DEBUG_NAME
,
&
tp
.
Privileges
[
0
]
.
Luid
)
;
tp
.
Privileges
[
0
]
.
Attributes
=
fEnable
?
SE_PRIVILEGE_ENABLED
:
0
;
AdjustTokenPrivileges
(
hToken
,
false
,
&
tp
,
sizeof
(
tp
)
,
NULL
,
NULL
)
;
CloseHandle
(
hToken
)
;
}
return
true
;
}
;
EnableDebugPrivilege
(
true
)
;
while
(
GetProcId
(
procName
)
==
-
1
)
{
Sleep
(
1
)
;
}
ProcessId
=
GetProcId
(
procName
)
;
printf
(
"Finded ProcID: %d\n"
,
ProcessId
)
;
PIMAGE_DOS_HEADER pIDH
;
PIMAGE_NT_HEADERS pINH
;
PIMAGE_SECTION_HEADER pISH
;
HANDLE hProcess
;
HANDLE hFile
;
PVOID image
,
mem
;
DWORD i
,
FileSize
,
read
;
MANUAL_INJECT ManualInject
;
hProcess
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
ProcessId
)
;
if
(
!
hProcess
)
{
while
(
!
hProcess
)
{
ProcessId
=
GetProcId
(
procName
)
;
hProcess
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
ProcessId
)
;
}
}
else
printf
(
"Opened process handle: 0x%X\n"
,
hProcess
)
;
hFile
=
CreateFileA
(
dllname
,
GENERIC_READ
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
)
;
if
(
hFile
==
INVALID_HANDLE_VALUE
)
{
printf
(
"\nError: Unable to open the DLL (%d)\n"
,
GetLastError
(
)
)
;
system
(
"pause"
)
;
}
FileSize
=
GetFileSize
(
hFile
,
NULL
)
;
BYTE
*
buffer
=
(
BYTE
*
)
VirtualAlloc
(
NULL
,
FileSize
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_READWRITE
)
;
if
(
!
buffer
)
{
printf
(
"\nError: Unable to allocate memory for DLL data (%d)\n"
,
GetLastError
(
)
)
;
CloseHandle
(
hFile
)
;
system
(
"pause"
)
;
}
if
(
!
ReadFile
(
hFile
,
buffer
,
FileSize
,
&
read
,
NULL
)
)
{
printf
(
"\nError: Unable to read the DLL (%d)\n"
,
GetLastError
(
)
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hFile
)
;
system
(
"pause"
)
;
}
CloseHandle
(
hFile
)
;
pIDH
=
(
PIMAGE_DOS_HEADER
)
buffer
;
if
(
pIDH
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
{
printf
(
"\nError: Invalid executable image.\n"
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
system
(
"pause"
)
;
}
pINH
=
(
PIMAGE_NT_HEADERS
)
(
(
LPBYTE
)
buffer
+
pIDH
->
e_lfanew
)
;
if
(
pINH
->
Signature
!=
IMAGE_NT_SIGNATURE
)
{
printf
(
"\nError: Invalid PE header.\n"
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
system
(
"pause"
)
;
}
if
(
!
(
pINH
->
FileHeader
.
Characteristics
&
IMAGE_FILE_DLL
)
)
{
printf
(
"\nError: The image is not DLL.\n"
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
system
(
"pause"
)
;
}
printf
(
"\nAllocating memory for the headers.\n"
)
;
image
=
VirtualAllocEx
(
hProcess
,
0
,
pINH
->
OptionalHeader
.
SizeOfImage
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
)
;
if
(
!
image
)
{
printf
(
"\nError: Unable to allocate memory for the headers (%d)\n"
,
GetLastError
(
)
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
system
(
"pause"
)
;
}
printf
(
"\nMemory allocated at 0x%llx\n"
,
image
)
;
printf
(
"\nCopying headers into target process.\n"
)
;
BOOL rslt
=
WriteProcessMemory
(
hProcess
,
image
,
buffer
,
pINH
->
OptionalHeader
.
SizeOfHeaders
,
NULL
)
;
if
(
!
rslt
)
{
printf
(
"\nError: Unable to copy headers to target process (%d)\n"
,
GetLastError
(
)
)
;
VirtualFreeEx
(
hProcess
,
image
,
0
,
MEM_RELEASE
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
system
(
"pause"
)
;
}
else
printf
(
"Headers writed at: 0x%llx\n"
,
image
)
;
pISH
=
(
PIMAGE_SECTION_HEADER
)
(
pINH
+
1
)
;
printf
(
"\nCopying sections to target process.\n"
)
;
for
(
i
=
0
;
i

FileHeader
.
NumberOfSections
;
i
++
)
{
WriteProcessMemory
(
hProcess
,
(
PVOID
)
(
(
LPBYTE
)
image
+
pISH
[
i
]
.
VirtualAddress
)
,
(
PVOID
)
(
(
LPBYTE
)
buffer
+
pISH
[
i
]
.
PointerToRawData
)
,
pISH
[
i
]
.
SizeOfRawData
,
NULL
)
;
printf
(
"PE Section %d writed at: 0x%llx\n"
,
i
,
(
PVOID
)
(
(
LPBYTE
)
image
+
pISH
[
i
]
.
VirtualAddress
)
)
;
}
printf
(
"\nAllocating memory for loader stub.\n"
)
;
mem
=
VirtualAllocEx
(
hProcess
,
0
,
4096
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
)
;
if
(
!
mem
)
{
printf
(
"\nError: Unable to allocate memory for loader stub (%d)\n"
,
GetLastError
(
)
)
;
VirtualFreeEx
(
hProcess
,
image
,
0
,
MEM_RELEASE
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
system
(
"pause"
)
;
}
printf
(
"\nMemory for loader stub allocated at 0x%llx\n"
,
mem
)
;
memset
(
&
ManualInject
,
0
,
sizeof
(
MANUAL_INJECT
)
)
;
ManualInject
.
ImageBase
=
image
;
ManualInject
.
NtHeaders
=
(
PIMAGE_NT_HEADERS
)
(
(
LPBYTE
)
image
+
pIDH
->
e_lfanew
)
;
ManualInject
.
BaseRelocation
=
(
PIMAGE_BASE_RELOCATION
)
(
(
LPBYTE
)
image
+
pINH
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_BASERELOC
]
.
VirtualAddress
)
;
ManualInject
.
ImportDirectory
=
(
PIMAGE_IMPORT_DESCRIPTOR
)
(
(
LPBYTE
)
image
+
pINH
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_IMPORT
]
.
VirtualAddress
)
;
ManualInject
.
fnLoadLibraryA
=
LoadLibraryA
;
ManualInject
.
fnGetProcAddress
=
GetProcAddress
;
printf
(
"\nWriting loader structure to target process.\n"
)
;
BOOL zbm
=
WriteProcessMemory
(
hProcess
,
mem
,
&
ManualInject
,
sizeof
(
MANUAL_INJECT
)
,
NULL
)
;
if
(
zbm
)
printf
(
"Loader structure writed at: 0x%llx\n"
,
mem
)
;
else
{
printf
(
"Failed to write loader structure. Error: %d\n"
,
GetLastError
(
)
)
;
VirtualFreeEx
(
hProcess
,
image
,
0
,
MEM_RELEASE
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
system
(
"pause"
)
;
}
PVOID stub
=
VirtualAlloc
(
0
,
(
(
DWORD
)
EntryPointEnd
-
(
DWORD
)
CustomEntryPoint
)
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
)
;
memcpy
(
stub
,
&
CustomEntryPoint
,
(
(
DWORD
)
EntryPointEnd
-
(
DWORD
)
CustomEntryPoint
)
)
;
BOOL stb
=
WriteProcessMemory
(
hProcess
,
(
PVOID
)
(
(
PMANUAL_INJECT
)
mem
+
1
)
,
stub
,
(
(
DWORD
)
EntryPointEnd
-
(
DWORD
)
CustomEntryPoint
)
,
NULL
)
;
if
(
stb
)
printf
(
"Loader stub writed at: 0x%llx\n"
,
(
(
PMANUAL_INJECT
)
mem
+
1
)
)
;
else
{
printf
(
"Failed to write loader stub code. Error: %d\n"
,
GetLastError
(
)
)
;
VirtualFreeEx
(
hProcess
,
image
,
0
,
MEM_RELEASE
)
;
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
system
(
"pause"
)
;
}
printf
(
"\nErasing DOS-Headers into DLL...\n"
)
;
PVOID dos_header
=
VirtualAlloc
(
0
,
sizeof
(
IMAGE_DOS_HEADER
)
,
MEM_RESERVE
|
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
)
;
memcpy
(
dos_header
,
buffer
,
sizeof
(
IMAGE_DOS_HEADER
)
)
;
for
(
int
i
=
0
;
i

WriteInteger
(
"Hijacked"
,
0x0
)
;
HijackThreadContext
(
(
HANDLE
)
hProcess
,
ProcessId
,
(
COMPATIBLE_DWORD
)
mem
,
(
COMPATIBLE_DWORD
)
(
(
PMANUAL_INJECT
)
mem
+
1
)
)
;
printf
(
"\nDLL injected at 0x%llx\n"
,
image
)
;
if
(
pINH
->
OptionalHeader
.
AddressOfEntryPoint
)
{
printf
(
"\nDLL entry point: 0x%llx\n"
,
(
PVOID
)
(
(
LPBYTE
)
image
+
pINH
->
OptionalHeader
.
AddressOfEntryPoint
)
)
;
}
VirtualFree
(
buffer
,
0
,
MEM_RELEASE
)
;
CloseHandle
(
hProcess
)
;
while
(
reg
->
ReadInteger
(
"Hijacked"
)
!=
0x1
)
{
Sleep
(
1
)
;
}
DWORD procID
=
GetProcId
(
"proxy_sa.exe"
)
;
HANDLE mtaProc
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
procID
)
;
procID
=
GetProcId
(
"gta_sa.exe"
)
;
if
(
!
mtaProc
)
mtaProc
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
procID
)
;
if
(
mtaProc
)
{
printf
(
"SUCCESSFULL HIJACKING!\n"
)
;
CloseHandle
(
mtaProc
)
;
}
else
printf
(
"FAILED ON HIJACKING!\n"
)
;
reg
->
WriteInteger
(
"Hijacked"
,
0x0
)
;
system
(
"pause"
)
;
return
1
;
}





:)

WARNING:Не пытайтесь использовать код мануал мап инжектора для инжекта дллок в сам процесс игры иначе получите пермач!

Автор: ntharbinger (NtKernelMC)

MTA Fuckers Team передаёт привет главному разработчику античита ccw808

Датчман XaskeL здесь не причём, не бань людей просто так :)

SiTrak
07.07.2019, 16:11
Опкодер вернулся😅

ntharbinger
07.07.2019, 18:39
пожалуйста, поставь чёртову запятую, это что, так сложно?


ещё мне троллей в теме не хватало

Vintik
29.12.2019, 16:45
ещё мне троллей в теме не хватало


ахахха)