Иконка ресурса

[INC] Memory Extended 3.1

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #1
Первое что хотелось бы сказать, что философия данного inc состоит в том, чтобы все манипуляции воспроизводились без создания и нужды дополнительных файлов на сервере.
Данный INC находится в разработке и из-за этого - WINDOWS ONLY Он был выложен для показа возможностей библиотеке, а так же возможной обратной связи.
Так же статья будет дописываться :)

А благодаря этим людям, этот inc был дописан хотя бы до такого состояния:

@Kailo - за помощь в обучении ASM/Отладчиков/Работе с IDA
@komashchenko - За помощь, которая помогла мне разобраться с SDKCall

Данное "оружие" было создано для удобной работы с другими .dll, ведь в функциях SourcePawn можно работать только с 3-мя => server.dll/engine.dll/matchmaking_ds
Что же из этого вышло? - Давайте рассмотрим его структуру =>

C-подобный:
#define Pointer Address
#define nullptr Address_Null

#define PTR(%0) view_as<Pointer>(%0)



OS GetServerOS() // Вы можете использовать этот stock вне MemoryEx
int HexToDec(const char[] hex)
int IsHexSymbol(int ch)

enum struct MemoryEx
{
    Pointer pAddrBase;
    OS os;

    bool bSaveBytes;

    bool bInit;

    ModifByte lastModif;
    ArrayList hModifList;

    StringMap hModules;

// --------------functions--------------

    bool Init();
    OS GetOS();
    void GetWindowsVersion(int& iMajorVer, int& iMinorVer);

    void SetAddr(any address);
    Pointer GetAddr();
    void Add(any iOffset);

    void SaveBytes(bool save);
    bool NeedSave();
    void RestoreBytes();
    void ChangeSettings(bool bSave = true);

    Pointer InitModule(const char[] sName);
    Pointer GetBaseAddress(const char[] sName);
    int GetModuleSize(const char[] sName);
    Pointer GetEndModule(const char[] sName);

    Pointer GetModuleHandle(const char[] name);
    Pointer GetProcAddress(const char[] sLibrary, const char[] sName);

    Pointer FindPattern(Pointer base, any size, const int[] pattern, int iLength, int iOffset = 0);

    int ReadByte(int iOffset = 0);
    void WriteByte(any iByte, int iOffset = 0,  int flags = MemoryEx_NoNeedAdd);

    int ReadWord(int iOffset = 0);
    void WriteWord(any iWord, int iOffset = 0,  int flags = MemoryEx_NoNeedAdd);

    int ReadInt (int iOffset = 0);
    void WriteInt(any iNumber, int iOffset = 0, int flags = MemoryEx_NoNeedAdd);

    void WriteData(const int[] data, int iSize, int flags = MemoryEx_NoNeedAdd);

    int ReadString(char[] sString, int iMaxLength);
    void WriteString(const char[] sString, bool bNull = true, int flags = MemoryEx_NoNeedAdd);
    void WriteUnicodeString(const char[] sString, bool bNull = true, int flags = MemoryEx_NoNeedAdd);

    Pointer FindString(const char[] sModule, const char[] sString);
    Pointer FindUnicodeString(const char[] sModule, const char[] sString);
    Pointer FindValue(const char[] sModule, any iValue, int iNextByte = 0x2A );
}

Самая интересная функция как по мне -> Pointer GetModuleHandle(const char[] name) которая вызывает и возвращает результат WINAPI GetModuleHandleW через SourcePawn :)
Данный INC вызывает WINAPI функцию GetModuleHandleW для получения Base Address любой библиотеки. Что же она делает?
Как можно заметить - первым аргументом она принимает название библиотеки, но для использования GetModuleHandleW - нужна unicode строка? - По этому и была создана функция MemoryEx::WriteUnicodeString.
В свободной памяти мы генерируем данную строку, делаем небольшой отступ [0x10] и мы должны создать функцию, которая вызывает ее, псевдокод на ASM =>
C-подобный:
push [string address]
call dword ptr [GetModuleHandleW]
retn

Что же inc делает?
GetModuleHandleW в server.dll используется в двух случаях и во всех - использует kernel32. По этому мы ищем адрес данной строки, и можно использовать MemoryEx::FindString, но т.к это unicode - используем MemoryEx::FindUnicodeString. После того, как мы нашли адрес данной строки - ищем где используется данная строка через MemoryEx::FindValue, так же можно заметить, что последним аргументом в данной функции вспомогательный байт 0xFF, что же это?

