Перейти к содержанию

Рекомендуемые сообщения

Опубликовано (изменено)

     Предлагаю в этой теме решать вопросы, связанные с адресами памяти. Только вчера добрался до программы IDA (позволяет открывать базу данных адресов gta_sa.exe), так что есть куча вопросов. И так первый вопрос как найти нужный мне адрес. Скачал IDB database by fastman92 для gta_sa 1.0 Hoodlum от 2015 года, открыл базу и все, далее мол иди учи ассемблер, а хотелось бы без этого. Тем более большинство адресов и функций уже найдено. И как узнать адрес функции, расположенной ниже? 

Пример

.text:007F0DC0     ; RwFrame *__cdecl RwFrameForAllChildren(RwFrame *frame, int callback, void *data)
.text:007F0DC0     frame           = dword ptr  0Ch
.text:007F0DC0     callback        = dword ptr  10h
.text:007F0DC0     data            = dword ptr  14h 

 

 

Изменено пользователем Constantines
Опубликовано

от 2015 года

На Discord-сервере по plugin-sdk и программированию в GTA есть более "свежая" база.

 

открыл базу и все, далее мол иди учи ассемблер, а хотелось бы без этого.

IDA генерирует псевдо код на С++ по нажатию клавиши F5, но там ещё надо разбираться, поскольку генерирует не идеально.

 

По работе с IDA есть такая тема

 

немного пояснений Если есть IDA и idb-база, то для "распутывания ниточек" можно использовать такие приёмы:

 

Как определить, откуда вызывается данная функция?

1.Открываем код функции в основной вкладке.

2.Далее выбираем в меню пункт View - Open Subviews - Function calls - список Caller.

 

Как определить, откуда происходит обращение к данному адресу?

1.Вставляем курсор между буквами названия адреса. Например здесь

Code:

 

.data:00B7CB84 _currentTime dd ? ; DATA XREF: _sub_406E50r

 

вставляем курсор между любыми буквами _currentTime.

2.Жмём X. Открывается список ссылок на данный адрес.

 

 

Очень часто случается такое, что декомпилятор (hex-rays) выдаёт ошибку "switch analysis failed".

Случается это в функциях, где используется конструкция switch.

Случается это потому что (моё предположение) разные версии декомпилятора по-разному работают с этой

конструкцией.

В официальных доках рекомендуют вручную настроить эту конструкцию, но есть более простое решение:

пересобрать функцию.

Для этого надо преобразовать функцию в обычные данные, преобразовать данные в код, и создать функцию.

 

1. Нажимаем U на названии функции (Undefine function).

2. Нажимаем C на первом байте (Code)

3. Нажимаем P (Create function).

 

В exe есть 2 основных типа адресов - data и text (есть и другие типы). Если проводить аналогию со

скриптами, то адреса типа data можно сравнить с глобальными переменными - в них хранятся различные

