2012-05-03 4 views
1

Я недавно работал над функциями объединия (только в Linux), и до сих пор я имел большой успех. Я разрабатывал свой собственный класс объездов, пока не нашел this. Я немного модернизировал код и преобразовал его в C++ (как класс курса). Этот код, как и любая другая реализация объединителя, заменяет исходный адрес функции на JMP на мою собственную функцию «hook». Он также создает «батут» для исходной функции.Захват и использование _thiscall как крюка (соглашение о вызове GCC)

Все работает безупречно, но я хотел бы сделать одно простое регулирование. Я программирую в чистом C++, я не использую глобальных функций, и все заключено в классы (как Java/C#). Проблема в том, что этот метод обхода разрывает мой шаблон. Функция «hook» нуждается в как статическую/неклассовую функцию.

Что я хочу сделать, это реализовать поддержку _thiscall hooks (что должно быть довольно простым с помощью соглашения GCC _thiscall). Мне не удалось изменить этот код для работы с перехватами _thiscall. То, что я хочу в качестве конечного результата, является таким же простым, как это; PatchAddress(void * target, void * hook, void * class);. Я не прошу кого-либо сделать это для меня, но я хотел бы знать, как решить/подойти к моей проблеме?

Из того, что я знаю, мне нужно только увеличить размер «патча» (т. Е. Теперь это 5 байт, и мне потребуются дополнительные 5 байтов?), А затем, прежде чем я буду использовать вызов JMP (к моему крюку function), я нажимаю свой «этот» указатель на стек (который должен быть так, как если бы я назвал его как функцию-член). Для иллюстрации:

push 'my class pointer' 
jmp <my hook function> 

Вместо того, чтобы иметь прямой вызов «jmp» напрямую/только. Это правильный подход или есть что-то еще под этим, которое необходимо учитывать (примечание: мне не нужна поддержка VC++ _thiscall)?

ПРИМЕЧАНИЕ: вот моя реализация указанного выше кода: header: source использует libudis86

+0

Вы называете «чистый C++» спорным. Закрытие всего в классах не имеет смысла в C++. Pure C++ использует модули правильно. –

+0

@ KonradRudolph Мне напомнил старый лозунг «C++ для написания лучшего C», но замените C на Java. :) Но я одобряю вопрос (pl1) – Orwellophile

ответ

1

Я попробовал несколько различных способов, и среди них были JIT компиляции (с помощью libjit), который оказался успешным, но метод не предусматривает достаточная производительность для его использования. Вместо этого я обратился к libffi, который используется для динамического вызова функций во время выполнения. Библиотека libffi имела API-интерфейс закрытия (ffi_prep_closure_loc), который позволял мне указывать мой «этот» указатель на каждое созданное закрытие. Поэтому я использовал статическую функцию обратного вызова и преобразовал указатель void в мой тип объекта, и оттуда я мог бы назвать любую нестационарную функцию, которую я хотел!

+0

Превосходно, я просто попытался автоматизировать генерацию 70 крючков (я подключил функцию регистрации обратного вызова), используя закрытие лямбда, но мне сказали, что это не сработает. Мой следующий шаг был libjit тоже, но я увижу, поможет ли ваше решение. Мы не используем классы для наших крючков, но мы используем пространство имен, чтобы сохранить его полуорганизованным, идея иметь вас на крючках как классы является абсолютной безумием (это то, что я сказал бы, если бы вы этого не сделали Работа). – Orwellophile

Смежные вопросы