C-подобный:
.text:1072C378 56                                      push    esi
.text:1072C379 68 EC D5 79 10                          push    offset aKernel32Dll_0 ; "kernel32.dll"
.text:1072C37E FF 15 F4 E0 78 10                       call    ds:GetModuleHandleW

Если проанализировать где используется данная строка, всегда после нее идет call ds:GetModuleHandleW т.е первый байт = 0xFF.
И так, узнали где используется kernel32.dll - теперь делаем смещение + 0x6 и тем самым загружаем адрес GetModuleHandleW. И так, как же это выглядит в библиотеке? =>
C-подобный:
Pointer pKernelStr = this.FindUnicodeString("server", "kernel32.dll");
Pointer module = this.FindValue("server", pKernelStr, 0xFF)  + PTR(0x06);

if(pKernelStr == nullptr || module == nullptr)
{
    this.ChangeSettings(false);
    LogStackTrace("GetModuleHandles failed -> Base = 0x%X pKernelStr 0x%X module 0x%X end = 0x%X", g_ServerDLL.base, pKernelStr, module, g_ServerDLL.base + PTR(g_ServerDLL.size) );
    return nullptr;
}

module = PTR(LoadFromAddress(module, NumberType_Int32));

Дальнейшие действия такие:
C-подобный:
        static int offsetForString = 0x10; // offset between string and function
        static int offsetForEnd = 0x100;

        int iLengthStr = strlen(name);

        //Теперь нужно перейти на адрес куда мы можем нужную строку + саму функцию.
        this.SetAddr((view_as<int>(g_ServerDLL.base) + g_ServerDLL.size) - offsetForEnd - offsetForString - (iLengthStr * 2)); // Address for string
        Pointer pString = this.GetAddr();

        // this.WriteUnicodeString(name) возвращает нам адрес, куда была записан последний байт строки и делаем маленькое смещения для написания уже самой функции.
        this.SetAddr( this.WriteUnicodeString(name) + PTR(offsetForString));


        Pointer pFunc = this.GetAddr();

        // Реализуем функцию из псевдокода, который был выше
        this.WriteByte(0x68,     _,     MemoryEx_AddAfterWrite); // push
        this.WriteInt(pString,    _,     MemoryEx_AddAfterWrite); // Адрес записаной unicode строки
        this.WriteWord(0x15FF,    _,     MemoryEx_AddAfterWrite); // call dword ptr
        this.WriteInt(module,    _,     MemoryEx_AddAfterWrite); // Адрес GetModuleHandleW
        this.WriteByte(0xC3,    _,    MemoryEx_AddAfterWrite); // retn

Чтобы было более понятно, в итоге это привело к этому:
2019-12-18_20-53-19.png

Далее просто вызываем ее через SDKCall и получаем Base Address любой интересующей нас dll
C-подобный:
StartPrepSDKCall(SDKCall_Static);
PrepSDKCall_SetAddress(pFunc);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);

Handle h = EndPrepSDKCall();
Pointer iRes = SDKCall(h);

Описании некоторых функций:

Данную функцию вы должны вызывать при инициализации MemoryEx, в ней определяется OS сервера, base address + size server.dll/.so.
Это позволяет использовать все функции из данной библиотеки.

Если вы попробуйте найтм какую-то строку, но не сделаете MemoryEx::Init() то ваш плагин будет вызывать подобную ошибку
C-подобный:
L 12/18/2019 - 19:33:28: [SM] Stack trace requested: MemoryEx wasn't be initialized
L 12/18/2019 - 19:33:28: [SM] Called from: nobots_bypass.smx
L 12/18/2019 - 19:33:28: [SM] Call stack trace:
L 12/18/2019 - 19:33:28: [SM]   [0] LogStackTrace
L 12/18/2019 - 19:33:28: [SM]   [1] Line 437, E:\server\bhopserver\csgo\addons\sourcemod\records\2\include\MemoryEx.inc::MemoryEx::GetModuleSize
L 12/18/2019 - 19:33:28: [SM]   [2] Line 735, E:\server\bhopserver\csgo\addons\sourcemod\records\2\include\MemoryEx.inc::MemoryEx::FindString
L 12/18/2019 - 19:33:28: [SM]   [3] Line 18, nobots_bypass.sp::OnPluginStart

MemoryEx::SaveBytes(bool) - Нужно ли сохранять байты, которые были изменены в ходе работы плагина.