значения (например, 0xB7CB84 - [dword Глобальный таймер в ms, 0x8D2530 - [float Плотность движения

пешеходов). В ходе игры отдельные процедуры exe читают эти значения или записывают в эти адреса новые

значения. Эти адреса (не все) можно читать/перезаписывать и в скрипте с помощью опкодов 0A8C/0A8D.

Назначение некоторых часто употребляемых data-адресов, а также смещений в структурах можно найти тут:

http://gtamodding.ru/wiki/Адреса_Памяти_(SA)

Что касается адресов типа text, то в них записаны отдельные команды, из которых в свою очередь

состоят процедуры exe. Сами по себе значения этих адресов во время игры не меняются, но их, как и

адреса data, можно (не все) менять скриптом - в этом случае в опкодах 0A8C/0A8D следует ставить

значение параметра virtual protect, равное 1. Понятно, что в случае изменения значения text-адреса,

процедура, которой он принадлежит, станет работать уже по новому алгоритму.

Для поиска нужных адресов и процедур незаменима idb-база от listener. Открыть её можно с помощью

IDA 5. В окне программы есть несколько вкладок, которые представляют код exe в различном виде.

Основные из них: "IDA View-A" - основной вид. Если текущий участок exe состоит из адресов типа data,

то они отображаются в виде списка, а если текущий участок является какой-то

процедурой (text-адреса), то она отобразится в виде блок-схемы. "Hex View-A" - побайтовое отображение

кода. Многие data-адреса и процедуры в базе проименованы, при активной вкладке "IDA View-A" можно

осуществлять их поиск по названию (Search - Text).

Есть ещё полезная вкладка Functions - список всех процедур exe. Если эта вкладка активна, то можно

осуществить поиск процедуры по названию (Search). Например, осуществив поиск по слову train, можно

найти процедуры, имеющие отношение к поездам. При щелчке по названию процедуры, активируется вкладка

"IDA View-A" и появится блок-схема этой процедуры, по которой можно исследовать, как она

работает (какие процедуры вызывает, со значениями каких адресов оперирует и т.д.).

 

 

 

И как узнать адрес функции, расположенной ниже?

007F0DC0 - это и есть адрес этой функции, т.е. 0x7F0DC0

  • RESPECT + 2
Опубликовано (изменено)

     И еще вопрос, как находить смещение в адресе для интересующей детали.  Если, к примеру, 0@ += 0x678 это у нас bump_front_dummy (Инфа тоже где найдена среди груды перечитанных форумов), то как найти для остальных деталей, при чем даже для тех, что вне дамми. В качестве примера для себя взял скрипт Kenking'a "руль". Значит берётся структура авто и находится деталь по смещению 2@ = 1@ + 0x18 (Указатель на RwObject (RpClump)), и с помощью функции памяти 0x4C5400 (CClumpModelInfo::GetFrameFromName(RpClump *,char *)) вызывается эта деталь для дальнейшей работы с ней.  Это одна деталь, а как оформить на две детали? Так же через 0х18? Только с другой переменной? И заставить вторую деталь поворачиваться с первой, но чтобы она еще вертелась вокруг своей оси. Такое вообще возможно? Т.е. сейчас на основе скрипта "руль" вместе с поворотом колес - поворачивается первая деталь также по оси-Y (не стал менять адрес, повернул дами в дфф модели и угол в самом скрипте, короче, поворачивает как надо). Вторую деталь вращаться вокруг своей оси заставил, при замене на misc от комбайна, соответственно и модель заменил на сам комбайн. Но тут уже пошло все не так. После переименования поворачивающейся детали в misc_a, а второй в misc_b - первая перестала поворачиваться вместе с поворотом колес. Ну и:

Адреса функций (поворот по оси) Только по X (float) 0x59AFA0
Только по Y (float) 0x59AFE0
Только по Z (float) 0x59B020

Вызываются опкодом 0AA6

 

Изменено пользователем Constantines
Опубликовано

Чтоб тема не совсем утухла буду выкладывать примеры работы с адресами памяти. Пока что простые, так как и сам еще учусь.

цвета авто

{$CLEO .cs}
0000:

:CARSTRUCT
wait 0
if 
Actor.Driving($PLAYER_ACTOR) 
then
03C0: 0@ = actor $PLAYER_ACTOR car // присваиваем переменной 0 модель авто, в которой находится игрок
0A97: 1@ = car 0@ struct // присваиваем 1@ структуру авто 0@
// 0x0434 BYTE  colorPrimary
// 0x0435 BYTE  colorSecondary
// 0x0436 BYTE  colorTertiary
// 0x0437 BYTE  colorQuaternary
0A8E: 2@ = 1@ + 0x0434 // смещение к первому цвету, тот что [prim
 в dff
0A8D: 3@ = read_memory 2@ size 1 virtual_protect 0 // 1 - потому что 0x0434 - BYTE
else jump @CARSTRUCT
end

if
0AB0: key_pressed 48 // проверка на нажатие кнопки "0"
then
3@ = 0 // id цвета из carcolors.dat - красим в черный цвет 
0A8C: write_memory 2@ size 1 value 3@ virtual_protect 0 //записываем новое значение в память
end

if
0AB0: key_pressed 49 // проверка на нажатие кнопки "1"
then
3@ = 126 // id цвета из carcolors.dat - красим в розовый цвет 
0A8C: write_memory 2@ size 1 value 3@ virtual_protect 0 //записываем новое значение в память
end 
jump @CARSTRUCT 

 

 

статус дверей

{$CLEO .cs}
0000:

:CARSTRUCT
wait 0
if 
Actor.Driving($PLAYER_ACTOR) 
then
03C0: 0@ = actor $PLAYER_ACTOR car // присваиваем переменной 0 модель авто, в которой находится игрок
0A97: 1@ = car 0@ struct // присваиваем 1@ структуру авто 0@
0A8E: 2@ = 1@ + 0x4F8 // смещение к нужному адресу
0A8D: 3@ = read_memory 2@ size 4 virtual_protect 0 // 4 - потому что 0x4F8 - dword
else jump @CARSTRUCT
end

if
0AB0: key_pressed 57 // проверка на нажатие кнопки "9"
then
3@ = 1 // двери открыты 
0A8C: write_memory 2@ size 4 value 3@ virtual_protect 0 //записываем новое значение в память
end

if
0AB0: key_pressed 48 // проверка на нажатие кнопки "0"
then
3@ = 2 // двери закрыты 
0A8C: write_memory 2@ size 4 value 3@ virtual_protect 0 //записываем новое значение в память
end 
jump @CARSTRUCT 

 

 

статус бомбы

{$CLEO .cs}
0000:

:CARSTRUCT
wait 0
if 
Actor.Driving($PLAYER_ACTOR) 
then
03C0: 0@ = actor $PLAYER_ACTOR car // присваиваем переменной 0 модель авто, в которой находится игрок
0A97: 1@ = car 0@ struct // присваиваем 1@ структуру авто 0@
0A8E: 2@ = 1@ + 0x4A8 // смещение к нужному адресу
0A8D: 3@ = read_memory 2@ size 1 virtual_protect 0 // 1 - потому что 0x4A8 - byte
else jump @CARSTRUCT
end

if
0AB0: key_pressed 48 // проверка на нажатие кнопки "0"
then
3@ = 0 // нет бомбы 
0A8C: write_memory 2@ size 1 value 3@ virtual_protect 0 //записываем новое значение в память
end

if
0AB0: key_pressed 49 // проверка на нажатие кнопки "1"
then
3@ = 1 // бомба с таймером, активация ЛКМ 
0A8C: write_memory 2@ size 1 value 3@ virtual_protect 0 //записываем новое значение в память
end 
jump @CARSTRUCT 

 

 

Опубликовано

У меня проблема(( мне надо для кентового скрипта добыть адрес цвета фар например на челику (Тоесть не самых фар а типа если поменять цвет фар то если подоййти челиком то они стандартным на него светят хотя сами по себе они изменоные)) 

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
×
×
  • Создать...