Current time: 24.11.2024, 17:14 Hello There, Guest! (LoginRegister)
Language: english | russian  

Poll: Интересно ли вам научиться самим находить необходимые данные в exe игры без посторонней помощи?
This poll is closed.
Да! 57.14% 8 57.14%
Конечно же ДА!!! 42.86% 6 42.86%
[...] 0% 0 0%
Total 14 votes 100%
* You voted for this item. [Show Results]

Post Reply 
Threaded Mode | Linear Mode
Реверс игры для новичков
» Небольшой туториал по нахождению данных для UN:C
Author Message
igrik Offline

Posts: 2819
Post: #1
Подмигивает 
Тема создана для того, чтобы объяснить основы реверс-инжиниринга для HoMM3, а также описать базовые техники и способы нахождения необходимых вам данных во внутреннем коде игры (в exe)

Необходимые программы. (Click to View)

Содержание:
1. Приведение псевдокода Иды в удобочитаемый вид ©RoseKavalier (инструкция на английском). Внесение перечисляемых типов Enum
2. Принцип нахождения необходимых данных на примере поиска параметров бонуса Баллисты, зависящего от навыка Артилерия. Часть 1
2. Принцип нахождения необходимых данных на примере поиска параметров бонуса Баллисты, зависящего от навыка Артилерия. Часть 2
3. Находим данные элементов родных геройских диалогов (окно героя)
4. Определение причины краша игры с помощью HD_CRASH_LOG.TXT и Ида ©Zur13
5. Разбор причины вылета из игры, из-за неправильных манипуляций с UN:C ©XEPOMAHT
6. Запись стрима: feanor & Orzie исследуют код и создают плагин на Мистицизм и героя специалиста по Баллистике в рамках проекта The Succession Wars на ERA 2

Памятка установки хуков на WoG (Click to View)


game bug fixes extended.dll || My Plugins || My GitHub
22.07.2020 12:55
Visit this user's website Find all posts by this user Quote this message in a reply
Zur13 Offline

Posts: 223
Post: #2

(22.07.2020 12:55)igrik Wrote:  Ребята, которые очень хорошо шарят как писать код на ERM, но не знают как находить данные в исходном коде игры для UN:C. Я всё меньше и меньше могу позволить себе выделять время на игру, и как следствие этого - в недалёком будущем я намерен полностью уйти из модинга героев, поэтому я бы хотел не забирать свои знания с собой, а передать хотя бы чать их. Интересно ли вам научиться самим находить необходимые данные в exe игры без посторонней помощи?

Жаль конечно, но всякое бьвает, я тоже думал что уйду из модинга после ведьмака 3, а потом как-то зацепился за цивилизацию 6, а потом на тытрубе зацепился за теплое ламповое прохождение героев, вспомнил свой 2010 и первую попытку в ЕРМ, где-то тут на форумах лежит небольшой скрипт с того времени, оказывается что без модинга скучно и разминка для мозгов как-никак, да и время появляется пару часов в неделю 118

Да конечно интересно, но просто передать паре человек это не то, если есть возможность нужен отдельный туториал, именно так и названый, как найти нужные адреса и данные для UN:C. Просто проблема в чем, я например не готов сам засесть за ИДУ и потратить пол года пытаясь разобраться как там в героях всё устроено, у меня просто нет столько свободного времени да и сил наверное, это исходя из того что я асм только из универа помню, а структуру PE и организации ПО в памяти так и вообще не знаю 105
(This post was last modified: 22.07.2020 13:18 by Zur13.)
22.07.2020 13:17
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2356
Post: #3

(22.07.2020 12:55)igrik Wrote:  Интересно ли вам научиться самим находить необходимые данные в exe игры без посторонней помощи?

По опыту скажу что, этим можно научиться только на практике, а именно:

1. Собственно, основы работы с UN:C - умение читать/записывать основные типы данных (integer, float) и размеры (1,2,4-байтные числа), для экстрималов - запись программного кода 148 .
2. Умение работать в соответствующем ПО - шестнадцатеричный редактор, отладчик и великом и ужасном IDA Pro.
3. Практические знания Ассемблера со знанием принципов внутреннего устройства исполняемого кода.
4. Собственно, представлять примерно где что лежит в коде и как это быстро можно найти по косвенным признакам.

Смогут ли простые смертные это осилить (на изучение могут уйти годы 148 )?

Когда всё это есть, то можно свободно уже заканчивать с UN:C и начинать писать собственные бинарные патчи и DLL-плагины.

(22.07.2020 13:17)Zur13 Wrote:  нужен отдельный туториал, именно так и названый, как найти нужные адреса и данные для UN:C.

Нет (по крайней мере я не знаю) какого-то универсального способа нахождения любых данных в коде игры, которое можно было бы описать доступным и понятным туториалом. Для каждого - свой подход. Самое простое - данные, которые просто лежат по фиксированным адресам (работает метод научного тыка, более подробно - в теме "How to edit HotA?", как раз для слабоподготовленных моддеров, меняющих что-либо в содовском exe, при этом считающих, что изменяют код HoA 148 ). Посмотрим, может быть Игрик сможет разложить всё по полкам.
(This post was last modified: 22.07.2020 13:52 by XEPOMAHT.)
22.07.2020 13:41
Find all posts by this user Quote this message in a reply
PerryR Offline

Posts: 460
Post: #4

Never really got into UN:C because I was not able to abstract examples. I'am not sure what knowledge is required to find the addresses, can everybody do it with the right tutorial or does it require the ability to read code?
I guess if you can just list the programs you use with 1 or 2 pictures and 1 or 2 examples like you did with the ballista damage. How to come from the idea to the finished ERM code.
So there is a starting point for people willing to learn/try it.
Thanks Ab
What XEPOMAHT writes already sounds complicated to me, so maybe UN:C is not for everybody.
(This post was last modified: 22.07.2020 13:46 by PerryR.)
22.07.2020 13:43
Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2356
Post: #5

(22.07.2020 13:43)PerryR Wrote:  so maybe UN:C is not for everybody.

Да, в скрипте лучше использовать UN:C как можно реже, в случаях, когда по-другому никак. По факту, UN:C - вынужденная мера, так как ERM почти не развивается. Малограмотный моддер с помощью UN:C может наделать ошибок в игре, из-за чего скрипт может приводить к утечкам памяти и случайным вылетам. Если обычные ERM-команды рекомендуется использовать осторожно, то UN:C - втройне осторожно.
22.07.2020 14:14
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #6

igrik, ты внёс неоценимый вклад в развитие игры и мы всегда будем рады даже твоим кратковременным визитам. Ну и, конечно, желаем успехов в росте и саморазвитии на работе.
Возможно, небольшой туториал с картинками пригодился бы + базы для IDA. Пригодился бы многим.

XEPOMAHT, !!UN:C команды следует помещать в именованные функции, которые делать достаточно абстрагированными от деталей реализации.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
22.07.2020 16:41
Find all posts by this user Quote this message in a reply
daemon_n Offline
Administrators

Posts: 4343
Post: #7

igrik, Присоединюсь к списку желающих, хотя к тем, кто хорошо пишет на ЭРМ не отношусь112. Начал немного изучать с++ (на телефоне, да-да96-copy ), так что понял больше половины из того, что написал XEPOMAHT.

К сожалению, отсутствие времени ограничивает нас всех - кого-то больше, кого-то меньше, но для данного темы я постараюсь приложить необходимые усилия и жертвы, особенно если это мне может помочь с пониманием работы приложений и всего подобногоYes


Image: widget.png?style=banner2

Новейший Heroes Launcher
22.07.2020 18:30
Visit this user's website Find all posts by this user Quote this message in a reply
RoseKavalier Offline

Posts: 118
Post: #8

igrik
Best of luck in your new endeavors! We have all been lucky to have you in the community and hope you will continue to drop by for fun))
22.07.2020 18:36
Find all posts by this user Quote this message in a reply
wessonsm Offline

