Current time: 23.11.2024, 02:58 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
patcher_x86.dll
» версия 2.8
Author Message
baratorch Offline

Posts: 197
Post: #1

Дабы облегчить жизнь себе и потенциально другим мододелам,
а также в целях повышения совместимости независимых разработок
состряпал полезную штуку
перевел на нее ХД 3
и переводится на нее ХотA

готова версия 2.8:
библиотека + SDK + исходники


изменения:
Code:
Изменения нарушающие обратную совместимость: [!]
Исправления багов: [-]
Расширение функциональности: [+]
Несущественные изменения/комментарии: [*]

2.8

[-] теперь EXTENDED_ и SAFE_ HiHook хуки могут быть установлены на рекурсивно выполняемый код.



2.7

[+] patcher_x86 теперь полностью совместим с DEP (Предотвращением выполнения данных)



2.6

[+] Добавлен метод PatcherInstance::BlockAllExceptVA(_ptr_* va_args)
    блокирует для данного  PatcherInstance установку патчей для всех адресов кроме указанных.
      Добавлен метод Patcher::PreCreateInstance(char* name)
    нужен для применения методов PatcherInstance::BlockAt и PatcherInstance::BlockAllExceptVA
     до того как PatcherInstance будет полноценно создан с помощью Patcher::CreateInstance
[-] Исправлена возможность краша на старте из-за DEP.



2.5

[+] Функциии PatcherInstance::CreateCodePatch и PatcherInstance::WriteCodePatch
    теперь умеют корректно воспринимать записанные прямо опкоды с относительной адресацией.
    Например 0x639C40: call 0x447799 раньше можно было записать только в виде
    WriteCodePatch(0x639C40, "c%", 0x447799); или
    WriteCodePatch(0x639C40, "E8 ~d", 0x447799);
    (+ еще можно: WriteDataPatch(0x639C40, "E8  54 DB E0 FF");  чего, в принципе, было достаточно)
    Теперь можно и прямо WriteCodePatch(0x639C40, "E8  54 DB E0 FF") ;  (т.е. теперь можно просто скопировать патч с OllyDbg и не париться с преобразованием)
    


2.4

[-] баг: установка LoHook на длинную последвательность NOP'ов приводила к ошибкам.



2.3

[+] добавлены функции
    Patcher::VarInit
    Patcher::VarFind
    и тип Variable для работы с общими "переменными" для всех текущих клиентов patcher_x86.dll
[+] функция SaveDump сохраняет в файл после списка всех установленных патчей список всех "переменных" с их текущими значениями.


2.2

[-] LoHook не сохранял регистр флагов


2.1

[-] чтение/изменение esp регистра в LoHook хуке работало неверно

[+] добавлены функции
    PatcherInstance::WriteHexHook
    PatcherInstance::CreateHexHook
    
    эти функции позволяют установить самый примитивный хук
    а именно LoHook без высокоуровневой оболочки-функции.
    тело хука пишется прямо в вызове WriteHexHook или CreateHexHook
    таким же образом как пишется патч с помощью WriteCodePatch или CreateCodePatch

[+] В любом LoHook хуке теперь доступен для чтения/изменения регистр флагов процессора (расширена структура HookContext)

[+] LoHook теперь хранит экземляр HookContext в стеке, а не по фиксированному адресу, что позволяет корректно рекурсивно выполнять LoHook хук.

[+] теперь внутри функции сработавшей по LoHook хуку можно использовать операции с помещением данных в стэк контекста хука, аналогичные команде процессора PUSH.
    размер памяти, доступной для такого помещения в стэк контекста ограничен 128 байтами для хука, созданного с помощью методов PatcherInstance::WriteLoHook и PatcherInstance::CreateLoHook, и произволен для хука, установленного с помощью новых методов
    PatcherInstance::WriteLoHookEx
    PatcherInstance::CreateLoHookEx.

[+] добавлена функция:
    PatcherInstance::BlockAt
    которая запрещает данному экземпляру PatcherInstance устанавливать по заданному адресу патчи/хуки

[+] добавлены функции
    HiHook::SetUserData
    HiHook::GetUserData

[+] расширен функционал PatcherInstance::WriteDataPatch и PatcherInstance::CreateDataPatch
    - добавлен формат символ %s (string) - копирует си-строку из аргумента


1.7

[+] для HiHook добавлен новый subtype: SAFE_ = 2
    - то же самое что и EXTENDED_, однако перед вызовом GetDefaultFunc() восстанавливаются (только на время вызова)
    значения регистров процессора EAX, ECX (если не FASTCALL_ и не THISCALL_),
    EDX (если не FASTCALL_), EBX, ESI, EDI, бывшие на момент вызова замещенной функции