MemoryEx::NeedSave - true - Включена необходимость сохранять байты

MemoryEx::RestoreBytes - восстанавливает все измененные байты.
Пример:
C-подобный:
#include <MemoryEx>

MemoryEx g_hMem;

public void OnPluginStart()
{
    RegServerCmd("sm_nobots", Cmd_NoBots);
}
public Action Cmd_NoBots(int iArgs)
{
    if(iArgs)
    {
        g_hMem.RestoreBytes();
    }
    else
    {
        if(g_hMem.Init())
        {
            g_hMem.SaveBytes(true);

            Pointer pEnd = g_hMem.GetBaseAddress("server") + PTR(g_hMem.GetModuleSize("server"));
            g_hMem.SetAddr(pEnd - PTR(0x200));

            g_hMem.WriteString("Memory", _, MemoryEx_AddAfterWrite);
            g_hMem.WriteUnicodeString("Extended", _, MemoryEx_AddAfterWrite);
            g_hMem.WriteByte(0x31, _, MemoryEx_AddAfterWrite);
            g_hMem.WriteWord(0x32, _, MemoryEx_AddAfterWrite);
            g_hMem.WriteInt(0x33, _, MemoryEx_AddAfterWrite);
        }
    }

}
bandicam-2019-12-19-16-55-03-239.gif

Pointer GetModuleHandle(const char[] library) - Возвращает Base Address указанного модуля [На основе WINAPI GetModuleHandleW]. "0" - Возвращает адрес srcds.

Pointer InitModule(const char[] library) - Инициализирует Base/End address указанного модуля

Pointer GetBaseAddress(const char[] library) - Возвращает Base Address уже из инициализированного модуля

int GetModuleSize(const char[] library) - Возвращает инициализированный размер библиотеки

Pointer GetEndModule(const char[] library) - Возвращает адресс последнего инициализированного байта библиотеки [MemoryEx::GetBaseAddress + MemoryEx::GetBaseAddres]

Пример всех этих функций:
C-подобный:
#include <MemoryEx>

public void OnPluginStart()
{
    MemoryEx mem;

    if(!mem.Init()) return;

    Pointer base = mem.GetModuleHandle("kernel32.dll");
    Pointer base1 = mem.InitModule("kernel32.dll");
    Pointer base2 = mem.GetBaseAddress("kernel32.dll");

    Pointer srcds = mem.GetModuleHandle("0");

    int size = mem.GetModuleSize("kernel32.dll");

    Pointer end1 = base1 + PTR(size);
    Pointer end2 = mem.GetEndModule("kernel32.dll");

    PrintToServer("base [0x%X] == base1 [0x%X] == base2 [0x%X] size [0x%X] end1 [0x%X] == end2 [0x%X] srcds [0x%X]", base, base1, base2, size, end1, end2, srcds);
}


Результат

base [0x75170000] == base1 [0x75170000] == base2 [0x75170000] size [0xE0000] end1 [0x75250000] == end2 [0x75250000] srcds [0xB10000]

Примеры:

1) Внедряем .dll через SourcePawn [GetProcAddress + вызов WINAPI LoadLibraryA]

C-подобный:
#include <MemoryEx>

public void OnPluginStart()
{
    MemoryEx mem;

    if(!mem.Init()) return;

    mem.InitModule("kernel32.dll");
    Pointer libAddr = mem.GetProcAddress("kernel32.dll", "LoadLibraryA");

    StartPrepSDKCall(SDKCall_Static);
    PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
    PrepSDKCall_SetAddress(libAddr);
    PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);

    Handle h = EndPrepSDKCall();
    int baseDLL = SDKCall(h, "D:/CSS_HOOK.dll");
    delete h;

    PrintToServer("libaddr = 0x%X Base Address DLL = 0x%X ",libAddr, baseDLL);
}

2019-12-22_14-08-00.png

2019-12-22_14-08-44.png

На ранней стадии создании данного inc он был раскритикован @Kruzya в теме с моим плагином => Bypass -nobots и я действительно был с ним согласен, по этому теперь давайте рассмотрим использование данного inc именно на данном плагине.

Первая претензия была в том, что геймдату нужно изредко обновлять. Теперь мы просто ищем данное слово и "уничтожаем его"
C-подобный:
#include <MemoryEx>

