HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 02.12.2020, 00:47
kin4stat
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами: 4483143

Репутация: 183


По умолчанию

Всем салам, сегодня будем обходить любые клиентчеки со стороны сервера

Алгоритм обхода у нас такой:

Сохранить к себе чистые модули gta_sa.exe и samp, и при попытке чтения таковых, подменять их.

Все хуки буду ставить через MinHook.

Оффсет обработчика RPC ClientCheck на R3 - 11710; R4 - 0x11A40

В начало кода добавляем это:

C++:





Код:
#include 
#include 
#include 
#include "MinHook.h"
#pragma comment(lib, "libMinHook-x86-v141-mt.lib")
#pragma intrinsic(_ReturnAddress)
#define FAKEVER "0.3.7-R4"


Создадим enum для версий сампа:

C++:





Код:
enum
SampVersion
{
SAMP_UNKNOWN
=
-
1
,
SAMP_0_3_7_R1
=
0
,
SAMP_0_3_7_R3_1
,
SAMP_0_3_7_R4
,
}
;


Объявим переменные констант(как бы это глупо не звучало )

C++:





Код:
DWORD READMEMFUNC
;
DWORD SAMPHMODULE
;
DWORD HOOKREADMEM
;
DWORD HOOKEXITREADMEM
;


Где нибудь ниже объявим все необходимые переменные:

C++:





Код:
HMODULE hSAMPModule
;
HMODULE hGTAModule
;
DWORD dwSampModule
;
DWORD dwGTAModule
;
unsigned
char
*
ClearSAMPModule
=
nullptr
;
// байты чистого сампа
unsigned
char
*
ClearGTAModule
=
nullptr
;
// байты чистой гташки


Объявляем прототипы и трамплины для хуков:

C++:





Код:
typedef
bool
(
__fastcall
*
RakPeer_RPC
)
(
void
*
,
void
*
,
int
*
,
BitStream
*
,
int
,
int
,
int
,
int
,
__int16
,
int
,
int
,
int
,
int
,
int
)
;
typedef
unsigned
char
(
__cdecl
*
ReadMemory
)
(
int
,
unsigned
__int16
)
;
typedef
void
(
__cdecl
*
ClientCheck
)
(
RPCParameters
*
)
;
RakPeer_RPC fpRPC
=
NULL
;
ReadMemory fpHkRead
=
NULL
;
ClientCheck fpHkClientCheck
=
NULL
;


Начнем с обхода захода с R2/R3/R4.

(Перейти к SAMP R1 можете тыкнув )

Возможные варианты подмены чтения gta_sa.exe - хук на месте вызова, либо хук ReadMemory и проверка адреса возврата.

Тут я покажу оба.

В случае с хуком вызова будем хукать это место:

Код:





Код:
.text:10011A3E 140 50                                push    eax
.text:10011A3F 144 E8 FC CC FF FF                    call    readMemory


Из-за того что в MinHook нет Call хуков, я буду использовать naked hook. Сам код:

Вариант с naked хуком::





Код:
// Объявляем функцию с параметром naked и укажем что она ничего не принимает и не возращает
__declspec
(
naked
)
void
HK_ReadMemory
(
void
)
{
static
unsigned
int
address
=
0
;
// Адрес откуда собирается читать самп
__asm
{
pushad
// Кидаем все регистры на стек, чтобы не затереть случайно лишнего
mov address
,
eax
// Вытаскиваем адрес с eax регистра
}
address
+=
reinterpret_cast

(
ClearGTAModule
)
-
dwGTAModule
;
// Меняем адрес на наш.
static
DWORD dwTmp
=
dwSampModule
+
READMEMFUNC
;
static
DWORD retjmp
=
dwSampModule
+
HOOKEXITREADMEM
;
__asm
{
popad
// тащим все регистры со стека обратно
mov eax
,
address
// перезаписываем регистр eax
push eax
// пушим его перед вызовом ReadMemory
call dwTmp
// Вызываем функцию ReadMemory
jmp retjmp
// Прыжок дальше
}
}


