Есть такое дело: нужно перехватить функцию (заменить ее адрес на свой, а потом вызвать оригинальную), расположенную в vtable. Функция эта экспортируется из DLL, которую подгружает "исследуемая" программа. Я написал свою DLL и инжектор. Нужно в моей DLL реализовать перехват, используя функции из приложенного файла. Вот кусочек дампа с IDA Pro Code (Text): 0000:100ACA04 ; Exported entry 672. ??_7CButton@@6B@ 0000:100ACA04 public ??_7CButton@@6B@ 0000:100ACA04 ; const CButton::`vftable' 0000:100ACA04 D7 92 02 10 ??_7CButton@@6B@ dd offset ?TimerHandler@CControlBase@@UAEXKK_N@Z 0000:100ACA04 ; DATA XREF: CButton::CButton(CButton const &)+1Fo 0000:100ACA04 ; CButton::CButton(void)+22o ... 0000:100ACA04 ; CControlBase::TimerHandler(ulong,ulong,bool) 0000:100ACA08 1B 33 00 10 dd offset sub_1000331B 0000:100ACA0C 6D 83 02 10 dd offset ?Create@CControlBase@@UAEJJJJJJJ@Z ; CControlBase::Create(long,long,long,long,long,long) 0000:100ACA10 60 83 02 10 dd offset ?Create@CControlBase@@UAEJJ@Z ; CControlBase::Create(long) 0000:100ACA14 25 84 02 10 dd offset ?Destroy@CControlBase@@UAEJXZ ; CControlBase::Destroy(void) 0000:100ACA18 73 55 02 10 dd offset ?Clone@CButton@@UAEPAVCControlBase@@XZ ; CButton::Clone(void) Индекс нужной функции мне известен. Я не знаю как до нее добраться из моей длл.
1. Запустил "исследуемую" программу. 2. Инжектнул в нее свою длл, которая при загрузке определила хендл длл, у которой находится нужная мне функция. нужная мне таблица я так понял находится по смещению 100ACA04 относительно базового адреса длл после ее загрузки, так? дальше я делаю так (не работает): Code (Text): HMODULE hModule; PVOID realProcAddress; PVOID bytes; hModule = GetModuleHandle("Library.dll"); realProcAddress = hModule + 0x100ACA04; bytes = DetourClassFunc((BYTE *)realProcAddress, (BYTE *)MyFunction, 8); здесь по поводу последнего параметра ( = 8 ) не совсем ясно. что он значит я не понял. потом я пишу так: Code (Text): RetourClassFunc((BYTE *)realProcAddress, (BYTE *)bytes, 8); Помогите, пожалуйста!
UTeX, если б мне показалось, я б исправил это я пытался базовый адрес дллки загруженной получить и сместиться к таблице. как надо правильно не подскажешь?
По моему тут нет универсального способа. Это практически равносильно написанию патча. Я так думаю потому, что видел разные реализации конструкторов обектов. И сама структура объекта может быть разная. Даже если ты получиш This то что с ним делать еще большой вопос. Так что изучай как конструктор создает объект, потом добывай указатель на объект и тд.
вот если б я перехватывал обычную функцию, то сделал бы так: hModule = GetModuleHandle("Library.dll"); realProcAddress = GetProcAddress(hModule, "NameOfFunction"); а с vtable проблемы вот я и думал найти таким способом смещение таблицы относительно базового адреса длл (я понимаю как адрес, по которому загрузилась Library.dll после вызова LoadLibrary). Library.dll - не моя, а подопытная.
проблема в том, что экспортируется например в виде: const CButton::'vftable' а нужная мне функция имеет вид: public __thiscall CButton::CButton(void) из-за thiscall прибегнул к DetourClassFunc из приложенного ранее файла. но как с ним надо работать не пойму
InTRUEdeR мне интересна твоя задачка.. перехват я уже делал.. вот перехват писалса для OpenGL and Dx8-9 www.injhdc.fidep.ru есть одна интересная ссылка.. короче пешы.. (просто сам сижу нечем занятса)
С DeTour не разбирался, но думаю что 0x100ACA04 в строке: Code (Text): realProcAddress = hModule + 0x100ACA04; некорректно, т.к. IDA (адрес, судя по всему взят оттуда) при загрузке DLL сама производит релокацию, т.е. адрес 0x100ACA04 не относительный, а абсолютный. Относительный (вероятно) будет 0xACA04, т.к. база DLL видимо = 0x10000000. +надо учесть, что DLL может быть загружена по другому адресу, если тот, по которому она была слинкована, занят.
_mikityak_ задачка будет решена, если я доберусь до нужной мне функции во время выполнения программы, и правильно воспользуюсь функциями из прикрепленного в первом посте файла... в ветке http://www.wasm.ru/forum/viewtopic.php?id=24263 написано, как получить смещение к функции по индексу (умножить его на 4). но нужно еще найти смещение внутри длл к этой таблице виртуальных методов во время выполнения. Что мне дает адрес 100ACA04 ? Как он видоизменится (и видоизменится ли) при загрузке Dll в память?
InTRUEdeR Если использование DeTour не принципиально, и речь идет о конкретной DLL то можно пойти немного другим путем. Если тебе известен адрес создаваемого объекта и ты знаешь из чего он состоит (можно посмотреть в отладчике/дизассемблере), то можно получить адрес vtable из самого объекта. Обычно (но не факт, что так будет в твоем случае) указатель на vtable идет как самый последний член класса. Соотвественно из адреса объекта можно получить адрес vtable и поправить ее так, как тебе хочется. Можно попробовать совсем извращенный путь: создать объект из DLL, получить адрес vtable и убить объект с помощью деструктора. Правда тут могут быть побочные эффекты в виде появления/исчезновения кнопки, если она создается в конструкторе и уничтожается в деструкторе. И вообще неизвестно, как как это скажется на ресурсах.
вот круто... читает адрес функции как FFF7368F, ну т.е. адрес то наоборот 8F36F7FF, ну в отладчике тоже такое число есть. именно там где я его ищу. вроде правильно. но при вызове DetourClassFunc в ней не срабатывает функция VirtualProtect, т.к. не может изменять атрибуты участков памяти в диапазоне 0x80000000 - 0xBFFFFFFF. Мое положение безвыходно?
Code (Text): void *OldFunctionAddress; HMODULE hModule; hModule = GetModuleHandle("Library.dll"); VTable = (VOID **)((DWORD)hModule + 0xACA08); OldFunctionAddress = VTableFunction(VTable,2); после этого OldFunctionAddress = FFF7368F, в отладчике по смещению ACA10 (10 = 8 + 2*4) тоже такое показывает. Это я получил адрес метода в тблице виртуальных методов я так понял. Теперь DetourClassFunc (принципиально до сих пор было) не работает. Думаю просто поменять там адрес на свой, и потом вызвать тот что нужно. не знаю правда сработает или нет. VTableFunction просто к VTable добавляет 2*4 (не так как в оригинале): return *(void **)((DWORD)VTabEntry + index*4);