public void OnPluginStart()
{
    MemoryEx mem;
    if(mem.Init())
    {
        Pointer pStr = mem.FindString("server", "-nobots");

        if(pStr != nullptr)
        {
            mem.SetAddr(pStr + PTR(0x01)); // bypass `-`
            for(int y = 0; y < 6; y++)    mem.WriteByte(GetRandomInt(0x61, 0x7A), y);
        }
    }
}
Но если посмотрим на претензию до конца, то видно, что если снять сжатие, было видно строки, что упрощает поимку плагина, что же делать? - Попробуем другой способ - через MemoryEx::FindPattern
C-подобный:
#include <MemoryEx>

public void OnPluginStart()
{
    static int pattern[8] = {0x2D, 0x6E, 0x6F, 0x62, 0x6F, 0x74, 0x73, 0x00}; // `-nobots`;
    MemoryEx mem;

    if(mem.Init())
    {
        ModuleInfo server;
        server.base = mem.GetBaseAddress("server");
        server.size = mem.GetModuleSize("server");

        Pointer pStr = mem.FindPattern(server.base, server.size, pattern, sizeof(pattern), 0x01); // bypass `-`

        if(pStr != nullptr)
        {
            mem.SetAddr(pStr);
            for(int y = 0; y < 6; y++)    mem.WriteByte(GetRandomInt(0x61, 0x7A), y);
        }
    }
}
 
Последнее редактирование:

Мировой

Участник
Сообщения
342
Реакции
53
скажите попроще что это и нужно ли оно для сервера кс го виндос ?
 

White Wolf

🍉
Сообщения
2,382
Реакции
2,187
  • Команда форума
  • #3
скажите попроще что это и нужно ли оно для сервера кс го виндос ?
Это просто библиотека для разработчиков. Позволяет вмешиваться в работу сервера несколько более изощрёнными путями. Владельцам серверов это ни к чему.
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #4
Теперь вы можете посредством SourcePawn - внедрять .dll файлы :)

0) Было добавлено описание некоторых функций данной библиотеки [Например: MemoryEx::RestoreBytes/MemoryEx::GetModuleHandle]
1) Все функции записи [WriteByte,WriteData,WrtieUnicodeString, ...] имеют тип void
2) Исправлена логика записи нуль-терминированной строки в функциях WriteString/WrtieUnicodeString при втором параметре bNull = true
3) В функциях WriteString/WriteUnicodeString - добавился еще один параметр int flags, по умолчанию имеет значение MemoryEx_NoNeedAdd, которая устанавливает адресс на конец записанной строки
4) Исправлен баг, когда GetWindowsVersion не возвращала назад старый адрес
5) Добавлена функция MemoryEx::GetProcAddress(const char[] library, const char[] function) - аналог WINAPI GetProcAddress
5.1) В описании библиотеки - был добавлен пример использования MemoryEx::GetProcAddress

6) Исправлено описание структуры MemoryEx в шапке темы
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #6
Теперь MemoryEx находится не в одном файле - а в древовидном виден, каждый файл которого - вы можете использовать отдельно

  • MemoryEx.inc
    • DynamicLibrary.inc
      • ASM_Instruction.inc
      • ServerLibrary.inc
        • BaseMemory.inc
        • WindowsFunction.inc
        • LinuxFunction.inc
        • Stocks.inc
Была добавлена поддержка Linux, а так же - поддержка всех Source игр [Windows поддерживает Only CS:GO]

В MemoryEx/LinuxFunction.inc функция LinuxParseMapsFile() - возвращает StringMap, который содержит
1) Название библиотеки
2) Базовый адрес
3) Инициализированный размер

На SP - это выглядит так
C-подобный:
enum struct ModuleInfo
{
    Pointer base;
    int size;
}

Был вырезан функционал ModifBytes - который помогал восстанавливать все измененные за работу inc байты
Теперь для более удобной инициализации библиотек - можно опускать его расширение [Кроме DynamicLibrary::GetModuleHandle]

До
C-подобный:
mem.lib.InitModule(GetServerOS() == OS_Windows ? "engine.dll" : "engine.so");
После
C-подобный:
mem.lib.InitModule("engine");

Оптимизирована функция GetServerOS - теперь при первом ее вызове - определяется OS - в последующая - просто возвращается результат.

Теперь нет нужны в MemoryEx делать MemoryEx::Init для определения базового адреса библиотеки server.dll/server.so

Для Windows можно используется
C-подобный:
Pointer base = GetServerDLLBase();
int size = GetServerDLLSize()
Для Linux - все в LinuxParseMapsFile

