patсher_x86 |
Здравствуйте, гость ( Вход | Регистрация )
patсher_x86 |
21 Oct 2016, 13:41
(Сообщение отредактировал baratorch - 21 Oct 2016, 13:43)
Сообщение
#1
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
Патчер - это инструмент для модификации любого исполняемого кода (не только героев). Патчер делает модинг максимально стандартизованным, удобным и безопасным. А так же помогает достичь максимальной совместимости между несколькими независимо разрабатываемыми модификациями одного кода (пример - Хд, Хота и ХВ-рулз).
С хд и хотой поставляется уже патчер версии 4.2.2 в нем теперь нет понятия неотменяемого патча. появились методы WriteAsmPatch и WriteAsmHook, которые позволяют писать конструкции типа: Код _PI->WriteAsmHook(0x4F8662, "push 1", "call %d", Sleep, "_ExecDefault", 0); Код _PI->WriteAsmPatch(0x59D715, "MOVZX ESI,BYTE PTR DS:[EAX + EBX - 0x159]", "MOV EAX, DWORD PTR DS:[EBX + 0x60]", "TEST EAX,EAX", "JNZ SHORT 0x59D72A", "CMP DWORD PTR DS:[EBX + 0x74], 1", "JE SHORT 0x59D735", "CMP EAX, 1", "JNZ SHORT 0x59D7A9", "CMP DWORD PTR DS:[EBX + 0x74], 2", "JNZ SHORT 0x59D7A9", "PUSH DWORD PTR DS:[EBX + 0x6C]", "PUSH DWORD PTR DS:[EBX + 0x68]", "MOV ECX, DWORD PTR DS:[EBX + 0x64]", "PUSH ESI", "CALL 0x4E54B0", "MOV ECX, DWORD PTR DS:[EBX + 0x64]", "MOVSX ECX, WORD PTR DS:[ECX + 0x18]", "CMP EAX, ECX", "JG SHORT 0x59D762", "MOV EDX, DWORD PTR DS:[EDI + 0x8]", "MOVZX EAX, BYTE PTR DS:[EDX + EBX - 0x159]", 0); Так же в новом патчере практически устранена разница между Code и Data патчами. Т.е. Code патч всегда пишет код именно так как мы задумали, без неочевидных конвертаций относительных адресов. И еще ряд мелких правок и багфиксов. *** Кому-нибудь это вообще интересно? Расписывать ли мне здесь общую документацию, изменения и документацию к новому функционалу? Кто-нибудь, кроме меня, Сава и феанора еще пользуется патчером? feanor, тебе это интересно? Просто у меня весьма ограничено свободное время и совершенно не хочется его тратить впустую. На вог-форуме есть тема по патчеру, но, к сожалению, цель с которой я эту тему там создавал - не достигнута. Эра так и не встала на рельсы патчера. Берсу не до эры и тем более не до патчера, поэтому писать туда смысла не вижу. -------------------- |
|
|
21 Oct 2016, 14:10
Сообщение
#2
|
|
Etoprostostatus Сообщений: 8 527 Спасибо сказали: 15833 раза |
А patcher_x64 сложно будет сделать?
-------------------- Etoprostopodpis'
|
|
|
21 Oct 2016, 14:18
(Сообщение отредактировал igrik - 25 Oct 2016, 17:03)
Сообщение
#3
|
|
Immortal Сообщений: 589 Спасибо сказали: 890 раз |
Я пользуюсь патчером. И да - мне это интересно.
Но пользуюсь я им не настолько глубоко, чтобы делать что-то грандиозное. -------------------- |
|
|
21 Oct 2016, 16:43
(Сообщение отредактировал baratorch - 21 Oct 2016, 16:48)
Сообщение
#4
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
А patcher_x64 сложно будет сделать? У меня лично в нем нет потребности и я не знаю особенностей x64 И если учесть что надо будет писать другие то да, для меня сделать сложно. Но вообще - реально. Основные проблемы, короче, - это дизассемблер длин и ассемблер, остальное - уже решаемо мной. Причем дизассемблер длин нужен компактный и быстрый, писанный на асм/си/си++. А ассемблер тоже нужен с минимальнейшим функционалом, лишь бы все инструкции понимал. + должен быть написан на си/си++. Я когда искал подходящего кандидата для x86 натыкался либо на каких-то громоздких суперфункциональных чудовищ либо на ущербов, которые даже не все 86ые инструкции переваривали. Ассемблер из OllyDbg - идеален для наших задач, но я нашел его не сразу. Насколько мне известно подобного для х64 - нет (в смысле - открытых исходников). В принципе можно обойтись и без ассемблера, как без него обходился патчер x86 до версии 4.0. Он нужен только чтобы полностью повторить имеющийся сейчас функционал. -------------------- |
|
|
21 Oct 2016, 16:44
Сообщение
#5
|
|
---------------------- New_Life_of_Heroes ---------------------- Сообщений: 226 Спасибо сказали: 345 раз |
Теоретически не представляю как пользоваться patсher_x86, да хотя бы как просто подключить его к третьим Героям без HD-мода или ХотА. Да и когда отсутствует разобранный диассамблированный код третьих Героев, не знаю, что смогу наменять в Героях, скорее добавлю какие-нибудь баги и вылеты. И на каком языке что-то писать под patсher_x86 (ERM-костылями неудобно, а Си-крест-крест - это слишком высокоуровнево для низкоуровневых представителей человечества) Поэтому для моддинга ERA/MOP only, patсher_x86 is not. И документация к patсher_x86 вряд ли поможет зелёным новичкам типа меня - это уже бесполезно в силу древности игры и минимальному интересу к моддингу у игроков в Героев в целом (может быть patсher_x86 может поднять интерес к моддингу Героев, но вероятность этого крайне низка - эта вещь сделана для программистов/хакеров, а не для обычных моддеров, лично для меня patсher_x86 не представляет интереса, когда есть более понятные и доступные для использования в третьих Героях платформы ERM/WERD), тем более нужно им понадобиться очень подробная документация с примерами "patсher_x86 для чайников" - может ли такую написать профессиональный программист (по себе могу сказать, что у меня ушло много месяцев на расжёвывания документации по ERM, вряд ли получится разобраться в документации patсher_x86, если она всё-таки будет написана)?
-------------------- WoG + MoP + HoA + Forge + Bastion = ERA+
|
|
|
21 Oct 2016, 16:55
(Сообщение отредактировал baratorch - 21 Oct 2016, 16:58)
Сообщение
#6
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
XEPOMAHT, да, pather_x86 - это инструмент именно для программиста, причем такого, кто готов реверсить код, работая с отладчиками и дизассемблерами.
просто патчер облегчает (ускоряет!) работу, по реверсингу в том числе. Мне и интересно сколько здесь таких. -------------------- |
|
|
21 Oct 2016, 17:39
(Сообщение отредактировал t800 - 21 Oct 2016, 17:39)
Сообщение
#7
|
|
Разработчик Сообщений: 534 Спасибо сказали: 221 раз |
XEPOMAHT, да, pather_x86 - это инструмент именно для программиста, причем такого, кто готов реверсить код, работая с отладчиками и дизассемблерами. просто патчер облегчает (ускоряет!) работу, по реверсингу в том числе. Мне и интересно сколько здесь таких. Здравствуйте! А каким образом Ваш патчер ускоряет работу по ререрсингу? Просто летом в свою IDA поставил плагин от James Koppel https://www.hex-rays.com/contests/2011/index.shtml им можно прямо в дебагере патчить и сразу смотреть что получилось. ЗЫ Если еще если вы дадите инструкцию с каким-нибудь примерам как ползоваться и что можно интересного сделать Вашим патчером, то если хотете я мог бы мог сделать видеоурок про Ваш парчер. Вот. -------------------- |
|
|
21 Oct 2016, 17:42
Сообщение
#8
|
|
Etoprostostatus Сообщений: 8 527 Спасибо сказали: 15833 раза |
В составе Object File Converter есть дизассемблер с открытым исходным кодом http://www.agner.org/optimize/#objconv Я с ним детально не разбирался, но там очень широкий (если не полный, вплоть до всяких FMA, AVX, AVX512) диапазон распознаваемых и дизассемблируемых команд.
Вот сейчас взглянул на фрагмент кода (opcodes.cpp): Ну и вообще, у Агнера Фога много хороших книжек на тему оптимизации ассемблерной, сишной, вместе с примерами и библиотеками. -------------------- Etoprostopodpis'
|
|
|
21 Oct 2016, 17:52
Сообщение
#9
|
|
laughed as one fey Сообщений: 12 166 Спасибо сказали: 20581 раз |
Цитата feanor, тебе это интересно? В принципе, интересно, но если инклуд будет комментирован на уровне прошлых версий - можно и обойтись, если не до того. |
|
|
22 Oct 2016, 00:53
(Сообщение отредактировал baratorch - 22 Oct 2016, 01:29)
Сообщение
#10
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
Положил на дропбокс патчер 4.2.3 (отличается от 4.2.2 меньшим размером) и обновленный хэдер для Си++:
https://dl.dropboxusercontent.com/u/5667529...r_x86%204.2.zip Итак, изменения версии 4.2 относительно 2.8: [!] Переработана структура хранения примененных патчей. Теперь патчи группируются не по адресу установки, как было, а по динамическим диапазонам (отрезкам): начальный адрес - конечный адрес. В одном таком динамическом отрезке хранятся все пересекающиеся патчи. Если применяется один патч поверх другого со смещением или отличающийся по размеру - то этот патч помещается в тот же отрезок, при этом отрезок расширяется (меняются его начальный адрес и конечный адрес) Пока (в версии 4.2), отрезки при применении патчей - создаются, расширяются. Но не уменьшаются и не удаляются при отмене. Т.е. возможна ситуация когда в одной стопке хранятся не пересекающиеся патчи (когда патч пересекающий их обоих отменен). В связи с этим теперь: - можно отменить любой патч, в том числе и перекрытый другим со смещением. FIXED патчей теперь нет. - методы, GetLastPatchAt GetFirstPatchAt, все зависимые (UndoAllAt и пр.) теперь ищут патч не по адресу установки, а по попаданию в существующий диапазон (в patcher_x86.cpp хэдере используется термин "в окрестности адреса address" вместо "по адресу address"). (методы BlockAt и BlockAllExcept по прежнему оперируют адресами установки) - изменились форматы дампа и лога патчера. дамп: Код [ ][ ][ ] 3: (00401510 05 HiHook 0000001843 - HD.HotA), (00401510 05 HiHook 0000001845 - HD.HotA), (00401510 05 HiHook 0000002968 - HD.Af) [ ][s][t] 2: (00424389 04 Patch 0000003595 - HotA), (00424389 06 LoHook 0000003596 - HotA) [ ][s][t] 2: (0042440B 03 Patch 0000003597 - HotA), (0042440B 05 LoHook 0000003598 - HotA) [a][s][t] 2: (005A8048 05 HiHook 0000002731 - HD.HotA), (005A8014 64 Patch 0000005395 - HotA) [a][s][ ] 2: (005F946E 03 Patch 0000001782 - HD.HotA), (005F9470 01 Patch 0000003184 - HD.True32) [a] значит в стопке есть патчи не совпадающие по адресам установки [s] значит в стопке есть патчи не совпадающие по размеру [t] - по типу число после типа патча - это общая глобальная очередность применения. в логе ворнинги теперь выглядят так: Код WARNING! [a][s][t]: Applying LoHook (00432E91 10 - HotA) over already applied Patch (00432E97 04 - HotA). [!] теперь для установки EXTENDED_(и SAFE_) CDECL_ HiHook-хуков можно использовать и __stdcall функции (возможность использовать __cdecl функции сохранена) - это было продекларировано для более ранних версий патчера, но с какой-то версии сломалось и не работало. Таким образом для EXTENDED_ хука хук-функция имеет единый вид: ? __stdcall new_func(HiHook* hook, ?) [-] исправлен баг с применеием-отменой-применением хуков поверх длинных патчей (размером больше 5, на практике это серии NOP'ов) [!] изменена часть мостов хай-хуков, позволяющая устанавливать хуки на рекурсивно выполняющиеся функции. Теперь для не рекурсивных вызовов выполняется один (максимально быстрый и безопасный) код, а для рекурсивных - другой. Поскольку не рекурсивных функций обычно 99+% , такой подход очень сильно повлиял на быстродействие и стабильность. [ ] теперь патчер жрет на ~ 1.2 - 1.5 мегабайта оперативы меньше (в сравнение с версиями 2.7, 2.8, ...). [ ] практически устранена разница между CODE_ и DATA_ патчами. Т.е. Code патч всегда пишет код именно так как мы задумали, без неочевидных конвертаций относительных адресов. Таким образом вызовы PatcherInstance::Write(a, d, CODE_) и PatcherInstance::Write(a, d, DATA_) теперь идентичны. [+] добавлены новые методы PatcherInstance: WriteAsmPatch и WriteAsmHook (а так же CreateAsmPatch и CreateAsmHook): *** в хэдере в методе virtual LoHook* __stdcall WriteLoHook(_ptr_ address, _LoHookFunc_ func) = 0; изменен тип func с void* на _LoHookFunc_, чтобы в MS VC++ компиляторах (в VC++ 2010 и новее) методу можно было скармливать лямбды: Код _PI->WriteLoHook(0xAABBCC, [](LoHook* h, HookContext* c) -> int { o_MsgBox("Hello from lambda LoHook!"); return EXEC_DEFAULT; }); так же для MS VC++ 2010 и новее я сделал такой макрос (через лямбду опять же): чтобы можно было ставить "быстрые инлайн" хайхуки: Код Create_HiHook(0xAABBCC, SPLICE_, EXTENDED_, int, __thiscall, FuncName, (int in, int in2), { //... return DefaultFunc(in, in2); } )->ApplyInsert(0); правда пользоваться ими для написания больших хуков неудобно, потому что IntelliSence не работает как надо внутри. *** позже буду обновлять первый пост - добавлять в него актуальную информацию, ссылки, примеры. -------------------- |
|
|
22 Oct 2016, 03:15
Сообщение
#11
|
|
laughed as one fey Сообщений: 12 166 Спасибо сказали: 20581 раз |
Лямбды, ня!
|
|
|
25 Oct 2016, 08:05
(Сообщение отредактировал baratorch - 25 Oct 2016, 08:05)
Сообщение
#12
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
Здравствуйте! А каким образом Ваш патчер ускоряет работу по ререрсингу? Несколько примеров из личного опыта: 1. Дано: В ИДА мы нашли конструктор интересующего нас объекта, в конструкторе нашли виртуальную таблицу, отреверсили определенную функцию F (т.е. +- поняли что она делает) в этой виртуальной таблице. Найти: откуда в программе эта функция F вообще вызывается? Решение: ставим с помощью патчера SPLICE_ EXTENDED_ хук на эту функцию F Внутри хука делаем запись в лог (например в ХД я использую вывод в консоль) результат hook->GetReturnAddress() так же при этом мы можем в лог писать значения входных аргументов и результат выполнения функции F, например. Запускаем программу (Героев), совершаем действия, смотрим лог. 2. Нам нужно в отладчике (OllyDbg) поставить брэйкпоинт на чтение или изменение определенного поля определенной структуры в определенный момент (т.е. после выполнения определенных действий). Решение: ставим хук на нужное место в коде (это место, понятно, должно быть отреверсено), делаем вывод адреса нтересующего нас поля (обычно адрес - динамический), нужной структуры, например с помощью MessageBox - что одновременно "ставит на паузу" выполнение программы (Героев), позволяя нам поставить бряк в отладчике на нужный адрес. Постановка на паузу особенно актуальна, если интересующее нас поле ДО интересующего нас момента может меняться в программе хренову тучу раз. Нажимаем ОК в мессадж-боксе - смотрим где сработал бряк. 3. Установка элементарной точки трассировки: Этого можно было бы добиться установкой бряка в отладчике. Но бряк останавливает выполнение программы, и в случае когда код выполняется много раз в короткий промежуток времени, такой метод (установка ьряка) совсем не юзабелен. Думаю, те, кто занимается реверсингом эти методы (о)ценят. Хотя возможно я не все знаю о возможностях Olly и IDA и их инструментами можно достичь того же. Если так, то просветите меня, пожауйста. Цитата Просто летом в свою IDA поставил плагин от James Koppel https://www.hex-rays.com/contests/2011/index.shtml им можно прямо в дебагере патчить и сразу смотреть что получилось. я плагин не смотрел, но позволяет ли он менять оригинальный код на новый большей длины? позволяет ли писать новый код не на асме а на с++, скажем?Если нет, то этот плагин совсем несравним с патчером. UPD. сейчас в сети нашел как поставить брейкпоинт на чтение/зменение памяти программно из нашего кода - в сочетании с Примером 2 вообще удобнота будет. -------------------- |
|
|
25 Oct 2016, 17:55
(Сообщение отредактировал igrik - 25 Oct 2016, 20:12)
Сообщение
#13
|
|
Immortal Сообщений: 589 Спасибо сказали: 890 раз |
А в чем принципиальная разница Hi и Lo хуков?
И еще вопрос: можно ли как-то вывести диалог, с выбором одного из 7-ми элементов. Элементы - изображения ресурсов (дерево и т.д.). (Хотя думаю вопрос не совсем в теме) -------------------- |
|
|
25 Oct 2016, 21:43
Сообщение
#14
|
|
Разработчик Сообщений: 534 Спасибо сказали: 221 раз |
Цитата Просто летом в свою IDA поставил плагин от James Koppel https://www.hex-rays.com/contests/2011/index.shtml им можно прямо в дебагере патчить и сразу смотреть что получилось. я плагин не смотрел, но позволяет ли он менять оригинальный код на новый большей длины? позволяет ли писать новый код не на асме а на с++, скажем?Нет не позволяет, только каманды asm можно писать Здравствуйте! А каким образом Ваш патчер ускоряет работу по ререрсингу? Несколько примеров из личного опыта: 1. Дано: В ИДА мы нашли конструктор интересующего нас объекта, в конструкторе нашли виртуальную таблицу, отреверсили определенную функцию F (т.е. +- поняли что она делает) в этой виртуальной таблице. Найти: откуда в программе эта функция F вообще вызывается? Решение: ставим с помощью патчера SPLICE_ EXTENDED_ хук на эту функцию F Внутри хука делаем запись в лог (например в ХД я использую вывод в консоль) результат hook->GetReturnAddress() так же при этом мы можем в лог писать значения входных аргументов и результат выполнения функции F, например. Запускаем программу (Героев), совершаем действия, смотрим лог. Может я что-то не понял, а разве по Блок Схеме в IDA нельзя просто по стрелочке глянуть откуда функция F вызывается? -------------------- |
|
|
25 Oct 2016, 23:39
Сообщение
#15
|
|
😸🧡✊✌️ Сообщений: 16 002 Спасибо сказали: 2623 раза |
Может я что-то не понял, а разве по Блок Схеме в IDA нельзя просто по стрелочке глянуть откуда функция F вызывается? Только статические вызовы функций. Динамические вызовы, т.е., через указатель на функцию и вызовы виртуальных функций в статике в принципе не отследить.
-------------------- |
|
|
26 Oct 2016, 08:57
(Сообщение отредактировал baratorch - 26 Oct 2016, 09:00)
Сообщение
#16
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
Цитата А в чем принципиальная разница Hi и Lo хуков? HiHook - это "высокоуровневый" хук. Он может ставиться только на функцию. SPLICE_ - на саму функцию. CALL_ - на ее конкретный явный вызов (call 0xAABBCC или call dword ptr [0xAABBCC]) FUNCPTR_ - на указатель, т.е. например на позицию в виртуальной таблице или таблице импорта, или на колбэк, передаваемый аргуменом в другую функцию). SLPICE_ - используется если нам всегда и везде нужно измененное поведение функции, откуда бы она ни вызывалась. СALL_ - если нам нужно измененное поведение функции только в этом конкретном вызове. FUNCPTR_ чаще применяется когда по-другому функцию не захучить (функция из таблицы импорта) если мы ставим FUNCPTR_ хук на функцию из таблицы импорта, то в рамках игры получается тот же эффект, что от SPLICE_ хука. Если поставим FUNCPTR_ хук на функцию в виртуальной таблице, то наша измененная функция будет вызываться только тем объектом - чья виртуальная таблица. Хотя сама функция при этом может входить в другие виртуальные таблицы других объектов, и на их поведение наш FUNCPTR_ хук уже влиять не будет. Используя высокоуровневый хук, мы заставляем игру вызывать вместо ее функции - нашу. Наша функция при этом имеет (должна иметь) тот же интерфейс что и оригинальная, т.е. тот же возвращаемый тип и те же аргументы. Здесь мы совершенно не запариваемся ни о каких низкоуровневых вещах - содержимом регистров и состоянием стэка, и т.п. Нам совершенно не нужно знать ассемблерный контекст вызова. Поэтому я назвал этот тип Хука - высокоуровневым. LoHook - это, соответственно, "низкоуровневый" хук. Его мы можем поставить вообще на любое место в коде. При этом мы получаем возможность работать с регистрами процессора как с переменными, используя их в нашем (допустим С++) коде и можем менять адрес возврата. LoHook - гораздо более мощный и универсальный инструмент, в сравнение с HiHook'ом. Им можно решать любые задачи (даже те что решают SPLICE_ и CALL_ хайхуки). Но я в ХД использую в основном именно ХайХуки - ибо с ними код гораздо более читаемый, удобный для правок, безопасный и минимально конфликтен с другими модификациями. ЛоуХуки стараюсь использовать как можно меньше. Я их использую в крайних случаях, когда это максимально эффективно (в плане объема работ и скорости внедрения изменений). Цитата И еще вопрос: можно ли как-то вывести диалог, с выбором одного из 7-ми элементов. Элементы - изображения ресурсов (дерево и т.д.). (Хотя думаю вопрос не совсем в теме) можно, конечно. Может быть найду время и выложу UI SDK для героев с примерами. -------------------- |
|
|
26 Oct 2016, 10:24
Сообщение
#17
|
|
Immortal Сообщений: 589 Спасибо сказали: 890 раз |
Цитата(igrik) И еще вопрос: можно ли как-то вывести диалог, с выбором одного из 7-ми элементов. Элементы - изображения ресурсов (дерево и т.д.). (Хотя думаю вопрос не совсем в теме) Можно, конечно. Может быть найду время и выложу UI SDK для героев с примерами. Это было бы идеально. -------------------- |
|
|
17 Sep 2017, 20:25
(Сообщение отредактировал AlexSpl - 17 Sep 2017, 20:26)
Сообщение
#18
|
|
Immortal Сообщений: 677 Спасибо сказали: 496 раз |
Цитата Патчер - это инструмент для модификации любого исполняемого кода (не только героев). Кто-нибудь может привести пример, как использовать патчер для моддинга других игр (например, Героев 2)? |
|
|
17 Sep 2017, 22:09
Сообщение
#19
|
|
Immortal Сообщений: 2 412 Спасибо сказали: 4617 раз |
Цитата Патчер - это инструмент для модификации любого исполняемого кода (не только героев). Кто-нибудь может привести пример, как использовать патчер для моддинга других игр (например, Героев 2)? Сейчас я в отпуске. Вернусь, покажу пример модинга героев 2. Я же начал делать ХД мод для двойки, но запнулся о локализацию, просто обломало ее делать. И работа дальше не пошла, хотя двойка (экзешник с сигнатурами) - благодатнейшая платформа для модинга. -------------------- |
|
|
17 Sep 2017, 22:28
Сообщение
#20
|
|
Immortal Сообщений: 677 Спасибо сказали: 496 раз |
Было бы очень здорово! Патчить вручную не самое приятное занятие, а возможности патчера я уже успел оценить
|
|
|
Текстовая версия | Сейчас: 29 March 2024 - 14:29 |
Copyright by Алексей Крючков
Programming by Degtyarev Dmitry |