patcher_x86.dll - Printable Version +- Wake of Gods Forum | Форум Во Имя Богов (http://wforum.heroes35.net) +-- Forum: Герои Меча и Магии 3.5 WoG/ERA (/forumdisplay.php?fid=99) +--- Forum: Моды (/forumdisplay.php?fid=104) +--- Thread: patcher_x86.dll (/showthread.php?tid=3648) |
patcher_x86.dll - baratorch - 11.02.2012 13:20 Дабы облегчить жизнь себе и потенциально другим мододелам, а также в целях повышения совместимости независимых разработок состряпал полезную штуку перевел на нее ХД 3 и переводится на нее ХотA готова версия 2.8: библиотека + SDK + исходники изменения: Code: Изменения нарушающие обратную совместимость: [!] Code: //////////////////////////////////////////////////////////////////////////////////////////////////////////// RE: patcher_x86.dll - Berserker - 11.02.2012 15:48 Хорошая работа, будет интересно глянуть. Я, кстати, для дизассемблирования взял готовую компактную (600 байт) Hacker Disassembler Engine (hde32), правда использовал только для определения минимального безопасного размера перехвата (5 байт и более). RE: patcher_x86.dll - kostya_76 - 11.02.2012 22:59 baratorch' Wrote:Сейчас идет тестирование и готов SDK для Cи А эта штука будет в билдере компилиться? А то SDK Berserker'а для GNU C++ билдер не понимает, а как это исправить - придумать не получается. RE: patcher_x86.dll - baratorch - 13.02.2012 18:42 должна компилиться везде ) SDK для C++ представляет 1 хидер-файл, в котором объявлены нужные структуры и интерфейсы, сама библиотека экспортирует всего 1 функцию итак версия 0.1 http://sites.google.com/site/heroes3hd/files/patcher_x86%200.1.7z?attredirects=0&d=1 в архиве: длл : patcher_x86.dll и SDK С++: patcher_x86.h - хидер совсем без комментариев (выглядит не таким страшным и большим как комментированный) patcher_x86_commented.h - тот же хидер с ооччень подробными комментариями RE: patcher_x86.dll - Berserker - 13.02.2012 20:09 Тогда уж либо хэдер, либо заголовочный файл ) RE: patcher_x86.dll - baratorch - 13.02.2012 21:36 ну простите ) RE: patcher_x86.dll - kostya_76 - 13.02.2012 21:42 (13.02.2012 18:42)baratorch Wrote: patcher_x86_commented.h - тот же хидер с ооччень подробными комментариями Не хватает примера создания хука. RE: patcher_x86.dll - Berserker - 13.02.2012 22:04 Кстати, из-за ООП и fastcall вызовов переходник SDK на Object Pascal или C вряд ли возможен. RE: patcher_x86.dll - baratorch - 13.02.2012 22:56 ну fastcall я запросто переделаю в stdcall а для си, если заморочиться, можно написать SDK объявив таблицу виртуальных методов в структурах и описать функции через эту таблицу Quote:Не хватает примера создания хука. Я ж написал в 1 посте, примеры - будут. позже RE: patcher_x86.dll - Berserker - 13.02.2012 23:25 Кстати, а почему бы автора патча не определять автоматически по адресу возврата? VirtualQuery на адрес, получить базовый адрес, GetModuleFileName на него? RE: patcher_x86.dll - baratorch - 15.02.2012 13:53 хорошая идея, воспользуюсь ей позже версия 0.2 http://sites.google.com/site/heroes3hd/files/patcher_x86%200.2.7z?attredirects=0&d=1 переделал функцию выполняющуюся при срабатывании LoHook хука из __fastcall в __stdcall скорректировал SDK для C++ написал SDK для С и для Delphi, но комментарии пока есть только для С++ коментарии к C и Делфи а так же примеры для C++, C, Делфи будут позже RE: patcher_x86.dll - baratorch - 17.02.2012 02:15 итак версия 1.0: http://sites.google.com/site/heroes3hd/files/patcher_x86%201.0.7z?attredirects=0&d=1 скорректировал и закрепил функционал для версии 1.0 исправил баги добавил логирование и функцию сохранения лога в файл написал коментированный SDK и коментированный пример для делфи написал коментированный SDK и коментированный пример для С++ для извращенцев SDK для С (коментарии и пример смотреть в SDK C++) примеры - плагины для эры/ХД (в ХД кидать в папку _HD3_Data\Common) примеры - протестированы, компилируются, работают в комплекте так же идет _HD3_.dll версии 3.0 бета 7 (та же бета 6, но переведенная на patcher_x86.dll) сочетание клавиш [SHIFT]+[CTRL]+[ALT]+[DEL] в ХД вызывает стоп-ошибку, при этом кроме крашлога в папку с игрой пишутся дамп и лог патчера: patcher_x86 dump.txt и patcher_x86 log.txt надеюсь все это будет интересно и полезно. новые версии длл будут с обратной совместимостью, т.е. моды/плагины написанные для 1.0 будут работать корректно с более новыми версиями RE: patcher_x86.dll - baratorch - 20.02.2012 08:49 готова версия 1.1: http://sites.google.com/site/heroes3hd/files/patcher_x86%201.1.7z?attredirects=0&d=1 [*] сильно смягчены правила установки патчей, теперь все конфликтные патчи применяются, WARNING сообщение о конфликте пишется в лог. [*] логирование по умолчанию теперь отключено, чтобы включить его, необходимо в той же папке создать файл patcher_x86.ini c единственной записью: Logging On = 1 (Logging On = 0 - отключает логирование) [*] исправлены ошибки в библиотеке и файлах SDK [*] скорректированы описания-коментарии в SDK [*] изменена форма записей в дампе и в логе RE: patcher_x86.dll - baratorch - 28.02.2012 09:38 готова версия 1.2: http://sites.google.com/site/heroes3hd/files/patcher_x86%201.2.7z?attredirects=0&d=1 исправил ошибки убрал _HD3_.dll из сборки, т.к. выпускаю HD 3.0 beta 8 (на базе patcher_x86 1.2) RE: patcher_x86.dll - Sav - 18.03.2012 19:04 Похоже, высокоуровневый хук CALL_, EXTENDED_, FASTCALL_ для функции с одним аргументом работает неправильно. При каждом вызове он уменьшает ESP на 4. Если заменить на THISCALL_, то всё нормально. RE: patcher_x86.dll - Sav - 24.03.2012 23:36 SPLICE_ хук очень плохо себя ведёт, когда в затираемом им коде содержится локальный переход. Вызов оригинальной функции в этом случае невозможен. RE: patcher_x86.dll - gamecreator - 25.03.2012 01:37 можно как-нибудь поставить хук на завершение функции? придется ставить хук на все места выхода? а если выход из нее находится посреди кода? RE: patcher_x86.dll - Sav - 25.03.2012 09:10 Поставь splice хук и вызови в нём оригинальную функцию до собственного кода. RE: patcher_x86.dll - baratorch - 26.03.2012 09:14 (18.03.2012 19:04)Sav Wrote: Похоже, высокоуровневый хук CALL_, EXTENDED_, FASTCALL_ для функции с одним аргументом работает неправильно. При каждом вызове он уменьшает ESP на 4. Если заменить на THISCALL_, то всё нормально.да, так и есть. Для меня это - само собой, поэтому даже не подумал обратить на это внимание в комментариях. Хотя Code: если int __fastcall orig(int a1, int a2, ?) то int __stdcall new_func(HiHook* h, int a1, int a2, ?) Действительно, этот недостаток можно обойти используя EXTENDED_ THISTCALL_ Ну а для читабельности и логичности можно использовать пару констант типа: FASTCALL_1_ = THISCALL_ и FASTCAL_2_ = FASTCALL_ Просто мне не представляется возможным, чтобы хук сам мог определять сколько аргументов передается замещаемой функции, поэтому EXTENDED_ FASTCALL_ всегда пушит и ECX и EDX в стек. Quote:SPLICE_ хук очень плохо себя ведёт, когда в затираемом им коде содержится локальный переход. Вызов оригинальной функции в этом случае невозможен.Дело в функциональности MemCopyCode, сейчас она копирует корректно только CALL и далекий JMP опкоды. После твоего поста добавлю поддержку далеких JE, JNE, JL, JG, JLE, JGE, JA, JB, JBE, JNA, .... Впринципе короткие прыжки можно в замещаемом коде при копировании заменять на длинные, однако тогда скопироавнный код будет длиннее оригинального, что еще добавит работы... Короче, сделаю в следующем релизе. RE: patcher_x86.dll - baratorch - 04.04.2012 14:17 1.3 http://sites.google.com/site/heroes3hd/files/patcher_x86%201.3.7z?attredirects=0&d=1 старался как можно сильнее сохранить обратную совместимость. но полностью не получилось. ХД 3 написанный с patcher_x86 SDK 1.2, например прекрасно пошел на новой 1.3 (а вот последнюю редакцию ХоТы придется подправить) чейнджлог: Code: Изменения нарушающие обратную совместимость: [!] RE: patcher_x86.dll - Berserker - 04.04.2012 19:33 baratorch, круто, но, кажись, журнал изменений продублирован. RE: patcher_x86.dll - baratorch - 25.06.2012 08:23 готова версия 1.4: http://sites.google.com/site/heroes3hd/files/Patcher%20x86%201.4.zip?attredirects=0&d=1 изменения: Code: 1.4 RE: patcher_x86.dll - baratorch - 27.07.2012 09:43 готова версия 1.6: http://sites.google.com/site/heroes3hd/files/Patcher%20x86%201.6.zip?attredirects=0&d=1 изменения: Code: 1.6 так же в архиве плагин для эры (wog_patcherizer.era), который засталяет Эру делать все инициализационные патчи ВоГ через patcher_x86 (версии не ниже 1.6) *** надо бы еще сделать чтобы эра делала все патчи через patcher_x86. будет очень зашибись.. в логе patcher_x86 будут сразу видны все потенциальные конфликты RE: patcher_x86.dll - Berserker - 27.07.2012 14:04 Quote:надо бы еще сделать чтобы эра делала все патчи через patcher_x86.Хм, глянул, появились переходники на Паскаль. В таком случае посмотрю, что можно сделать к следующей версии. Имеет ли смысл использовать один объект заплатки на все изменения? Или на каждый чих свой объект? RE: patcher_x86.dll - baratorch - 27.07.2012 17:30 не очень понял вопрос, но попытаюсь ответить. установка патча с помощью patcher_x86 в виде непрерывной последовательности байт - это всегда создание нового отдельного объекта TPatch ХД+ХотА ставят более 3000 патчей/хуков ХД+ВоГ - более 2200 ХД - более 1200 никаких промедлений при запуске не заметно, тыщи патчей ставятся 'мгновенно'. ну, подумаешь, сколько-то там сотен килобайт памяти расходуется на это дело зато удобств куча. как мне видится использование patcher_x86 в эре: патчи из самой эры (если таковые имеются) устанавливаются через TPatcherInstance c именем "ERA" а скажем каждая bin заплатка через TPatcherInstance c именем "ERA:<имя_заплатки.bin>" и, bers, обрати внимание на Хуки в patcher_x86. посмотри SamplePlugin в SDK Delphi. Хоть пример и не охватывает весь функционал patcher_x86, но некоторое представление о хуках дает . Было бы вообще супер, если бы ты полностью перешел на них, отказавшись от своей реализации в Эре. ну реально удобно видеть где кто какие патчи поставил,.. где какой патч пересек другой.. RE: patcher_x86.dll - Berserker - 27.07.2012 19:18 Да, я понял. Попробую. RE: patcher_x86.dll - baratorch - 24.09.2012 17:36 готова версия 1.7: https://sites.google.com/site/heroes3hd/files/Patcher%20x86%201.7.zip?attredirects=0&d=1 Code: 1.7 SAFE_ subtype создан прежде всего для установки хуков поверх воговских, т.к. воговские хуки функций часто не ограничиваются аргументами, но используют значения из регистров процессора в контексте вызова в геройском коде. проблема решалась и без SAFE_, просто вначале Hi-хука нужно было сохранить значения регистров и восстановить их перед вызовом дефолтной функции. Однако patcher_x86 создан для высокоуровневого модифицирования, и использовать асемблер с ним - идеологически неверно. RE: patcher_x86.dll - baratorch - 21.11.2012 06:37 Исходники patcher_x86 (MS VC++ 2008): http://sites.google.com/site/heroes3hd/files/patcher_x86%201.7%20src.7z?attredirects=0&d=1 Berserker Wrote:Наконец, если там вдруг ошибка или ошибка в SDK, или нужно глянуть реализацию, потому что мой код не работает, исходников нет.Примеры SDK для всех языков билдились и тестировались успешно. В самом патчере 1.7 пока ни ХотА ни ХД не нарвались на баг. Berserker Wrote:Помимо прочего я не помню (поправьте если не прав), чтобы клиенты патчера могли делать то же самое: получить список всех заплаток, например (а ради чего ещё остальным такая централизация?). Наконец, если там вдруг ошибка или ошибка в SDK, или нужно глянуть реализацию, потому что мой код не работает, исходников нет.Список всех заплаток клиент получить не может. Было бы не плохо если б было можно. Еще лучше была бы функция: получить патчи в указанном диапазоне адресов. Что сейчас может клиент. Может отменить/применить все патчи, может отменить применить все патчи указанного PatcherInstance (т.е. мода или части мода). Можно получить все патчи по конкретному адресу. А еще клиент может сохранить в файл дамп - карту всех наложенных патчей в данный момент времени; и лог, показывающий очередность применения/отменения патчей с деталями и потенциальные конфликты. Разработчик смотрит дамп и лог и, руководствуясь увиденным, делает изменения в коде мода. Вот ради возможности посмотреть такие дамп и лог (которые кроме всего прочего показывают какой мод (PatcherInstance) установил определнный патч/хук) и возможности включать отключать патчи установленные из других модов и нужна централизация. Все патчи хранятся в упорядоченном двоичном дереве, каждый лист которого - адрес с динамическим массивом всех наложенных по этому адресу патчей. Правда в каждом PatcherInstance хранится еще и связанный список всех его патчей. Возможно это всё лишние нагромождения, и можно б было обойтись динамическим массивом вместо дерева, но дерево сделано для скорости доступа к патчу по конкретному адресу (хотя я, крайне редко использую эту возможность). (20.11.2012 06:56)GrayFace Wrote:Главная фича хуков патчера - это то, что разные моды независимо друг от друга могут хучить одну и туже функцию или ее конкретный вызов сколько угодно раз, не перекрывая а дополняя её код при желании.(15.11.2012 03:03)baratorch Wrote: Было бы здорово, если б 3.59 тоже перешел на патчер, ибо никакие узкоспециализированные API и скриптовые языки не смогут решать такие задачи, какие может патчерЯ сейчас использую удобную систему хуков на Луа. По сути, любые задачи с помощью моего модуля хуков/структур/работы с памятью можно решать. Одно исключение - когда нужна скорость, тогда придется грузить dll или байт-код писать строкой. Да, еще ограничение - код должен исполняться в основном потоке. Патчер я глянул только чуть-чуть и, как я понял, есть сходства с моими хуками в высокоуровневости. Ну и описанные выше возможности по управлению чужими патчами/хуками и просмотр дампа и лога - очень важная и полезная вещь. вот пример дампа: Quote:instances(7): 'HD', 'HotA', 'spellbook.patch', 'HD.Af', 'HD.TE', 'HD.IG', 'HD.Pack.SuperRus', и лога: Quote:log records count: 3769 RE: patcher_x86.dll - Berserker - 21.11.2012 13:38 baratorch, спасибо за исходники и разъяснения. Мне осталось только разобраться в конфликтах виртуальной файловой системы Эры и Wine. Quote:Главная фича хуков патчера - это то, что разные моды независимо друг от друга могут хучить одну и туже функцию или ее конкретный вызов сколько угодно разПодавляющее большинство моих перехватов находится в произвольных частях. Правку call/jmp смещений в затёртых командах я добавил, так что и пять заплаток в одно место в режиме "мост" сработают. Но в целом направление верное, будем туда и копать. RE: patcher_x86.dll - Berserker - 01.01.2013 22:27 Патчер 1.7, SDK C++, patcher_x86.hpp: 225:2 [Warning] no newline at end of file RE: patcher_x86.dll - gamecreator - 01.01.2013 23:00 ну добавь. тем более, что это такой несущественный пустяк, который и предупреждением не назовешь RE: patcher_x86.dll - Berserker - 04.01.2013 21:51 Code: SAFE_ - то же самое что и EXTENDED_, однако перед вызовом (на время вызова) GetDefaultFunc() восстанавливаются RE: patcher_x86.dll - Sav - 04.01.2013 22:01 В HiHook'ах регистры сохраняются до перехвата и восстанавливаются после. А когда делаешь CALL от GetDefaultFunc никакие регистры не восстанавливаются: ведь вызываемая функция не должна работать ни с чем, кроме своих параметров. Однако, по-видимому, в Воге кое-где в вызываемой функции используются регистры, значение которых было присвоено в вызывающей функции и, не будучи параметром, волею случая при компиляции, не затёрто в вызываемой функции. Судя по описанию, SAFE_ отвечает за восстановление регистров именно перед вызовом функции по GetDefaultFunc. RE: patcher_x86.dll - Berserker - 04.01.2013 22:43 Спасибо, что-то подобное и предполагал. RE: patcher_x86.dll - Berserker - 05.01.2013 00:05 .hpp]ISO C++11 переработанный вариант заголовочного файла патчера
RE: patcher_x86.dll - Berserker - 06.01.2013 03:10 ППЦ, чувствую себя магом. Code: template<typename T> struct to_dword Code: patching::call<HMODULE, patching::kCdecl>(0x887668, L"Hello", L"World"); Code: MOV [DWORD ESP+4],60103086 Всё без макросов ))) RE: patcher_x86.dll - hippocamus - 09.01.2013 12:59 (05.01.2013 00:05)Berserker Wrote: Антонимом к Direct ("прямой") является посреднический, а "расширенный" и "безопасный" вообще сбивают с толку.Relative ("относительный") же! RE: patcher_x86.dll - Berserker - 09.01.2013 18:11 В контексте функций-перехватчиков, перехват либо прямой, либо через посредника. RE: patcher_x86.dll - Berserker - 28.06.2013 14:16 Меня в Делфийском SDK смущает строчка: Code: vtString: dword_args[i] := _dword_(PAnsiChar(AnsiString(VString^ + #0))); Правильнее, наверное, будет оставить строку как есть. RE: patcher_x86.dll - Berserker - 28.06.2013 15:21 Quote:// заранее объявлены переменные _P и _PI для использования во всех модулях пректа RE: patcher_x86.dll - Berserker - 02.07.2013 19:50 Методы GetOriginalFunc, GetReturnAddress не потокобезопасны. В Делфийском SDK не потокобезопасен Call (глобальный массив аргументов). RE: patcher_x86.dll - baratorch - 16.08.2013 09:06 Bersy Wrote:.hpp]ISO C++11 переработанный вариант заголовочного файла патчерассылка, помоему, с самого начала мертвой была, ну или пару дней продержалась, так и не смог скачать посмотреть. Вот пишу об этом только сейчас. насчет DIRECT_ и EXTENDED_ c DIRECT_ - все понятно. а в EXTENDED_ - основной смысл не в том что мы функцию через мост вызываем, а в том что из тела функции можем получить аргументом указатель на экземпляр хука. В этом и расширенность хука. А то что эта расширенность невозможна без моста, так это побочный эффект. Вот такая логика у меня была. SAFE_ назван мной так для краткости, по моей логике должен называться SAFE_EXTENDED_ а еще правильнее WOG_SAFE_EXTENDED )) Quote:ППЦ, чувствую себя магом.к сожалению пишу в MS VS 2008, а в ней не поддерживается ISO C++ 11 в полной мере оценить красоту решения не могу. Bersy Wrote:Меня в Делфийском SDK смущает строчка: Quote:В Делфийском SDK не потокобезопасен Call (глобальный массив аргументов).Вы уж простите меня, но мой опыт работы с паскалем составлен из 3х этапов: 10класс школы, перевод исходников Хота на C++, написание SDK для патчера. Здесь лучше заняться исправлением улучшением и оптимизацией, опытному паскалисту/делфисту. Bersy Wrote:Методы GetOriginalFunc, GetReturnAddress не потокобезопасны.тогда получаются непотокобезопасны методы Apply, ApplyInsert и Undo (у Patch/LoHook/HiHook) т.к. может случится так что когда один поток будет стирать патч, другой будет ставить в это же место (а ставя он читает 'старый' код) и вообще в это время может до этого места дойти выполнение модифицируемой программы. Потокобезопасностью никогда не занимался. Поможет ли создание одной единственной критической секции для всего патчера, и вход в нее когда пишем в код и в default_func??? если я правильно понял проблему.... RE: patcher_x86.dll - Sav - 22.08.2013 21:02 В LowHook`ах следует сделать pushf после сохранения всех регистров - тогда внутри хука можно будет свободно работать с c->esp. Сейчас же это невозможно, т. к. он меняется до хука и используется после. RE: patcher_x86.dll - Berserker - 05.09.2013 21:11 Quote:Поможет ли создание одной единственной критической секции для всего патчера, и вход в нее когда пишем в код и в default_func???Думаю, не стоит. Пусть пользователи сами оборачивают. Залил два своих файла: http://wikisend.com/download/439718/Patcher.rar RE: patcher_x86.dll - Berserker - 25.09.2013 19:27 Ужаснулся, глянув в код низкоуровневого перехватчика. Регистры не в стеке сохраняются и передаются, а в глобальной памяти. Это значит, что рекурсивный вызов перезатрёт их подчистую! Spoiler (Click to View) RE: patcher_x86.dll - Berserker - 26.09.2013 18:44 EXEC_DEFAULT = 1; NO_EXEC_DEFAULT = 0; Проверка в коде патчера на 1 не есть хорошо. Нужно сравнивать с нулём. Так работает тип bool: 0 = ложь, остальное - истина. RE: patcher_x86.dll - Berserker - 10.10.2013 19:43 Ещё не хватает возможности в параметрах записи высокоуровневого перехватчика пользовательский указатель, который будет сохранён в структуре перехватчика и по которому можно было бы определить, с какой целью ставился перехват и кто его клиент. Что=то вроде HiHool->UserData. Не хочется также изобретать велосипед по поводу генерации журнала о вылете. Может быть оформить эту часть хд в виде плагина? RE: patcher_x86.dll - baratorch - 24.10.2013 21:32 Quote:Ужаснулся, глянув в код низкоуровневого перехватчика. Регистры не в стеке сохраняются и передаются, а в глобальной памяти. Это значит, что рекурсивный вызов перезатрёт их подчистую!я так понял речь о мосте LoHook хука. во-первых, регистры сохраняются не в глобальной памяти а в памяти выделенной для конкретного объекта LoHook. точно так же и память под мост выделена для каждого конкретного LoHook объекта и сам мост уникален для каждого экземпляра LoHook. То есть получается что каждый мост каждого LoHook объекта работает со своей областью памяти для хранения значений регистров. во-вторых, я не понимаю о какой рекурсии может идти речь. если будет иметь место рекурсивный вызов самой высокоуровневая функций (которую мы используем для вызова из моста) то, да, каждый вызов будет работать с текущим общим значением регистров контекста для данного хука. Но чем это страшно и зачем может понадобиться такая рекурсия не знаю. в-третьих, один патч (с собственным одним мостом и объектом HookContext) невозможно применить дважды ни к одному и тому же адресу ни к разным адресам. то есть рекурсивное выполнение кода моста невозможно. На практике все прекрасно, что подтверждает правильность реализации. т.е. HookContext передаваемый в высокоуровневую LoHook функцию на самом деле является частью LoHook, но доступен он только из высокоуровневой функции, ибо в другое время доступ к нему не имеет смысла. Quote:Проверка в коде патчера на 1 не есть хорошо. Нужно сравнивать с нулём. Так работает тип bool: 0 = ложь, остальное - истина.поправил в версии 2.1 Quote:Ещё не хватает возможности в параметрах записи высокоуровневого перехватчика пользовательский указатель, который будет сохранён в структуре перехватчика и по которому можно было бы определить, с какой целью ставился перехват и кто его клиент. Что=то вроде HiHool->UserData.не совсем понял зачем это нужно. можно абстрактный пример?... ни внутри хд, ни в нутри хоты, ни во взаимодействии до сих пор не понадобилось ничего подобного. позже опубликую версию 2.1 RE: patcher_x86.dll - Berserker - 24.10.2013 22:38 Quote:во-вторых, я не понимаю о какой рекурсии может идти речь.Процедура Х (...) команда 1 низкоуровневый перехватчик №1 команда 2... Низкоуровневый перехватчик №1(...) вызвать процедуру Х(...); рекурсия !!! другие команды... Многие АПИ и часть алгоритмов требует рекурсии. Нельзя, чтобы перехватчик по одному адресу сохранял контекст в одной и той же области памяти. В такой перехватчик невозможно зайти дважды, не затерев предыдущий контекст. В Эре контекст сохраняется через PUSHAD и таких проблем нет. Quote:не совсем понял зачем это нужно. можно абстрактный пример?...Положим, есть скриптовый язык, для примера будет ЕРМ, но только для примера. Ему предоставляется АПИ для установки перехватчика SetHook(Addr, ERM_FUNC_ID). Реально вызывается WriteHiHook на одну общую функцию: CallErmFunc. Но так как это именно функция без привязки к данным, она не может определить, какой ERM_FUNC_ID вызывать в свою очередь ей. Для этого в ЯП используют делегаты - связку: адрес объекта + адрес метода объекта. Иначе говоря, одна функция обслуживает десятки перехватов. Чтобы определить, кому дальше передавать управление, ей нужно проанализировать какое-то поле данных, но ничего передать не получается. А с другой стороны, всегда передаётся-таки объект Hi/LoHook. Однако он бесполезен, в нём нельзя сохранить пользовательский указатель (h->UserData = ...). RE: patcher_x86.dll - baratorch - 25.10.2013 08:11 Quote:Процедура Х (...)понял о какой рекурсии идет речь, но это изврат - вызывать из лоухука код, в который установлен этот лоухук. хочу реального примера. Но посмотрю, конечно, что можно сделать. В HiHook UserData добавлю А так к версии 2 в патчере появились две вкусные вещи WriteLoHookEx и WriteHexHook. WriteLoHookEx работает так же как WriteLoHook, но позволяет полноценно работать со стеком контекста, т.е. возможно выполнение такой штуки: Code: int __stdcall LoHook_Func(LoHook* h, HookContext* c) а WriteHexHook устанавливает LoHook без использования высокоуровневой функции, тело хука пишется прямо в вызове WriteHexHook в машинных кодах, подобно тому как патч пишется с помощью WriteCodePatch пример: Code: _PI->WriteHexHook(0x335577, NO_EXEC_DEFAULT, "FF 35 %d", &x); // push [&x] Вот, кстати, с помощью WriteHexHook и можно самостоятельно написать свой мост к высокоуровневой функции любого содержания, в том числе и сохраняющего регистры в стеке. RE: patcher_x86.dll - Berserker - 25.10.2013 17:42 Quote:понял о какой рекурсии идет речь, но это изврат - вызывать из лоухука код, в который установлен этот лоухук.Например, FindFileInLod. А в нём if FindFileInLod(файл с альтернативным расширением или изменённым именем, то вернуть его), иначе действие по умолчанию. У меня были и другие примеры, но нужно лезть в код и искать те, где была рекурсия. При чём порой рекурсия была косвенной, когда ты вызываешь АПИ, которое дёргает ту же функцию, в которой перехват. Это нормально, ибо рекурсия не бесконечная, а ограничена условиями и проверками. Quote:с->esp -= 4; Я обычно пишу так: dec(Context.esp, 4) и pinteger(context.esp)^ := x; Вряд ли можно чем-то упростить работу с обычными адресами в памяти, но посмотрим. Quote:В HiHook UserData добавлюСпасибо. Quote:Но посмотрю, конечно, что можно сделать.PUSHAD PUSH ESP? )) RE: patcher_x86.dll - baratorch - 25.10.2013 20:20 (25.10.2013 17:42)Berserker Wrote:в приведенном примере напрашивается использование хай хука на FindFileInLod. Но в любом случае я уже сделал сохранение регистров в стэке.Quote: хочу реального примера. (25.10.2013 17:42)Berserker Wrote:ты не понял о чем речь.Quote:с->esp -= 4; мой и твой код идентичны, дело не в простоте. В твоем хуке по адресу (Context.esp - 4) храниться значение одного из регистров. Т.е. с каждым таким push в хуке ты будешь портить значения регистров, которые возможно соберешься использовать после такого пуша, и которые потом заPOPADишь в мосте, а за регистрами пойдут указатель на экземпляр THookHandlerArgs и адрес возврата в мост. Надеюсь, проблема понятна. (25.10.2013 17:42)Berserker Wrote:не так все просто.Quote:Но посмотрю, конечно, что можно сделать.PUSHAD PUSH ESP? )) В структуре HookContext патчера регистры в обратном порядке нежели в THookHandlerArgs и чтобы сохранить обратную совместимость пушить регистры надо в обратном PUSHADу порядке. плюс в новой версии патчера в HookContext еще и доступен для чтения/изменения регистр флагов, а он для той же обратной совместимости добавлен после поля return_address. сама длл 2.1 и хэдер для с++ с комментариями уже готовы. дополню твой PatchApi.pas и опубликую. RE: patcher_x86.dll - Berserker - 25.10.2013 22:04 Отлично. RE: patcher_x86.dll - baratorch - 26.10.2013 21:47 версия 2.1 библиотека + SDK + исходники чейнджлог: Code: 2.1 Добавил SetUserData и GetUserData к HiHook, но функцию установки HiHook хука с одновременным указанием UserData писать не стал. Ее можно быстро написать самому, используя PatcherInstance::CreateHiHook, HiHook::SetUserData и HiHook::Apply Есть один нюанс. В хота 1.2 и в ХД+ версий ниже 3.59 есть критический баг в использовании патчера, который прощали старые версии, но не прощает 2.1 RE: patcher_x86.dll - Berserker - 26.10.2013 22:12 Quote:Добавил SetUserData и GetUserData к HiHook, но функцию установки HiHook хука с одновременным указанием UserData писать не стал.Согласен. Не стал писать это же предложение. Quote:В хота 1.2 и в ХД+ версий ниже 3.59 есть критический баг в использовании патчера, который прощали старые версии, но не прощает 2.1Если есть двоичная несовместимость, можно было и в LoHook использовать PUSHAD (что быстрее ручного порегистрового сохранения). А с другой стороны, это нужно кучу всего обновлять. Меня просто всё время точит червь оптимизации ))) Кстати, использовал уже несколько раз исходники ХД при поиске информации. Так что открытые материалы имеют таки синергетический эффект. RE: patcher_x86.dll - baratorch - 28.10.2013 12:46 версия 2.2 библиотека + SDK + исходники чейнджлог: Code: 2.2 RE: patcher_x86.dll - baratorch - 03.12.2013 16:39 версия 2.3 библиотека + SDK + исходники чейнджлог: Code: 2.3 patcher_x86.hpp для С++ дополнен еще и методами Patcher::VarGetValue(name, default_value) и Patcher::VarValue(name), которых нет в PatchApi.pas но подобные методы можно написать самому. HD версии 3.660 теперь использует патчер 2.3 и использует его общие "переменные". Экспортируемые _HD3_.dll методы HdCommon_Get и HdCommon_Set оставлены для обратной совместимости, но теперь являются оболочками новых методов патчера. напомню, с помощью [SHIFT]+[CTRL]+[ALT]+[DEL] в ХД вызывается краш c генерацией логов, и в сгенерированном patcher_x86 dump.txt можно посмотреть все общие "переменные" и их значения Теперь чтобы использовать "переменные" ХД, не нужно грузить _HD3_.dll и импортировать ее функции. еще один шаг для взаимодеийствия и дружбы модов. RE: patcher_x86.dll - Berserker - 03.12.2013 19:21 Аналог общей библиотеки-реестра выходит (хранение ключей-значений с интерфейсом доступа к ним). RE: patcher_x86.dll - Arseniy - 31.03.2014 12:28 У меня, может, немного нубский вопрос, но я пока не понял, как выглядит система с патчером в действии. Вот если я хочу использовать вместе свой мод, который будет прописывать какие-то значения в игре с помощью патчера, и HD Mod. Как, что и к чему нужно подключать? И второй вопрос про jump хуки в код. Если я правильно понимаю, то функции патчера просто позволяют извлечь текущий контекст в ассеблеровском виде, то есть нужно доподлинно знать, что именно сейчас лежит в регистрах и за что отвечает? RE: patcher_x86.dll - Berserker - 31.03.2014 21:39 Погляди что-ли плагины Феанора с исходным кодом в качестве примеров. RE: patcher_x86.dll - baratorch - 03.11.2014 02:19 версия 2.5 библиотека + SDK + исходники чейнджлог: Code: 2.5 RE: patcher_x86.dll - baratorch - 03.11.2014 02:49 Bers, продолжим здесь. baratorch Wrote:Berserker Wrote:На мой взгляд, указанная тобой, Бара, проверка, неэффективна. Мало ли из какого кода какого модуля вызывается запись патча? Из ЕРМ? Из сгенерированного в оперативной памяти обработчика? Из модуля, который использует функционал другого?Берс, я хочу чтобы у тебя там все работало с патчером. Я понял в чем дело. Нужно заменить Patcher.Write(cardinal(Patch.Addr), cardinal(@Patch.Bytes), Patch.NumBytes, CODE_PATCH); на Patcher.Write(cardinal(Patch.Addr), cardinal(@Patch.Bytes), Patch.NumBytes, DATA_PATCH); Это не очевидно, но я объясню почему. Я понимаю что, практически все сочиняемые пачти подразумевают содержание кода. Однако CODE_PATCH в Методе Write означает не то что 'мы пишем код', а то что данные по адресу @Patch.Bytes будут восприниматься как код. Возмем пример из ченджлога к патчеру 2.5. Допустим мы хотим поставить патч 0x639C40: call 0x447799. В бин-файле это будет записано в прямом виде: 0x639C40, 5, E8 54 DB E0 FF после считывания в Patch.Bytes будет E8 54 DB E0 FF но ведь @Patch.Bytes не равен 0x639C40!!! а значит если мы подразумеваем что по адресу @Patch.Bytes код, а не данные, то E8 54 DB E0 FF будет вызывать не 0x447799, а функцию заданную адресом относительным к @Patch.Bytes. Ну вот представь, что мы процессору передали на выполнение адрес @Patch.Bytes: будет вызвана функция не 0x447799, а совершенно левая. *** Еще раз повторю вопрос: что выдает лог патчера? создаем рядом с patcher_x86.dll - patcher_x86.ini c записью Logging = 1 и после установки всех патчей вызываем Patcher::SaveLog(char* file_name). если в логе отсутствуют записи ERROR! Can not create ... at ... (...): Wrong Patcher Instance! то проверка на верный модуль ни при чем, а дело в CODE_PATCH жду ответа. RE: patcher_x86.dll - Berserker - 03.11.2014 20:14 Привет, только прочитал сообщение, отвечу дома. Извини, первые три месяца работы после универа, ещё вхожу в ритм. RE: patcher_x86.dll - Berserker - 03.11.2014 20:21 Если я верно понимаю, при CODE_PATCH патчер считает, что я копирую блок существующего кода, в котором нужно исправить относительные смещения? То есть реальный безопасный патч без обработки — это всегда DATA_PATCH? RE: patcher_x86.dll - baratorch - 03.11.2014 20:22 да, именно так RE: patcher_x86.dll - Berserker - 03.11.2014 22:18 Откатил в Git для тестов до версии с Patcher, поменял на DATA_PATCH, вылеты исчезли. Значит перенесу потом изменения, вопрос решён, спасибо за помощь. RE: patcher_x86.dll - baratorch - 07.11.2014 16:12 версия 2.6 библиотека + SDK + исходники чейнджлог: Code: 2.6 RE: patcher_x86.dll - baratorch - 21.08.2015 11:25 версия 2.8 библиотека + SDK + исходники чейнджлог: Code: 2.8 RE: patcher_x86.dll - Bes - 10.09.2015 20:04 вопрос к Отцам, кто может теперь адаптировать ERA2.47 под новый патчер, ибо сейчас они перестали дружить - новый HD-мод и последняя (2,46 и 2,47) ERA Владыка судя по всему не скоро вернётся к ERA (или никогда ((( ) RE: patcher_x86.dll - gamecreator - 11.09.2015 00:57 Почему это перестали? Они не пересекаются вроде. Может просто wog_patcherizer отвалился, или как там его? |