Constantines Опубликовано 27 февраля, 2019 Жалоба Поделиться Опубликовано 27 февраля, 2019 (изменено) Предлагаю в этой теме решать вопросы, связанные с адресами памяти. Только вчера добрался до программы IDA (позволяет открывать базу данных адресов gta_sa.exe), так что есть куча вопросов. И так первый вопрос как найти нужный мне адрес. Скачал IDB database by fastman92 для gta_sa 1.0 Hoodlum от 2015 года, открыл базу и все, далее мол иди учи ассемблер, а хотелось бы без этого. Тем более большинство адресов и функций уже найдено. И как узнать адрес функции, расположенной ниже? [spoiler=Пример] .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 есть такая тема [spoiler=немного пояснений]Если есть 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 - первая перестала поворачиваться вместе с поворотом колес. Ну и:[spoiler=Адреса функций (поворот по оси)]Только по X (float) 0x59AFA0Только по Y (float) 0x59AFE0Только по Z (float) 0x59B020Вызываются опкодом 0AA6 Изменено 28 февраля, 2019 пользователем Constantines Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Constantines Опубликовано 7 марта, 2019 Автор Жалоба Поделиться Опубликовано 7 марта, 2019 Чтоб тема не совсем утухла буду выкладывать примеры работы с адресами памяти. Пока что простые, так как и сам еще учусь.[spoiler=цвета авто] {$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 [spoiler=статус дверей] {$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 [spoiler=статус бомбы] {$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 У меня проблема(( мне надо для кентового скрипта добыть адрес цвета фар например на челику (Тоесть не самых фар а типа если поменять цвет фар то если подоййти челиком то они стандартным на него светят хотя сами по себе они изменоные)) Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.