Constantines Опубликовано 27 февраля, 2019 Жалоба Опубликовано 27 февраля, 2019 (изменено) Предлагаю в этой теме решать вопросы, связанные с адресами памяти. Только вчера добрался до программы 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 Изменено 27 февраля, 2019 пользователем Constantines Цитата
kenking Опубликовано 27 февраля, 2019 Жалоба Опубликовано 27 февраля, 2019 от 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 2 Цитата
Constantines Опубликовано 28 февраля, 2019 Автор Жалоба Опубликовано 28 февраля, 2019 (изменено) И еще вопрос, как находить смещение в адресе для интересующей детали. Если, к примеру, 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 Изменено 28 февраля, 2019 пользователем Constantines Цитата
Constantines Опубликовано 7 марта, 2019 Автор Жалоба Опубликовано 7 марта, 2019 Чтоб тема не совсем утухла буду выкладывать примеры работы с адресами памяти. Пока что простые, так как и сам еще учусь.цвета авто {$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 Цитата
kenking Опубликовано 7 марта, 2019 Жалоба Опубликовано 7 марта, 2019 И еще вопрос, как находить смещение в адресе для интересующей детали.Почитай эту тему, там много инфы. Все разобранные классы игры смотри здесь. 1 Цитата
Dezmondlin Опубликовано 23 июня, 2021 Жалоба Опубликовано 23 июня, 2021 У меня проблема(( мне надо для кентового скрипта добыть адрес цвета фар например на челику (Тоесть не самых фар а типа если поменять цвет фар то если подоййти челиком то они стандартным на него светят хотя сами по себе они изменоные)) Цитата
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.