А чтобы подменять чтение сампа, будем подменять HMODULE у сампа. Он используется только при краше и чтении памяти, так что можем безболезненно менять его.

А в случае с хуком ReadMemory это будет выглядеть так:

C++:





Код:
unsigned
char
__cdecl
HOOK_ReadMemory
(
unsigned
int
address
,
unsigned
short
readSize
)
{
auto
ret
=
reinterpret_cast

(
_ReturnAddress
(
)
)
;
// Получаем адрес куда вернется функция после своего возврата
if
(
ret
>=
0x400000
&&
ret

(
ClearGTAModule
)
-
dwGTAModule
;
}
else
{
// Чтение идет в модуле samp.dll
address
+=
reinterpret_cast

(
ClearSAMPModule
)
-
dwSAMPModule
;
}
return
fpHkReadMem
(
address
,
readSize
)
;
}


Перейдем к обходу для R1.

Здесь у нас принцип такой: подменять версию сампа при отправке RPC и на клиентчеки отсылать наш ответ.

Сначала добавьте samp.dll от любой версии которая вам нравится в ресурсы с типом DLL

также не забудьте заменить FAKEVER на версию, dll от которой вы берете

Объявим функцию хука отправки RPC для подмены версии сампа

C++:





Код:
bool
__fastcall
HOOK_RakPeer_RPC
(
void
*
dis
,
void
*
EDX
,
int
*
uniqueID
,
BitStream
*
parameters
,
int
a4
,
int
a5
,
int
a6
,
int
a7
,
__int16 a8
,
int
a9
,
int
a10
,
int
a11
,
int
a12
,
int
a13
)
{
if
(
*
uniqueID
==
25
)
{
INT32 iVersion
;
UINT8 byteMod
;
UINT8 byteNicknameLen
;
UINT32 uiClientChallengeResponse
;
UINT8 byteAuthKeyLen
;
parameters
->
Read
(
iVersion
)
;
parameters
->
Read
(
byteMod
)
;
parameters
->
Read
(
byteNicknameLen
)
;
char
*
nickname
=
new
char
[
byteNicknameLen
+
1
]
;
nickname
[
byteNicknameLen
]
=
0
;
parameters
->
Read
(
nickname
,
byteNicknameLen
)
;
parameters
->
Read
(
uiClientChallengeResponse
)
;
parameters
->
Read
(
byteAuthKeyLen
)
;
char
*
authKey
=
new
char
[
byteAuthKeyLen
+
1
]
;
authKey
[
byteAuthKeyLen
]
=
0
;
parameters
->
Read
(
authKey
,
byteAuthKeyLen
)
;
parameters
->
SetWriteOffset
(
parameters
->
GetReadOffset
(
)
)
;
parameters
->
Write
(
static_cast

(
strlen
(
FAKEVER
)
)
)
;
parameters
->
Write
(
FAKEVER
,
strlen
(
FAKEVER
)
)
;
delete
[
]
authKey
,
nickname
;
}
return
fpRPC
(
dis
,
EDX
,
uniqueID
,
parameters
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
,
a10
,
a11
,
a12
,
a13
)
;
}


Объявим функцию получения чексуммы с куска памяти(Скопировал псевдокод с ida pro):

C++:





Код:
unsigned
char
readMemory
(
int
address
,
unsigned
__int16 readSize
)
{
unsigned
char
result
=
0
;
int
i
=
0
;
if
(
readSize
)
{
do
result
^=
*
(
BYTE
*
)
(
i
++
+
address
)
&
0xCC
;
while
(
i
!=
readSize
)
;
}
return
result
;
}


Функция хука:

C++:





Код:
void
HandleRPCPacketFunc
(
RPCParameters
*
rpcParams
)
{
BitStream
bs
(
rpcParams
->
input
,
rpcParams
->
numberOfBitsOfData
/
8
,
false
)
;
#pragma pack(push, 1)
struct
CCheck
{
// Для удобной работы с входящими параметрами
unsigned
__int8 requestType
;
unsigned
__int32 arg
;
unsigned
__int16 offset
,
readSize
;
}
;
#pragma pack(pop)
CCheck
*
data
=
reinterpret_cast

(
rpcParams
->
input
)
;
// Определяем структуру
// Мы отправляем ответ только на те типы, которые R1 не обрабатывает. Остальное отдаем ему.
if
(
data
->
requestType
!=
0x45
&&
data
->
requestType
!=
5
)
fpHkClientCheck
(
rpcParams
)
;
if
(
data
->
readSize
>
256u
||
data
->
readSize

offset
>
256u
)
return
;
// Делаем те же проверки что и самп
unsigned
__int8 result
=
0
;
// что будем отправлять серверу
switch
(
data
->
requestType
)
{
case
0x5
:
if
(
data
->
arg
>=
0x400000
&&
data
->
arg

arg
+
data
->
offset
-
dwGTAModule
+
reinterpret_cast

(
ClearGTAModule
)
,
data
->
readSize
)
;
}
break
;
case
0x45
:
{
if
(
data
->
arg

arg
+
data
->
offset
+
reinterpret_cast

(
ClearSAMPModule
)
,
data
->
readSize
)
;
}
}
break
;
}
// Создадим битстрим для отправки
BitStream sendBS
;
// Записываем нужные данные.
sendBS
.
Write
(
data
->
requestType
)
;
sendBS
.
Write
(
data
->
arg
)
;
sendBS
.
Write
(
result
)
;
int
sendID
=
RPC_ClientCheck
;
#pragma pack(push, 1)
struct
CNetGameR1
{
// Опять же мне так удобнее.
char
junk
[
0x3C9
]
;
RakClientInterface
*
m_pRakClient
;
}
;
#pragma pack(pop)
RakClientInterface
*
pRak
=
(
*
reinterpret_cast

(
dwSampModule
+
0x21A0F8
)
)
->
m_pRakClient
;
// Отправляем результат чтения.
pRak
->
RPC
(
&
sendID
,
&
sendBS
,
PacketPriority
::
HIGH_PRIORITY
,
PacketReliability
::
RELIABLE_ORDERED
,
0u
,
false
)
;
return
;
}


Ну и перейдем к точке входа:

Инициализируем MinHook и получаем все нужные адреса:

C++:





Код:
DWORD oldProt
;
MH_Initialize
(
)
;
MODULEINFO SAMPmoduleInfo
;
hSAMPModule
=
GetModuleHandle
(
L
"samp.dll"
)
;
hGTAModule
=
GetModuleHandle
(
L
"gta_sa.exe"
)
;
dwSampModule
=
reinterpret_cast

(
hSAMPModule
)
;
dwGTAModule
=
reinterpret_cast

(
hGTAModule
)
;
if
(
hSAMPModule
==
NULL
||
hGTAModule
==
NULL
)
return
FALSE
;
// Вдруг самп не загружен


Определяем версию сампа:

C++:





Код:
GetModuleInformation
(
GetCurrentProcess
(
)
,
hSAMPModule
,
&
SAMPmoduleInfo
,
sizeof
(
SAMPmoduleInfo
)
)
;
// Получаем инфу о модуле
switch
(
reinterpret_cast

(
SAMPmoduleInfo
.
EntryPoint
)
-
dwSampModule
)
{
case
0x31DF13
:
sampVer
=
SampVersion
::
SAMP_0_3_7_R1
;
break
;
case
0xCC4D0
:
sampVer
=
SampVersion
::
SAMP_0_3_7_R3_1
;
break
;
case
0xCBCB0
:
sampVer
=
SampVersion
::
SAMP_0_3_7_R4
;
break
;
default
:
return
FALSE
;
// Если версия неизвестная.
}


C++:





Код:
if
(
sampVer
==
SampVersion
::
SAMP_0_3_7_R1
)
{
ClearSAMPModule
=
reinterpret_cast

(
LockResource
(
LoadResource
(
hModule
,
FindResourceW
(
hModule
,
MAKEINTRESOURCEW
(
IDR_DLL_FILE1
)
,
L
"DLL_FILE"
)
)
)
)
;
// Получаем DLL сампа из ресурсов
MH_CreateAndEnableHook
(
dwSampModule
+
0xEAF0
,
&
HandleRPCPacketFunc
,
reinterpret_cast

(
&
fpHkClientCheck
)
)
;
// Ставим хук на обработчик RPC ClientCheck
MH_CreateAndEnableHook
(
dwSampModule
+
0x36C30
,
&
HOOK_RakPeer_RPC
,
reinterpret_cast

(
&
fpRPC
)
)
;
// Ставим хук на отправку рпц
}
else
{
switch
(
sampVer
)
{
case
SampVersion
::
SAMP_0_3_7_R3_1
:
{
HOOKREADMEM
=
0x11A3F
;
HOOKEXITREADMEM
=
0x11A44
;
READMEMFUNC
=
0xE740
;
SAMPHMODULE
=
0x26E880
;
}
break
;
case
SampVersion
::
SAMP_0_3_7_R4
:
{
HOOKREADMEM
=
0x11D6F
;
HOOKEXITREADMEM
=
0x11D74
;
READMEMFUNC
=
0xEA50
;
SAMPHMODULE
=
0x26E9B0
;
}
break
;
}
ClearSAMPModule
=
new
unsigned
char
[
SAMPmoduleInfo
.
SizeOfImage
]
;
// Выделяем массив
// Копируем модуль samp.dll
memcpy
(
ClearSAMPModule
,
reinterpret_cast

(
dwSampModule
)
,
0xC3500
+
256
)
;
// пределы чеков сампа - C3500
VirtualProtect
(
reinterpret_cast

(
dwSampModule
+
HOOKREADMEM
-
1
)
,
6
,
PAGE_EXECUTE_READWRITE
,
&
oldProt
)
;
*
reinterpret_cast

(
dwSampModule
+
HOOKREADMEM
-
1
)
=
0x90
;
// Нопим байт чтобы листинг не сбивался
//MH_CreateAndEnableHook(dwSampModule + HOOKREADMEM, &HK_ReadMemory, NULL); // Если у вас naked хук - расскоммментировать!
// Строку ниже закомментировать, если у вас naked хук
MH_CreateAndEnableHook
(
dwSampModule
+
0xEA50
,
&
sub_1000EA50
,
reinterpret_cast

(
&
fpHkRead
)
)
;
VirtualProtect
(
reinterpret_cast

(
dwSampModule
+
HOOKREADMEM
-
1
)
,
6
,
oldProt
,
&
oldProt
)
;
// Раскомментировать если у вас naked хук
/*
    VirtualProtect(reinterpret_cast(dwSampModule + SAMPHMODULE), 4, PAGE_EXECUTE_READWRITE, &oldProt);
    *reinterpret_cast(dwSampModule + SAMPHMODULE) = reinterpret_cast(ClearSAMPModule);
    VirtualProtect(reinterpret_cast(dwSampModule + SAMPHMODULE), 4, oldProt, &oldProt);
    */
}


Ну и конце копируем модуль гташки:

C++:





Код:
MODULEINFO GTAmoduleInfo
;
GetModuleInformation
(
GetCurrentProcess
(
)
,
hGTAModule
,
&
GTAmoduleInfo
,
sizeof
(
GTAmoduleInfo
)
)
;
// копируем только то, что может прочитать сервер.
ClearGTAModule
=
new
unsigned
char
[
0x856000
+
256
-
0x400000
]
;
memcpy
(
ClearGTAModule
,
reinterpret_cast

(
dwGTAModule
)
,
0x856000
+
256
-
0x400000
)
;


На этом наш обход завершен.

Плюсы этого обхода в том, что он скроет любое говно что вы поставите на свою гта: будь то клео, сампфункс, сайлент аим и любые другие читы.

Также если сервер попытается прочитать наш хук, то ничего он не узнает, ведь мы перекидываем его чтение на чистый модуль

