2014-01-17 3 views
0

Мне удалось зацепить все, что я хотел (функции API, виртуальные методы, «стандартные» функции), но мне интересно, как подключить функцию (тип) класса-класса не-виртуальный. Чтобы подключить виртуальный метод, вам просто нужно получить VTable и исправить его (или скопировать, изменить и сменить VPointer). Однако, когда метод НЕ виртуальный, нет VTable.Hooking non-virtual class member function

Прежде всего, как я могу получить адрес метода Я хочу подключить от своего имени ? Я не могу использовать GetProcAddress(), так как функция не экспортируется. Кажется, что единственный способ поиска байтового шаблона в памяти, соответствующей функции. Затем, как только я получил адрес, как его подключить? Использование базового метода (JMP)? Что делать, если я хочу подключить только один экземпляр? Я думаю, что я проверю свою функцию подключения: если это правильный экземпляр, тогда сделайте то, что нужно сделать, иначе просто выполните его, не делая ничего другого.

На самом деле я ищу лучшие решения, потому что я думаю, что те, что были выше, будут работать, но они не очень «аккуратные», не так ли?

спасибо.

+0

Я не знаю много о 'WinAPI', но вы можете взять адрес члена-функции с помощью' & ИмяКласса :: member_name' синтаксис. – pmr

+0

Предположим, что 'ClassName' не является частью библиотеки, которую я могу включить # в моей DLL (которую я хочу добавить), но вместо этого это класс, определенный в программе, которую я хочу подключить: я не могу написать' & ClassName: member_name' в моей DLL, я получу ошибку компиляции. – GuiTeK

ответ

1

В большинстве случаев просто невозможно отменить функцию статического разрешения. Вы когда-нибудь слышали об этой оптимизации под названием inlining? Даже когда этого не происходит, COMDAT-фальцовка может сделать выделение вашей интересующей функции совершенно невозможной.

Настоятельно рекомендуется чтение: Raymond Chen's "Why does the debugger show me the wrong function?"

+0

Что вы подразумеваете под «статически разрешенной функцией»? Да, я забыл о встраивании ... вы правы, это может быть проблематично. Что касается COMDAT-folding, скажем, функция ссылается в программе, поэтому он не был удален компоновщиком (я бы не зацепил функцию, которая не используется?). Тогда как бы вы перешли к этой функции, если она не была встроена? – GuiTeK

+1

@GuiTeK: Статически разрешенный означает, что компилятор решает (разрешает) именно то, что функция вызывается во время компиляции. Сюда входят все вызовы, которые вы назвали не виртуальной функцией. Виртуальные функции и вызовы с помощью указателей функций могут быть статически разрешены или динамически разрешены в зависимости от того, сможет ли компилятор определить точный тип. –

+1

Кроме того, с помощью COMDAT-folding я имею в виду функции, содержащие идентичные инструкции (которые чаще встречаются на C++, чем вы сначала думали, например, все геттеры, которые читают и возвращают целое число, хранящее 8 байтов в объект, имеют тенденцию производить то же самое машинный код, независимо от фактического типа объекта), то эти функции отображаются в одно и то же место в исполняемом файле. См. Http://stackoverflow.com/questions/15168924/gcc-clang-merging-functions-with-identical-instructions-comdat-folding. Затем рассмотрим проблему замены одной из функций, совместно использующих одну реализацию. –