Обнаружение указателей доступа довольно громоздко, а значения статической памяти сложно адаптировать к различным компиляторам или версиям игры.
С помощью перехвата API malloc (), free () и т. Д. Метод отличается от следующих указателей. Обнаружение начинается с записи всех динамических распределений памяти и параллельного поиска в памяти. Найденный адрес памяти кучи затем обратно сопоставляется с записанным распределением памяти. Вы узнаете размер объекта и смещение вашего значения в объекте. Вы повторяете это с помощью backtracing и получаете адрес возврата кода вызова malloc () или конструктора C ++. С помощью этой информации вы можете отслеживать и изменять все объекты, которые оттуда выделяются. Вы сбрасываете объекты, сравниваете их и находите гораздо более интересные значения. Например. Универсальный элитный игровой тренажер "Ugtrain" делает это так в Linux. Он использует LD_PRELOAD.
Адаптация выполняется путем разборки на основе "objdump -D" и просто поиска вызова библиотечной функции с известным объемом памяти в ней.
См .: http://en.wikipedia.org/wiki/Trainer_%28games%29
Источник: Ugtrain: https://github.com/sriemer/ugtrain
Хук malloc () выглядит так:
static __thread bool no_hook = false;
void *malloc (size_t size)
{
void *mem_addr;
static void *(*orig_malloc)(size_t size) = NULL;
/* handle malloc() recursion correctly */
if (no_hook)
return orig_malloc(size);
/* get the libc malloc function */
no_hook = true;
if (!orig_malloc)
*(void **) (&orig_malloc) = dlsym(RTLD_NEXT, "malloc");
mem_addr = orig_malloc(size);
/* real magic -> backtrace and send out spied information */
postprocess_malloc(size, mem_addr);
no_hook = false;
return mem_addr;
}
Но если найденный адрес памяти находится внутри исполняемого файла или библиотеки в памяти, то, скорее всего, причиной динамического изменения является ASLR. В Linux библиотеки являются PIC (позиционно-независимым кодом), а в последних дистрибутивах все исполняемые файлы являются PIE (позиционно-независимыми исполняемыми файлами).