• XSS.stack #1 – первый литературный журнал от юзеров форума

Pattern scaner C++ (AOB)

Alexey18

(L3) cache
Пользователь
Регистрация
11.06.2023
Сообщения
163
Реакции
30
Всем привет. Решил ради интереса написать трейнер под один градострой новый. И столкнулся с проблемой которую не могу что-то решить.
В общем есть параметр, на который нет статичного указателя, который меняется при рестарте игры. => нужен AOB сканер.
Я через CE посмотрел и проанализировал кто обращается к искомому адресу, и была инструкция ( mov [rcx+10],eax ). Вот пытаюсь её найти patern сканированием.
И у меня возникает проблема с написанием AOB сканера - слишком долгое сканирование(мои наработки), а беру сорсы чужие, меняю начальный-конечный адреса, размеры буфферов, адреса вообще коллапс какой-то.
Анализировал в отладке.

Также бывает возникают проблемы доступа к определенным адресам.

Может были у кого опыт, наработки? принцип работы и тд понимаю, но в адекватном виде сделать не могу. Хотел бы на интерес попробовать.

Чужой пример с форума.
Код:
DWORD SignatureScanner(BYTE* mod_buffer, DWORD mod_size, DWORD mod_base, BYTE* pattern, int pattern_size, DWORD offset_from_offset)
{
    int counter = 0; // Счетчик совпадений сигнатуры

    // Проходим по всему буферу модуля памяти
    for (int i = 0; i < mod_size; i++)
    {
        // Проверяем, совпадает ли текущий байт с первым байтом сигнатуры
        if (mod_buffer[i] == pattern[0] || pattern[0] == 0x00)
        {
            // Если совпадение найдено, начинаем проверять последующие байты сигнатуры
            for (int p = 0; p < pattern_size; p++)
            {
                // Проверяем, совпадает ли текущий байт в буфере с текущим байтом сигнатуры
                if (mod_buffer[i + p] == pattern[p] || pattern[p] == 0x00)
                {
                    counter++; // Увеличиваем счетчик совпадений

                    // Если все байты сигнатуры найдены:
                    if (counter == pattern_size)
                    {
                        DWORD start_address_sig = i + mod_base; // Вычисляем адрес сигнатуры | Базовый адрес + количество шагов в памяти
                        DWORD address_of_offset_hp = start_address_sig + offset_from_offset; // Вычисляем адрес с учетом смещения | Добавляя к началу адреса сигнатуры 4 байта, получаем конечный искомый адрес
                        return address_of_offset_hp; // Возвращаем адрес
                    }
                }
                else {
                    counter = 0; // Если текущие байты не совпадают, сбрасываем счетчик
                }
            }

        }
    }

    // Если сигнатура не найдена, возвращаем нулевое значение
    std::cout << "Signature not found!" << std::endl;
    return 0;
}
 
Проблема такая, что на 32 битных файлах работает,а на 64битках адекватно не сканирует. сборку поменял естественно.


Код:
MODULEENTRY32 GetProcModuleInfo(int procId, const char* mod_name) {
    // Create a snapshot of the modules in the process
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    MODULEENTRY32 mod;
    // Initialize the module information structure
    ZeroMemory(&mod, sizeof(mod));
    mod.dwSize = sizeof(MODULEENTRY32);

    // Enumerate the modules in the process
    if (Module32First(hSnap, &mod)) {
        do {
            if (strcmp(mod_name, mod.szModule) == 0)
                // Compare the module names
            {
                CloseHandle(hSnap); // Close the snapshot handle
                return mod; // Return the module information
            }
        } while (Module32Next(hSnap, &mod)); // Get information about the next module
    }
    // If the module is not found, close the handle and return an empty structure
    CloseHandle(hSnap);
    ZeroMemory(&mod, sizeof(mod));
    return mod;
}

bool DataCompare(byte* data, byte* sign, const char* mask)
{
    for (; *mask; mask++, sign++, data++)
    {
        if (*mask == 'x' && *data != *sign)
            return false;
    }
    return true;
}

uintptr_t FindSignature(HANDLE hProc, DWORD base, DWORD size, byte* sign, const char* mask)
{
    MEMORY_BASIC_INFORMATION mbi = { 0 };
    DWORD offset = 0;

    while (offset < size)
    {
        VirtualQueryEx(hProc, (LPCVOID)(base + offset), &mbi, sizeof(MEMORY_BASIC_INFORMATION));
        if (mbi.State != MEM_FREE)
        {
            byte* buffer = new byte[mbi.RegionSize];
            ReadProcessMemory(hProc, mbi.BaseAddress, buffer, mbi.RegionSize, NULL);
            for (size_t i = 0; i < mbi.RegionSize; i++)
            {
                if (DataCompare(buffer + i, sign, mask))
                {
                    delete[] buffer;
                    return (uintptr_t)mbi.BaseAddress + i;
                }
            }
            delete[] buffer;
        }
        offset += mbi.RegionSize;
    }
    return 0;
}