1.6

[+] Добавлены функции:

    PatcherInstance::Write
    PatcherInstance::CreatePatch

    (см. SDK)

1.5

[-] критический баг при попытке поставить CALL_ HiHook на неверный опкод при выключенном логировании


1.4

[-] баг из-за которого невозможно было использовать FUNCPTR_ EXTENDED_ HiHook


1.3

[-] Исправлены ошибки:
    - отмена хуков во время выполнения их хук-функций приводила к непредвиденным результатам
    - неверно работал формат-символ %a в функции Patcher::WriteComplexData

[+] Функция Patcher::CreateInstance теперь, принимая в качестве аргумента нулевую и пустую строки,
    создает PatcherInstance с именем модуля вызвавшего функцию.

[+] Функции Patcher::GetInstance можно передавать в качестве аргумента не только
    уникальое имя PatcherInstance, но так же имя модуля, создавшего PatcherInstance.
    Однако, имейте ввиду что в одном модуле можно создать несколько экземпляров PatcherInstance,
    в этом случае Patcher::GetInstance с именем модуля в качестве аргумента будет
    возвращать первый созданный PatcherInstance в этом модуле.

[!] Теперь невозможно создавать патчи посредством экземпляра PatcherInstance созданным не в вашем модуле.
    Возможность отменять и применять эти патчи сохранена.

[!] Функция Patch::Apply() теперь возвращает индекс (c 0) патча/хука в последовательности примененных патчей по данному адресу
    в случае успеха, -2 если патч/хук уже применен и -1 в случае неуспеха из-за неведомой хрени.

[!] Функция Patcher::DestroyAllAt заменена на Patcher::UndoAllAt

[*] Функции
    PatcherInstance::WriteComplexPatch
    PatcherInstance::CreateComplexPatch
    переименованы в
    PatcherInstance::WriteCodePatch
    PatcherInstance::CreateCodePatch
    для лучшего отражения сути их работы

[!] Теперь все патчи разделены на 2 типа: DATA_ и CODE_
    DATA_ патчи устанавливаются посредством простого копирования памяти
    CODE_ - посредством MemCopyCode
    произвольно выбрать тип патча нельзя, он устанавливается автоматически.
    DATA_ : BytePatch, WordPatch, DwordPatch, HexPatch, FUNCPTR_ HiHook, DataPatch
    CODE_:  JmpPatch, CodePatch (бывший ComplexPatch), LoHook, CALL_ и SPLICE_ HiHook
    ОЧЕНЬ ВАЖНО понимать разницу!

[+] Добавлены/реализованы функции:

    Patch::ApplyInsert

    PatcherInstance::WriteDataPatch
    PatcherInstance::CreateDataPatch
      PatcherInstance::GetLastPatchAt,
    PatcherInstance::UndoAllAt,
    PatcherInstance::GetFirstPatchAt.

    Patcher::GetFirstPatchAt,
    Patcher::MemCopyCodeEx,


[!] Теперь невозможно уничтожить неотмененный Хук (т.е. чтобы уничтожить, нужно сначала отменить).
[!] Возможность корректно уничтожить хук во время выполнения хук-функции ликвидированна
    (из-за бага ее и так не было, но теперь ее нет официально)

[*] Теперь Хук любого типа можно безопасно отменить в любой момент во время выполнения
    его хук-функции (соответственно исключая т.н. FIXED хуки, которые вообще нельзя отменить).
    Хук отменяется сразу (т.н. понятие отложенной отмены теперь неактуально).

[+] Функция Patcher::MemCopyCode теперь помимо CALL (E8) и JMP (E9) опкодов корректно копирует
    опкоды 0F 80 - 0F 8F (длинные условные прыжки);
[!] теперь в функции Patcher::MemCopyCode переходы E8, E9, 0F 80 - 0F 8F трансформируются
    только если направляют за границы копируемого блока.