Posts: 792
Post: #9

На многое не претендую, выше правильно сказали, что все это требует времени, которого всегда не хватает. Но какие-то основы знать было бы полезно.
22.07.2020 21:40
Find all posts by this user Quote this message in a reply
daemon_n Offline
Administrators

Posts: 4343
Post: #10

Немного граммар наци:
"Конечно же ДА!!!" не требует постановки запятой, поскольку здесь идёт уверенное утверждение.
Выкрутиться здесь можно, назвав предложение перечислением согласий, но это уж совсем за уши натянутоYes

Bes Wrote:ок-ок, исправил 20


Image: widget.png?style=banner2

Новейший Heroes Launcher
22.07.2020 21:55
Visit this user's website Find all posts by this user Quote this message in a reply
Raistlin Away
Moderators

Posts: 1349
Post: #11

igrik, это будет реально круто, жду с нетерпением)) Лично я относительно неплохо понимаю происходящее на высоком уровне, но вот как вытащить из последовательности байт что-то полезное, мне пока не очень ясно102 Ассемблер я знаю только на уровне арифметических операций и работы со строками, но при желании смогу подучить что-то еще.


Создал новый глобальный мод: WoG Ultra Edition
23.07.2020 00:37
Find all posts by this user Quote this message in a reply
igrik Offline

Posts: 2819
Post: #12

Хорошо. Давайте начнем с малого и достаточо простого.
Например, постановка задачи недавно описанная Zur13
(19.07.2020 17:43)Zur13 Wrote:  Может ли кто-то подсказать: навык Артиллерия дает 50%,75%,100% шанс баллисте нанести двойной урони дает двойной выстрел. Как это отключить
Итак, разбиваем задачу на 2 этапа:
1. Отключить второй выстрел баллисты при навыке Артилерия
2. Убрать доп.урон с шансами 50%,75%,100%