Из-за того, что теперь inc может работать со всеми динамическими библиотеками - все ограничения - только в вашей голове :)
 
Последнее редактирование:

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #7
Перепакуй архив по нормальному в *.zip. Его реализация есть везде из коробки, в то время для рара нужно качать архиватор.
Снимок экрана 2020-01-19 в 15.26.25.png
 

Vit_ amin

Добрая душа
Сообщения
1,504
Реакции
660
Теперь осталось научиться работать с памятью ... Profit !?
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
3) В функциях WriteString/WriteUnicodeString - добавился еще один параметр int flags, по умолчанию имеет значение MemoryEx_NoNeedAdd, которая устанавливает адресс на конец записанной строки
Эмм, странное описание.
Если дословно, то NoNeedAdd - намекает, что не нужно добавлять к текущей позиции, но вы говорите, что устанавливает на конец записанной строки, т.е. получается что таки добавляет.
А как понять тогда остальные 2 флага?
enum
{
MemoryEx_NoNeedAdd = (1 << 0),

/*
When will read from memory is started, MemoryEx will automatically add to this.pAddrBase.

...
this.SetAddr(0x200) =>
int byte = this.ReadWord(0x20) [Read something]
Now this.GetAddr return 0x222 => 0x200 [Base] + 0x20 [offset] + 0x02 [size type]
...
*/
MemoryEx_AddAfterRead = (1 << 1),
MemoryEx_AddAfterWrite = (1 << 2),

}
Спасибо за пояснение.

P.S. Крутая работа. Респект!
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #10
Версия 2.5

1) В MemoryEx/WindowsFunction - добавилась функция получия PEB адресса для различных целей
2) Теперь ReadString/ReadUnicodeString/FindPattern/FindString/FindUnicodeString - доступны в виде обычных функций, которые объявлены в MemoryEx/Stocks.inc
3) Добавлена функция WindowsGetDLLList => Теперь MemoryEx не зависит от gamedata и работает на всех играх Source Движка, а так же на любой OS
4) В структуре MemoryEx - полностью реализована структура BaseMemory для более короткого кода [Было g_hMem.mem.ReadByte() => Стало g_hmem.ReadByte()]
5) Удален большой блок кода в MemoryEx/ServerLibrary - который относился к определению OS сервера. Теперь определение OS занимает всего 20 строчек :)
6) Добавлена новая stock функция FindFreeMemory - для нахождения в нужном промежутке - свободную память. Под свободной памятью подразумевается промежуток, на котором все байты = 0x00
7) В BaseMemory была добавлена функция BaseMemory::ReadUnicodeString
8) Благодаря тому, что теперь MemoryEx может без проблем получать список динамических библиотек- код в MemoryEx/DynamicLibrary:::InitModule/GetModuleHandle - уменьшился, ведь был удален костыль, который вызывал GetModuleHandle из kernel32.dll для этих целей.
9) Были вырезаны функции GetServerDLLBase/GetServerDLLSize за ненадобностью.
10) Теперь при MemoryEx::Init / DynamicLibrary::Init - инициализируется не только server.dll, а так же engine.dll
11) Добавлена функция GetListLibraries в структуру DynamicLibrary - которая возвращает список всех загруженных динамических библиотек.
 
Последнее редактирование:

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #11
Мне жаль тех людей, которые читают твои списки изменений на темном стиле.
Поменьше цветов используй, пожалуйста. Реально глаза вытекают на лоб.
И вообще, в чем смысл красить имена функций, когда есть [ICODE]-бб код?
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
@Rostu, можете, пожалуйста, ответить на мой вопрос?

Обновление не принесло ясности. В описании ресурса тоже этого нет.
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #13
Эмм, странное описание.
Если дословно, то NoNeedAdd - намекает, что не нужно добавлять к текущей позиции, но вы говорите, что устанавливает на конец записанной строки, т.е. получается что таки добавляет.
А как понять тогда остальные 2 флага?

Спасибо за пояснение.

P.S. Крутая работа. Респект!
Да, ваши догадки абсолютно верны - это моя ошибка. Конечно же, про NoNeedAdd - вернется адрес на начало строки т.к адрес не будет изменятся. Но при MemoryEx_AddAfterWrite - WriteString вернет уже на конец строки. Надо бы исправить....
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #14
Версия 2.7
2.6
1) Удалены функции MemoryEx::Init / DynamicLibrary::Init / DynamicLibrary::GetBaseAddress / DynamicLibrary::InitModule
2) Добавлены новые stock функции в ServerLibrary => GetListLibraries/GetModuleHandle/GetModuleSize/GetModuleEnd/GetModuleInfo
3) Все функции из 2-го пункта реализованы в DynamicLibrary под такими же названиями

