Как в IDA-базе gta_sa.exe искать адреса памяти, относящиеся только к определённым моделям транспорта
Спецэффекты крови и внутренностей создаются только в том случае, если персонаж был переехан транспортным средством с моделью 532 (COMBINE). Это даёт основания предположить, что где-то в exe есть проверка - если ИД модели транспорта равен 532, то запускаются функции создания крови и внутренностей.
Попробуем осуществить поиск данных проверок по базе gta_sa.exe. Открываем базу, далее идём на вкладку Functions (список всех функций и методов exe). Щёлкаем по первой функции в списке - её код открывается в основном окне IDA View-A (первую функцию открываем для того, чтобы поиск запустился с начала кода exe). Далее запускаем поиск командой Search - Text. В базе числа обычно отображаются в шестнадцатиричном виде, поэтому искать будем не 532, а 214h (h - приставка, обозначающая то, что число шестнадцатиричное. Напомню, что в скриптинге для этой же цели используется приставка 0x. Перевести число из десятичного в шестнадцатиричное и обратно можно с помощью стандартного Windows-калькулятора).
В найденных совпадениях ищем конструкции подобного вида:
cmp word ptr [esi+22h], 214h
Здесь: cmp - операция сравнения;
esi - регистр, в котором обычно записан адрес структуры объекта, транспорта, или педа (также для этой цели часто используется ecx)
22h - смещение в структуре объекта, транспорта и педа, по которому записан ИД номер модели;
214h - ИД-номер модели комбайна (532).
Т.е. данная команда сравнивает, равен ли ИД номер модели транспорта 532 (внешний вид команды может отличаться, но смысл должен быть тот же). Переход к следующему совпадению осуществляется с помощью комбинации Ctrl+T. Поиск продолжаем до тех пор, пока не пройдём всю кодовую часть exe (это адреса типа "text" - в "спектре", расположенном под панелью инструментов они обозначены синим и голубым цветом. Вторая часть exe используется для хранения различных данных - чисел, строк и т.п. Это адреса типа "data", в "спектре" им соответствуют серый и серо-зелёный цвет).
Просматривая совпадения по заданной комбинации, находим среди прочих и такой кусок кода:
.text:006B36C5 0E8 cmp word ptr [esi+22h], 214h ; Compare Two Operands
.text:006B36CB 0E8 jnz short loc_6B36D4 ; Jump if Not Zero (ZF=0)
.text:006B36CD 0E8 mov ecx, esi
.text:006B36CF 0E8 call sub_6A9680 ; Call Procedure
Суть кода в том, что если транспортное средство является комбайном, то вызывается функция sub_6A9680. Просмотрим эту функцию - для этого щёлкаем по sub_6A9680, в результате код функции отображается в окне IDA View-A.
Просмотрим список функций, из которых вызывается функция sub_6A9680. Для этого используем команду View - Open Subviews - Function Calls. В результате открывается окно, состоящее из двух частей: Caller - функции, вызывающие данную функцию, Called Functions - функции, вызываемые из данной функции. В окне Caller присутствует только одна функция, что свидетельствует о том, что sub_6A9680 во всём exe используется только один раз. Появился шанс, что мы нашли то, что нужно.
Внимательно просматриваем код функции sub_6A9680, находим такой кусок:
.text:006A99E5 074 mov [esp+74h+point.x], 0BF99999Ah
.text:006A99ED 074 mov [esp+74h+point.y], 0C0733333h
.text:006A99F5 074 mov [esp+74h+point.z], 3FC00000h
Данные команды записывают какие-то координаты. О том, что это координаты свидетельствуют признаки: 1) восьмизначные шестнадцатиричные числа (0BF99999Ah, 0C0733333h, 3FC00000h) - это, как правило, дробные числа 2)названия - point.x, point.y, point.z. 3) количество чисел - 3 (координат всегда 3).
Проверяем свою находку - для этого с помощью скрипта заменим дробные значения на свои. Адрес получаем следующим образом: сначала переходим на вкладку отображения кода exe в шестнадцатиричном виде Hex View-A. Команда
.text:006A99E5 074 mov [esp+74h+point.x], 0BF99999Ah
в шестнадцатиричном виде выглядит так
C7 44 24 34 9A 99 99 BF
Здесь 9A 99 99 BF - это записываемое дробное значение 0BF99999Ah (в коде exe байты каждого числа записываются в обратном порядке). Щёлкаем по первому байту числа (9A) - внизу окна программы отображается его адрес - 0x6A99E9. Для замены значения координаты, мы должны произвести запись нового значения по данному адресу. Размер записи составит 4 байта (т.к. число дробное). Адреса типа text имеют защиту от чтения и записи, для снятия защиты в опкодах 0A8C/0A8D используется значение флага virtual_protect, равное 1.
{$CLEO}
0A8C: write_memory 0x6A99E9 size 4 value -5.0 virtual_protect 1 // X
0A8C: write_memory 0x6A99F1 size 4 value 10.0 virtual_protect 1 // Y
0A8C: write_memory 0x6A99F9 size 4 value 0.0 virtual_protect 1 // Z
0A93:
Теперь внутренности и кровь должны создаваться слева и спереди от комбайна. Проверяем скрипт в игре - адреса найдены верно. |