[!] Функция Patcher::MemCopyCode теперь копирует всегда целое количество опкодов.
    (т.е. размер скопированного блока кода теперь >= size (был строго = size, т.е последний опкод мог быть обрезан).

[*] Функция Patcher::MemCopyCodeEx отличается от Patcher::MemCopyCode тем что если
    в копируемом блоке короткие прыжки EB, 70 - 7F направляют за границы копируемого блока,
    то они замняются на соответсвующие длинные прыжки (E9, 0F 80 - 0F 8F)

[*] Таким образом, теперь появилась возможность устанавливать SPLICE_ хуки и низкоуровневые хуки на код,
    содержащий любые корткие и длинные относительные переходы.
    А еще очевидна возможность скопировать целую функцию или ее часть от начала
    и вызывать копию как оригинал.

[+] Низкоуровневый хук теперь не сбивает содержимое регистров флагов, соответственно его
    теперь можно ставить на любой код в функции.

[!] Jmp патч, созданный посредством PatcherInstance::CreateJmpPatch и PatcherInstance::WriteJmp
    теперь закрывает целое количество опкодов, т.е. размер патча теперь >= 5 (был строго = 5),
    разница заполнятеся NOP'ами.

[+][!] Расширена функциональность Patcher::WriteComplexData, PatcherInstance::WriteCodePatch и PatcherInstance::CreateCodePatch
    - добавлена возможность ставить метки (до 10) и осуществлять переход к ним
      с помощью всех длинных и коротких относительных переходов (E8, E9, 0F 80 - 0F 8F, EB, 70 - 7F)
      (формат символы #0: , #1: , ... , #9: и #0 , #1 , ... , #9)
    - добавлен формат символ ~b - берет из аргументов абсолютный адрес и
      пишет относительное смещение до него размером в 1 байт для опкодов EB, 70 - 7F
    - добавлен формат символ ~d - берет из аргументов абсолютный адрес и
      пишет относительное смещение до него размером в 4 байта для опкодов E8, E9, 0F 80 - 0F 8F
    - добавлен формат символ %o (offset) - помещает по адресу из аргумента смещение позиции в Complex коде,
      относительно начала Complex кода.
    - добавлен формат символ %n (nop) - пишет nop опкоды, количеством указанным в аргументе
    - формат символ %m теперь копирует посредством MemCopyCodeEx а не MemCopyCode,
      то есть размер скопированного кода может оказаться больше копируемого
      из-за трансформации коротких прыжков в длинные.
    - формат символы %a и %h будут оставлены для обратной совместимости, но упоминания о них будут убраны из SDK;
      вместо этих символов рекомендуется использовать %o и %%

Code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ОПИСАНИЕ.
//
// ! библиотека предоставляет:
//        - удобные унифицированные централизованные
//          инструменты для установки патчей и хуков
//          в код целевой программы.
//        - дополнительные инструменты: дизассемблер длин опкодов и функцию
//          копирующую код с корректным переносом опкодов jmp и call c
//          относительной адресацией
// ! библиотека позволяет
//        - устанавливать как простые так и сложные патчи.
//          с методами по установке сложных патчей почти так же удобно работать
//          как с ассемблером (пока не хватает только меток и прыжкам к меткам)
//        - устанавливать высокоуровневые хуки, замещая оригинальные функции в
//          в целевом коде на свои, не заботясь о регистрах процессора,
//          стеке, и возврате в оригинальный код.
//        - устанавливать высокоуровневые хуки один на другой
//          не исключая а дополняя при этом функциональность хуков
//          установленных раньше последнего, тем самым реализуется идеология сабклассинга
//        - устанавливать низкоуровневые хуки с высокоуровневым доступом к
//          регистрам процессора, затертому коду и адресу возврата в код
//        - отменять любой патч и хук, установленный с помощью этой библиотеки.
//        - узнать задействован ли определенный мод, использующий библиотеку
//        - узнать какой мод (использующий библиотеку) установил определенный патч/хук
//        - получить полный доступ ко всем патчам/хукам, установленным из других модов
//          с помощью этой библиотеки
//        - легко и быстро обнаружить конфликтующие патчи из разных модов
//          (использующих эту библиотеку) 1) отмечаяв логе такие конфликты как:
//                                - устанавливаются патчи/хуки разного размера на один адрес
//                                - устанавливаются патчи/хуки перекрывающие один другого со смещением
//                                - устанавливаются патчи поверх хуков и наоборот
//          а так же 2) давая возможность посмотреть дамп (общий листинг) всех патчей
//          и хуков установленных с помощью этой библиотеки в конкретный момент времени и лог использования библиотеки.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
(This post was last modified: 21.08.2015 11:23 by baratorch.)
11.02.2012 13:20
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #2

Хорошая работа, будет интересно глянуть. Я, кстати, для дизассемблирования взял готовую компактную (600 байт) Hacker Disassembler Engine (hde32), правда использовал только для определения минимального безопасного размера перехвата (5 байт и более).


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

Posts: 33
Post: #3

baratorch' Wrote:Сейчас идет тестирование и готов SDK для Cи

А эта штука будет в билдере компилиться?

А то SDK Berserker'а для GNU C++ билдер не понимает, а как это исправить - придумать не получается.
11.02.2012 22:59
Find all posts by this user Quote this message in a reply
baratorch Offline

Posts: 197
Post: #4

должна компилиться везде )

SDK для C++ представляет 1 хидер-файл, в котором объявлены нужные структуры и интерфейсы, сама библиотека экспортирует всего 1 функцию

итак версия 0.1
http://sites.google.com/site/heroes3hd/f...ects=0&d=1

в архиве:
длл : patcher_x86.dll
и SDK С++:
patcher_x86.h - хидер совсем без комментариев (выглядит не таким страшным и большим как комментированный)
patcher_x86_commented.h - тот же хидер с ооччень подробными комментариями
13.02.2012 18:42
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #5

Тогда уж либо хэдер, либо заголовочный файл )


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