Для начала нам нужно установить необходимые программы. (Click to View)
Итак, открываем вогобазу через Иду.
Что мы видим: (Click to View)
1 - список функций, которая нашла Ида в нашем exe. На секундочку - эта вогобаза разобрана по исходнику SOD 3.2. Обязательно имейте это ввиду. Это означает, что воговских функций и адресов вы тут не найдёте! Как их искать я объясню позже
2 - это ASM код. Слева вы можете увидеть как идут адреса в шестнадцетеричной системе ".text:00401000". Как с ними работать для ERM? Сначала нам нужно научиться их переводить в десятеричную систему исчисления (ERM работает только с последней). Итак, открываем калькулятор видновс -> вид -> программист -> нажимаем чекбокс "Hex" -> копируем и вставляем например адрес 00401000 (часто пишут его как 401000h или 0x401000) -> нажимаем на чекбокс "Dec" -> и получаем адрес, представленный в десятеричной системе исчисления, т.е.: 4198400. Т.е. код для UN:C будет иметь вид !!UN:C4198400/<еще изучим>/<еще изучим>;
3 - обязательно запомните такую кнопку, как TAB (F5). С помоьщью этой волшебной клавиши, мы можем видеть так называемый С-шный "псевдокод", который намного более читабелен для человека. Ещ` одно нажатие на TAB заставит Иду перейти в ASM код.

Одно замечание на счет ASMа: не поленитесь, изучите что такое команды PUSH, POP, RETN, MOV, CALL, JMP, JNZ, JE. Этого будет хватать на 70% предварительного понимания ASM кода.

Теперь начнем практиковаться.
В ASM коде нажмите клавишу G (или вкладка "Jump->jump to address (7-мая по списку)"), вставте зачение 00475800 в появившееся диалоговое окно, нажмите Ok и сделайте 3-4 скролла средней кнопкой мыши (далее СКМ) вверх.
Вы увидите такое окно: (Click to View)
Мы попали в игровую функцию "Битва: новый раунд". (BattleMgr_NewRound)
Нажимает TAB. Ида декомпелирует и вредоставляет вашему обозрению "превдокод", который выглядит так:
Полистайте скролом и просмотрите этот код. Он более-менее описан уже за вас)
Итог: мы и научились переводить адрес в десятеричную систему из шестнадцетеричной (обратно делается так же, не сложно. Думаю вы и сами догадаетесь.), водить адрес для перехода на участок в exe, и переходить в декомпелированную функцию.

Теперь начнем решать нашу задачу.
Давайте подумаем - а за что нам зацепиться?
Так это баллиста, и вопрос состоял как "отключить второй выстрел", давайте попробуем найти функцию самого выстрела.
Для этого переходим в окно 1 (function name->скролл мышью до конца вверх->клавиша ALT+T->ищем "shoot"->ok)
Ида кидает на с на функцию "AI_Art_ShootingArt_Value". Это не наша. Кликаем в коно №1 (function name) и нажимаем далее "Ctr+T"
"AI_Battle_Defend_Shooter" - опять не наша функция. Опять "Ctr+T"
и так 5-6 раз.
В одном из случаев мы попадаем в функцию "BattleStack__PrepareShoot", т.е. подготовка для выстрела. Для тех, кто не нашел жмем "G" и вводим адрес 43FE80.
Дважды кликаем на неё (функцию BattleStack__PrepareShoot") в окне №1, и после этого в окне №2 откроется псевдокод функции подготовки выстрела. Исследуем его скроллом вниз и находим функцию "BattleStack_Shot". Да, тут Shot написано неправильно, и именно поэтому мы не смогли его найти в поиске раньше. Но вы должны понимать, что вогобаза наполнялась людми, поэтому грамматические ашибки неизбежны. Это именно тот случай. В общем, не важно. Важно что мы добрались до функции выстрела. Детальнее просмотрев код функции подготовки к выстрелу, мы обнаруживаем, что тут целых 3 вызова функции стрельбы.
[spoiler]Image: IDA1.jpg
Давайте разбираться (0043FF79):
Code:
BattleStack_Shot(stackAtt, target); // первый выстрел стека
        if ( ((unsigned int)stackAtt->Flags >> 15) & 1 && target->Count > 0 ) // флаг 15? (2^15=32768 см.ERM хелп флаги монстров: ага, двойная атака. Понятно. "И" цель->количество больше нуля (значит если стек жив))
          BattleStack_Shot(stackAtt, target); // делаем второй выстрел.

          // смотрим далее
        if ( stackAtt->creature_id == 146 && target->Count > 0 ) // ага, катапульта (id=146 и опять если цель жива)
        {
          v10 = stackAtt->SpellDuration[60]; // ERM help-> заклинания: 60=гипноз
          v11 = stackAtt->Side; // проверяем сторону баллисты
          v12 = v10 ? 1 - v11 : stackAtt->Side; // тернарный оператор: если под гипнозом, то инвертируем сторону, иначе сторона баллисты
          if ( *((_DWORD *)&o_BattleMgr->HeroA + v12) ) // тут мы с помощью определения стороны вычисляем номер героя (см.BA:H)
          {
            v13 = v10 ? 1 - v11 : stackAtt->Side; // тернарный оператор: но зачем дублировать код? я хз (опять получаем сторону). Возможно обратная перепроверка на стек под гипнозом...
            if ( *(_BYTE *)(*((_DWORD *)&o_BattleMgr->HeroA + v13) + 221) > 1 ) (проверяем у героя навык артилерии (герой)+221(201+20_Артилерия) > баз.уровня)
              BattleStack_Shot(stackAtt, target); // значит стреляем во второй раз баллистой
          }
        }

Какие выводы из этой функции?!:
1. Баллиста не имеет флага атаковать дважды. Интересненько, значит можно дать ей этот флаг, и при навыке артиллерии она будет стрелять трижды.
2. Код имеет проверку на "гипноз". WTF? На боевые машины дейстует гипноз? Я хз - нужно проверять. Но в любом случае проверка есть, а это значит,что баллиста под гипнозом по "своим" не будет стрелять во второй раз. Тут уже поле для тестов))

Так как же нам запретить второй выстрел баллисты?
Кликаем мышью (ЛКМ) на цифру 146 в псевдокоде и нажимаем TAB (переходим в ASM код)
Видим, строку
Code:
0043FF9A   cmp     dword ptr [esi+34h], 92h
где 92h = 146 (id баллисты).
По хорошему, не имея опыта конкеретно тут нужно запускать Olly, в ней запускать игру (желтое поле снизу срава после запуска игры -> эмакаем F9 сколько потребуется раз.) Запускаем карту (обычно тестовую). Переходим в Olly, жмем Ctrl+G, вводим наш адрес 0043FF9A и видим такую картину:
Image: IDA1.jpg
Тут в выделенной строке считаем кол-во байт (начиная с нуля!!)
На третьем счёте видим число 92000000 (это 4 байта!!)
Code:
0043FF9A  |> \817E 34 92000000         CMP DWORD PTR DS:[ESI+34],92
Значит, чтобы изменить номер монстра со второым выстрелом под втор.навыком артилерии, можно изменить число по адресу 0043FF9A +3 (4 байта).
Заодно сразу переведем в десятичную систему. Итого
!!UN:C4456349/4/146.
По идее можно изменить число 146 на любое другое.
Так, у нас 196 существ в игре. Значит можно поставить число 250.
Но! Важно помнить, что есть такой прекрасный мод как Тифон!
Но у нас не однобайтовое число, которое может содержать значения от 0...256 (и/или 127/-128).
А плюс в Тифоне существ 0...1000.

Можно запилить существо с id 1001 и дело в шляпе для первого вороса.
Хотя, правильнее вообще вырезать это действие (второй выстрел артилерии).
Но слишком много коньяка, да и рука болит от свеженабитой татухи.
А как это сделать более корректно (вырезать функционал второго выстрела, не меняя id монстра)? Это уже совсем другая история...

Продолжение следует...

PS: Для эксперимента, можно подменить номер баллисты на номер городской башни, и протестировать как они будут вести себя под навыком артилерии.
Бонусов 50%,75%,100% при этом не будет, а будут только у первого выстрела баллисты.


game bug fixes extended.dll || My Plugins || My GitHub
23.07.2020 01:59
Visit this user's website Find all posts by this user Quote this message in a reply
XEPOMAHT Offline
Moderators

Posts: 2356
Post: #13

(23.07.2020 01:59)igrik Wrote:  Как устанавливать - я не буду объяснять. Думаю, вы и сами справитесь.

Только для обладателей Windows 6.0 и выше. Для счастливых пользователей Windows XP/2003 максимальная версия IDA - 6.5 (проверял, более новые версии ничерта не работают, лично я пользуюсь 6.1), соответственно, ida-база будет немного другая, нежели у Игрика.

(23.07.2020 01:59)igrik Wrote:  мы можем видеть так называемый С-шный "псевдокод", который намного более читабелен для человека.

Заметьте, только для человека, хорошо знающего Си. Например, я это прочитать без комментариев Игрика не смог бы: куча странных и специфических знаков + английский язык, не зная ни того, ни другого код абсолютно нечитаемый для меня. На ассемблере, когда под рукой есть геройские структуры и имена функций - не сложно в ollydbg, подсматривая в базу IDA (там мне удобен вид иерархии для просмотра функции).

(23.07.2020 01:59)igrik Wrote:  function name->скролл мышью до конца вверх->клавиша ALT+T->ищем "shoot"->ok

А я просто открываю блокнотом H3era.dbgmap и ищу "shot" там 148 (IDA 100 лет ищет, перекапывая всю немаленькую базу, по крайней мере у меня так...).

(23.07.2020 01:59)igrik Wrote:  2. Код имеет проверку на "гипноз". WTF? На боевые машины дейстует гипноз? Я хз - нужно проверять. Но в любом случае проверка есть, а это значит,что баллиста под гипнозом по "своим" не будет стрелять во второй раз.

Гипноз вообще проверяется практически при любом действии отряда, это считай из разряда стандартных проверок в бою.

(23.07.2020 01:59)igrik Wrote:  А как это сделать более корректно (вырезать функционал второго выстрела, не меняя id монстра)?

Тут уже менять сам код - ставить прыжок вместо проверки. Т.е. поменять 2 байта в игре (если без подчистки мусора, что всё-таки рекомендуется делать, чтобы не путать отладчик).
(This post was last modified: 23.07.2020 03:10 by XEPOMAHT.)
23.07.2020 02:54
Find all posts by this user Quote this message in a reply
RoseKavalier Offline

Posts: 118
Post: #14

Great start!

My small contributions:
The functions window (1) allows CTRL+F filter which is fast, unlike the disassembly window.

IDA allows import of types (Local types Shift+F1, then Insert), enumeration, structure, types... there is no need to consult outside sources once everything useful is added, you can get something very readable without comments:
Code:
CombatMonster_Shoot_43F620(shooter, target);
        if ( (shooter->flags >> CF_DOUBLEATTACK) & 1 && target->Count > 0 )
          CombatMonster_Shoot_43F620(shooter, target);// shoot second time
        if ( shooter->creatureID == BALLISTA && target->Count > 0 )
        {
          hypnotized = shooter->spellDuration[SPELL_HYPNOTIZE];
          side = shooter->Side;
          hypnotizeSide = hypnotized ? 1 - side : shooter->Side;
          if ( P_CombatManager_699420->Hero[hypnotizeSide] )
          {
            hypnotizeSide2 = hypnotized ? 1 - side : shooter->Side;
            if ( P_CombatManager_699420->Hero[hypnotizeSide2]->secSkills[ARTILLERY] > 1 )
              CombatMonster_Shoot_43F620(shooter, target);
          }
        }

Code:
enum eCreatureFlags
{
  CF_DOUBLE_WIDE = 0x0,
  CF_FLYER = 0x1,
  CF_SHOOTER = 0x2,
  CF_EXTENDED = 0x3,
  CF_ALIVE = 0x4,
  CF_DESTROYWALLS = 0x5,
  CF_SIEGEWEAPON = 0x6,
  CF_KING1 = 0x7,
  CF_KING2 = 0x8,
  CF_KING3 = 0x9,
  CF_MINDIMMUNITY = 0xA,
  CF_NOOBSTACLEPENALTY = 0xB,
  CF_NOMELEEPENALTY = 0xC,
  CF_unk2000 = 0xD,
  CF_FIREIMMUNITY = 0xE,
  CF_DOUBLEATTACK = 0xF,
  CF_NORETALIATION = 0x10,
  CF_NOMORALE = 0x11,
  CF_UNDEAD = 0x12,
  CF_ATTACKALLAROUND = 0x13,
  CF_MAGOG = 0x14,
  CF_CANNOTMOVE = 0x15,
  CF_SUMMON = 0x16,
  CF_CLONE = 0x17,
  CF_MORALE = 0x18,
  CF_WAITING = 0x19,
  CF_DONE = 0x1A,
  CF_DEFENDING = 0x1B,
  CF_SACRIFICED = 0x1C,
  CF_NOCOLORING = 0x1D,
  CF_GRAY = 0x1E,
  CF_DRAGON = 0x1F,
};
23.07.2020 04:26
Find all posts by this user Quote this message in a reply
V_Maiko Offline

Posts: 610
Post: #15

Fantastic! RoseKavalier, you would be a very important pillar in ERA modding, you should help Berserker and the rest more often, they have all the sources so you can read them and be able to help completely in ERA Yes
Igrik doesn't have much time left for modding, so you would be worthy to carry his knowledge.

You're a powerful hero modifying hexadecimal functions in HotA and SoD, now it's time for you to be more united to the ERA family 177
(This post was last modified: 23.07.2020 07:07 by V_Maiko.)
23.07.2020 07:04
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group