main()
{
            auto inf = GetProcModuleInfo(processId, processName);
            cout << "Module base adress: " << hex << (uintptr_t)inf.modBaseAddr << endl;
            cout  << "Module size: " << hex << (DWORD)inf.modBaseSize << endl;
                       
           
            DWORD v = FindSignature(processHandle, (uintptr_t)inf.modBaseAddr, inf.modBaseSize, (PBYTE)"\x48\x83\xEC\x00\xE8\x00\x00\x00\x00\x48\x83", "xxx?x????xx");
            cout << hex << (uintptr_t)v << endl;
}
 
Последнее редактирование:
Думаю проблема в DWORD, поменяй на DWORD_PTR

DWORD base

Тут тоже пейсда:

uintptr_t FindSignature

DWORD v = FindSignature

Компилятор должен варны сообщать на такую движуху, видимо ты отключил или не смотришь их.
 
Писал давно, тоже для игрульки. Работает на обоих разрядностях. Надеюсь поможет.
C:
UINT h2b(LPSTR pHex) {
    UINT res = 0, delta = 0;
  
    char b = pHex[0];
    if(b >= '0' && b <= '9') {
        delta = 0x30;
    } else if (b >= 'A' && b <= 'F') {
        delta = 0x37;
    }
    res |= (b - delta) << 4;
  
    b = pHex[1];
    if(b >= '0' && b <= '9') {
        delta = 0x30;
    } else if (b >= 'A' && b <= 'F') {
        delta = 0x37;
    }
    res |= b - delta;
  
    return res;
}

bool SignCmp(BYTE *pMem, LPSTR pPattern) {
    BYTE b = h2b(pPattern);
    while(*pMem == b) {
        pPattern += 2;
        if(pPattern[0] == 0) {
            return TRUE;
        }
        pPattern++;
      
        while(pPattern[0] == '?') {
            pPattern += 3;
            pMem++;
        }
        pMem++;
        b = h2b(pPattern);
    }
  
    return false;
}
  
LPBYTE SignScan(BYTE *pMem, UINT cbMem, LPSTR pPattern) {
    UINT cb = (lstrlenA(pPattern) + 1) / 3;
    cbMem -= cb;
  
    BYTE b = h2b(pPattern);
    while(cbMem) {
        if(*pMem == b && SignCmp(pMem, pPattern)) {
            return pMem;
        }
        pMem++;
        cbMem--;
    }
    return NULL;
}
  
LPBYTE SignScanModule(HMODULE hMod, LPSTR pPattern) {
    BYTE *res = NULL;
  
    IMAGE_DOS_HEADER *pDOS = (IMAGE_DOS_HEADER*)hMod;
    IMAGE_NT_HEADERS *pNT = (IMAGE_NT_HEADERS*)((BYTE*)hMod + pDOS->e_lfanew);
    IMAGE_SECTION_HEADER *pSection = (IMAGE_SECTION_HEADER*)(pNT + 1);
  
    UINT i;
    for(i = 0; i < pNT->FileHeader.NumberOfSections; i++) {
        if((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) == 0) {
            pSection++;
            continue;
        }
        res = SignScan((BYTE*)hMod + pSection->VirtualAddress, pSection->SizeOfRawData, pPattern);
        if(res) {
            break;
        }
        pSection++;
    }
    return res;
}

Использовать вот так:
C:
ptr = SignScanModule(hBase, "4C 8D 05 ?? ?? ?? ?? 48 C1 E7 06");
 
Последнее редактирование:
Кто найдет ошибку в моем коде 100$ награда. Она там есть, не умышленно оставил, просто перечитывая его раз за разом заметил косяк.
UPD: Он в 99.9% случаев рабочий, но ошибка всеже есть.
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Кто найдет ошибку в моем коде 100$ награда. Она там есть, не умышленно оставил, просто перечитывая его раз за разом заметил косяк.
UPD: Он в 99.9% случаев рабочий, но ошибка всеже есть.
Скрытый контент для пользователей: waahoo.
 
Whoever finds a bug in my code will receive a $100 reward. It’s there, I didn’t intentionally leave it, I just re-read it over and over again and noticed a mistake.
UPD: It works in 99.9% of cases, but there is still an error.
Скрытый контент для пользователей: waahoo.
 
Кто найдет ошибку в моем коде 100$ награда. Она там есть, не умышленно оставил, просто перечитывая его раз за разом заметил косяк.
UPD: Он в 99.9% случаев рабочий, но ошибка всеже есть.

Скрытый контент для пользователей: waahoo.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх