Объявления | ||
---|---|---|
Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru. Я оторву свою задницу от всех дел и обязательно Вас активирую! Добро пожаловать на геройский форум! |
Re: База данных IDA от void17По коду многого не поймёшь. Только вот такой вывод информации спасает со сложными структурами.
|
Re: База данных IDA от void17Цитата: (cуммарный урон от достающих рукопашников + суммарный урон от достающих стрелков) / (суммарный урон от достающих стрелков + суммарный урон от достающих рукопашников * коэффициент снижения урона для Shield) Вот такой нехитрый коэффициент. И разумный. Для Air Shield всё наоборот: (суммарный урон от достающих стрелков + cуммарный урон от достающих рукопашников) / (cуммарный урон от достающих рукопашников + суммарный урон от достающих стрелков * коэффициент снижения урона для Air Shield) Чую физмиг знатно пополнится этой зимой... Сколько же нас открытий ждет |
Re: База данных IDA от void17
Таинственное поле field_544 стоит на пути полной декомпиляции конструктора, точнее, вызываемого им метода void __thiscall type_AI_spellcaster::find_enemy_attacks(type_AI_spellcaster *this). |
Re: База данных IDA от void17Скорее, битовое поле. Нужно будет тоже вывести на экран и посмотреть, что в нём хранится.
Ещё меня смущает индекс 0. Например, ++ADJ(pB)->AI_MeleeEnemy[0].threatsNum; Но массив заполняется для всех отрядов. Неужели указатель уже указывает на рассматриваемый отряд и индексация идёт именно от этого отряда? А динамически, вроде, нельзя зааджастить к началу массива. Будет переменный индекс, а зааджастить можно только на константу. Всё, понял, в цикле идёт инкремент указателя Т.е. сначала он указывает на 0-й элемент массива, а затем инкрементируется (или +1 размер структуры = 16 байт = 4 дворда). Всё-таки shifted pointer - мегакрутая вещь Вот тот же код без него:
Согласитесь, есть разница? Мы привыкли, что указатель всегда указывает на начало структуры и возможны только неотрицательные оффсеты, но компилятор не знаком с этим правилом и сдвигает начало так, чтобы ему было удобнее работать со структурой (точнее, для того, чтобы код быстрее выполнялся). Отсюда и возникают отрицательные смещения, которые по-прежнему находятся внутри структуры. shifted pointer позволяет сделать обратный сдвиг, не в самом коде, а в декомпилированном листинге, чтобы человек не путался, а читал код так, как он привык читать, т.е. когда указатель указывает на начало структуры, а не находится где-то посередине или вообще вне её. * * * Мне вот всегда интересно было, почему в коде проверки на CID_ARROW_ТОWER, ведь технически это не отряд. Как именно игра работает со Стрелковой башней? Три стрелковые башни ведь не препятствуют тому, чтобы игрок имел 20 отрядов на поле боя? И почему размер stack [2][21] = [2][20 + 1], а не просто [2][20]? Кто может быть 21-м отрядом? * * * Поправил выравнивание:
__declspec(align(4)) не нужно здесь. |
Re: База данных IDA от void17Цитата: Это не я, это IDA. Автоматически генерит. Не знаю, как отключить. Только каждый раз вручную убирать... |
Re: База данных IDA от void17AlexSpl, я НИЧЕГО не имею против shifted pointers. Эта крутая вещь, да, но она есть только в IDA.
А я хочу cpp файл написать, тобишь в Visual Studio. Их там на уровне макросов нет. Если можно их применять как-то, придумать бы как или найти в интернете определение макросов, тогда без проблем. |
Re: База данных IDA от void17Так на С++ Вы всё равно не будете писать, как в IDA - например, так: ++*(pB - 324); - Вы просто объявите указатель на type_AI_spellcaster и будете работать с ним. Вместо ++ADJ(pB)->AI_MeleeEnemy[0].threatsNum; у Вас будет ++p->AI_MeleeEnemy[i].threatsNum; (сорри, здесь, конечно, значение поля инкрементируется, но вместо инкрементации указателя далее по коду Вы будете работать с индексом массива i). Т.е. запись через shifted pointers гораздо ближе к реальному коду, чем без них.
А ещё у меня родилась крутая идея для разработчиков IDA - aliases. Часто бывает, что программа начинает работать, например, с аргументами, как с переменными, после того, как значения аргументов стали не нужны. Или использует одну и ту же переменную для работы с совершенно разными типами данных. Например, если у нас объявлена локальная переменная double a, то компилятор вполне может разобрать её на два инта и использовать половинки совершенно в других целях. Так вот, моя идея в том, чтобы можно было назначать переменной сколько угодно много имён и даже назначать отдельные имена частям переменной. Например, если программа работает со старшим двордом double a, нужно разрешить программисту задать alias этому старшему дворду, например, int b. Тогда чтение кода гораздо упростится и не будет всех этих SHIDWORD() и приведений к (__int64) в 32-разрядном коде. Технически это, наверное, через union сделать можно. Это не в духе С++, но и компилятор играет не по правилам С++ Я предлагаю любой тип для внутреннего использования IDA делать union'ом, чтобы по правому клику аналитик кода мог выбрать правильный тип в каждом конкретном случае. Кстати, IDA умеет работать с union, но нужно прописывать типы вручную. Вот вопиющий пример безобразия, творимого компилятором. Здесь union ой как нужны:
Понятно же, что в 32-битной архитектуре нет регистра rax (__int64 v14; // rax). Здесь пример того, как аргумент используется в качестве локальной переменной, и из-за его типа получается вот такой кривой код:
Попробую переписать через union позже. Вот увидите, что тут происходит совсем не то, о чём Вы могли подумать |
Re: База данных IDA от void17Это просто жесть. Такой реюз переменных, что декомпилированный код мало чем отличается от ассемблерного Как бороться дальше с реюзом переменных, не знаю Это пока самая сложная функция. Не в плане сложности вообще, а в плане сложности превратить её декомпилированный листинг в такой, который можно понять. Но уже всяко лучше того, что было.
Нужно глянуть, как её Ghidra декомпилирует Последний раз редактировалось AlexSpl 27 ноя 2021, 23:43, всего редактировалось 1 раз.
|
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1