Posts: 197
Post: #6

ну простите )
13.02.2012 21:36
Find all posts by this user Quote this message in a reply
kostya_76 Offline

Posts: 33
Post: #7

(13.02.2012 18:42)baratorch Wrote:  patcher_x86_commented.h - тот же хидер с ооччень подробными комментариями

   Не хватает примера создания хука. Ab
13.02.2012 21:42
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #8

Кстати, из-за ООП и fastcall вызовов переходник SDK на Object Pascal или C вряд ли возможен.


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

Posts: 197
Post: #9

ну fastcall я запросто переделаю в stdcall
а для си, если заморочиться, можно написать SDK
   объявив таблицу виртуальных методов в структурах
   и описать функции через эту таблицу

Quote:Не хватает примера создания хука.

Я ж написал в 1 посте, примеры - будут. позже
(This post was last modified: 13.02.2012 22:59 by baratorch.)
13.02.2012 22:56
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #10

Кстати, а почему бы автора патча не определять автоматически по адресу возврата? VirtualQuery на адрес, получить базовый адрес, GetModuleFileName на него?


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

Posts: 197
Post: #11

хорошая идея, воспользуюсь ей позже

версия 0.2
http://sites.google.com/site/heroes3hd/f...ects=0&d=1

переделал функцию выполняющуюся при срабатывании LoHook хука из __fastcall в __stdcall
скорректировал SDK для C++
написал SDK для С и для Delphi, но комментарии пока есть только для С++

коментарии к C и Делфи а так же примеры для C++, C, Делфи будут позже
15.02.2012 13:53
Find all posts by this user Quote this message in a reply
baratorch Offline

Posts: 197
Post: #12

итак версия 1.0:
http://sites.google.com/site/heroes3hd/f...ects=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 будут работать корректно с более новыми версиями
(This post was last modified: 17.02.2012 02:18 by baratorch.)
17.02.2012 02:15
Find all posts by this user Quote this message in a reply
baratorch Offline

Posts: 197
Post: #13

готова версия 1.1:
http://sites.google.com/site/heroes3hd/f...ects=0&d=1
[*] сильно смягчены правила установки патчей, теперь все конфликтные патчи применяются, WARNING сообщение о конфликте пишется в лог.
[*] логирование по умолчанию теперь отключено, чтобы включить его, необходимо в той же папке создать файл patcher_x86.ini c единственной записью: Logging On = 1 (Logging On = 0 - отключает логирование)
[*] исправлены ошибки в библиотеке и файлах SDK
[*] скорректированы описания-коментарии в SDK
[*] изменена форма записей в дампе и в логе
(This post was last modified: 20.02.2012 08:50 by baratorch.)
20.02.2012 08:49
Find all posts by this user Quote this message in a reply
baratorch Offline

Posts: 197
Post: #14

готова версия 1.2:
http://sites.google.com/site/heroes3hd/f...ects=0&d=1
исправил ошибки
убрал _HD3_.dll из сборки, т.к. выпускаю HD 3.0 beta 8 (на базе patcher_x86 1.2)
28.02.2012 09:38
Find all posts by this user Quote this message in a reply
Sav Offline

Posts: 2180
Post: #15

Похоже, высокоуровневый хук CALL_, EXTENDED_, FASTCALL_ для функции с одним аргументом работает неправильно. При каждом вызове он уменьшает ESP на 4. Если заменить на THISCALL_, то всё нормально.
(This post was last modified: 18.03.2012 20:34 by Sav.)
18.03.2012 19: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