2,7
1) Добавилась новая stock функция LoadFromAddressEx =>[return view_as<Address>(LoadFromAddress(addr, size))]
2) Исправлена неправильная работа stock функции ReadString
3) Добавлена функция чтения необходимой информации из ImportTable GetImportAddressWindows [Windows Only]
4) Добавлена stock функция для чтение Export символов [Windows + Linux]
4.1) Теперь функция DynamicLibrary::GetProcAddress - поддерживает и Linux
4.1.1) Добавлена stock функция GetProcAddressLinux в MemoryEx/LinuxFunction.inc
4.2) Добавлены stock функции GetFirstElfTable/GetElfTableSize/GetCountElfTable в MemoryEx/LinuxFunction.inc
5) Добавлена [Экспериментальная] stock функция DumpOnAddress - используйте ее, если необходимо узнать, что в определенном отрезке памяти происходит
 
Последнее редактирование:

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #15
Версия 3.0
Скоро будут обновлены и добавлены новые примеры, которые будут показывать - как правильно работать с данной библиотекой

1) Добавлена stock функция StrContainsEx - которая ищет необходимую строку в начале исходной
2) Добавлена stock функция FindModule - Которая ищет необходимую библиотеку по части названия
Возвращаемые результаты
FindModuleRes_None - Если не нашлось ни одного модуля [res = FindModule("gfhfhfg", sModule, sizeof sModule)]
FindModuleRes_OK - Если нашлась только одна нужная библиотека
FindModuleRes_More - Если под параметры поиска попали две и более библиотеки [Возвращается название последней найденной библиотеки]
3) Добавлена функция GetImportAddress - которая ищет в таблице импорта необходимую функцию [Win + linux]
4) Добавлена stock глобальная переменная MemoryEx g_hMem - чтобы было удобнее использовать функции
5) Добавлен новый inc - MemoryEx/MemoryAlloc.inc - где реализованы функции malloc/free
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #16
Rostu обновил(а) ресурс [INC] Memory Extended новой записью:

Приближение к smx dumper.../PatternEx/new stocks/any fix

Версия 3.1
1)Добавлена stock функция FindAllStrings, которая возвращает адреса необходимых строк в ArrayList
2)Добавлен новый inc MemoryEx/PatternGenerator.inc => Для удобной автоматической генерации сигнатур с меняющимися значениями.
Пример вы могли наблюдать уже =>...

Узнать больше об этом обновлении...
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
Могу я у вас попросить feature-request, если будет не трудно реализовать:
- выставление флага "executable" на выделенный регион памяти (тот что у вас в MemoryAlloc.inc). Это VirtualProtect (для Windows) и mprotect (для Linux).

Тем самым можно будет ставить нечто вроде detour на произвольные адреса внутри функции,
прыгать на executable область и дописывать код, например, те же проверки на NULL,
по оплошности забытые разработчиками.

Я точно не знаю, возможно, нечто похожее реально сделать и через DHookRaw() из dhooks.inc,
может кто-то из знающих подскажет.
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
Выяснил, что запросил у вас филькин труд.
Оказалось, что StoreToAddress() вместе с копированием включает в себя и установку executable флага.
 

Rostu

Добрая душа
Сообщения
986
Реакции
622
  • Автор ресурса
  • #19
Выяснил, что запросил у вас филькин труд.
Оказалось, что StoreToAddress() вместе с копированием включает в себя и установку executable флага.
Я как-то даже позабыл об этом изначально
Хотя я ведь этот лайфхак использовал для PEB'a)
Вот пример😅

 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
Фишка конечно прикольная с созданием энтити взамен malloc, уже хотел было взять на вооружение,
только вот она ставит временные ограничения на момент использования этой функции.
L 12/08/2020 - 23:59:43: [SM] Exception reported: Cannot create new entity when no map is running
Эх, если бы что-нибудь такое же простое придумать.
Слышал есть такие энтити, которые сохраняются даже при смене карты.

PS. В принципе, как еще более дикий план, можно задействовать World (0), и сразу же восстановить ему память =)
 
Последнее редактирование:
Сверху Снизу