Пасиба @HellsCoder за идею обхода, @DarkP1xel за моральную поддержку, а также Lot. за пинки
 
Ответить с цитированием

  #2  
Старый 02.12.2020, 01:42
Issaychik
Участник форума
Регистрация: 08.07.2017
Сообщений: 195
С нами: 4657176

Репутация: 83
По умолчанию

Обход аддона шоле получился?)

Вернусь на абсолют что-ль 😄
 
Ответить с цитированием

  #3  
Старый 02.12.2020, 02:40
kin4stat
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами: 4483143

Репутация: 183


По умолчанию

Цитата:
Сообщение от Issaychik  

Обход аддона шоле получился?)
Вернусь на абсолют что-ль 😄
Нет. Это для таких серверов, как Surv-Zone, где клиентского античита нет
 
Ответить с цитированием

  #4  
Старый 02.12.2020, 10:59
SR_team
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами: 6603505

Репутация: 183


По умолчанию

В собе вроде есть обход без сохранения чистых gta_sa и samp. И R1 не позволяет чекать память, только модельки
 
Ответить с цитированием

  #5  
Старый 02.12.2020, 11:07
CleanLegend
Постоянный
Регистрация: 28.03.2013
Сообщений: 495
С нами: 6908018

Репутация: 213
По умолчанию

Цитата:
Сообщение от SR_team  

В собе вроде есть обход без сохранения чистых gta_sa и samp. И R1 не позволяет чекать память, только модельки
в собе только защита от проверки флагов, а тут именно проверка по адресам памяти gta_sa и samp.dll

r1 не позволяет, но когда подрубаешь фейк версию r2-r4,то придется в таком случае эмулировать проверку памяти, так как сервер думает, что ты зашел r2-r4 и начинает проверять память. если нет ответа - не пускает

Цитата:
Сообщение от KiN4StAt  

обходить любые клиентчеки со стороны сервера
правильно наверно будет только клинтчеки: 0x5 и 0x45
 
Ответить с цитированием

  #6  
Старый 02.12.2020, 13:55
Gorskin
Познавший АНТИЧАТ
Регистрация: 15.10.2017
Сообщений: 1,407
С нами: 4514423

Репутация: 183


По умолчанию

Соберите это в асишник, мне лень с визуалкой возиться
 
Ответить с цитированием

  #7  
Старый 02.12.2020, 19:06
kin4stat
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами: 4483143

Репутация: 183


По умолчанию

Цитата:
Сообщение от KoZEROg  

Соберите это в асишник, мне лень с визуалкой возиться
Неактуально - ASI - AC Bypass for SurvZone | R3 | R4

Описание: Обходит проверки от античита на SAMPFUNCS/CLEO/MoonLoader и прочие. Активация - автоматическая. Старую тему удалил чтобы не задавали лишних вопросов когда где што куда

www.blast.hk
 
Ответить с цитированием

  #8  
Старый 02.12.2020, 20:53
ph03nix
Новичок
Регистрация: 07.01.2016
Сообщений: 4
С нами: 5447126

Репутация: 0
По умолчанию

0.3.DL-R1?
 
Ответить с цитированием

  #9  
Старый 11.10.2021, 20:39
Tester1337
Новичок
Регистрация: 10.03.2021
Сообщений: 11
С нами: 2725981

Репутация: 3
По умолчанию

Тут точно должно быть EDX ?

C++:





Код:
fpRPC
(
dis
,
EDX
,
uniqueID
,
parameters
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
,
a10
,
a11
,
a12
,
a13
)
;
 
Ответить с цитированием

  #10  
Старый 11.10.2021, 20:40
kin4stat
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами: 4483143

Репутация: 183


По умолчанию

Цитата:
Сообщение от Tester1337  

Тут точно должно быть EDX ?

C++:





Код:
fpRPC
(
dis
,
EDX
,
uniqueID
,
parameters
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
,
a10
,
a11
,
a12
,
a13
)
;

А почему не должно быть
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.