Перехват функции в vtable

Тема в разделе "WASM.BEGINNERS", создана пользователем InTRUEdeR, 7 июл 2008.

  1. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    Есть такое дело: нужно перехватить функцию (заменить ее адрес на свой, а потом вызвать оригинальную), расположенную в vtable. Функция эта экспортируется из DLL, которую подгружает "исследуемая" программа. Я написал свою DLL и инжектор. Нужно в моей DLL реализовать перехват, используя функции из приложенного файла.

    Вот кусочек дампа с IDA Pro
    Код (Text):
    1. 0000:100ACA04                          ; Exported entry 672. ??_7CButton@@6B@
    2. 0000:100ACA04                                          public ??_7CButton@@6B@
    3. 0000:100ACA04                          ; const CButton::`vftable'
    4. 0000:100ACA04 D7 92 02 10              ??_7CButton@@6B@ dd offset ?TimerHandler@CControlBase@@UAEXKK_N@Z
    5. 0000:100ACA04                                                                  ; DATA XREF: CButton::CButton(CButton const &)+1Fo
    6. 0000:100ACA04                                                                  ; CButton::CButton(void)+22o ...
    7. 0000:100ACA04                                                                  ; CControlBase::TimerHandler(ulong,ulong,bool)
    8. 0000:100ACA08 1B 33 00 10                              dd offset sub_1000331B
    9. 0000:100ACA0C 6D 83 02 10                              dd offset ?Create@CControlBase@@UAEJJJJJJJ@Z ; CControlBase::Create(long,long,long,long,long,long)
    10. 0000:100ACA10 60 83 02 10                              dd offset ?Create@CControlBase@@UAEJJ@Z ; CControlBase::Create(long)
    11. 0000:100ACA14 25 84 02 10                              dd offset ?Destroy@CControlBase@@UAEJXZ ; CControlBase::Destroy(void)
    12. 0000:100ACA18 73 55 02 10                              dd offset ?Clone@CButton@@UAEPAVCControlBase@@XZ ; CButton::Clone(void)
    Индекс нужной функции мне известен. Я не знаю как до нее добраться из моей длл.
     
  2. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    1. Запустил "исследуемую" программу.
    2. Инжектнул в нее свою длл, которая при загрузке определила хендл длл, у которой находится нужная мне функция.

    нужная мне таблица я так понял находится по смещению 100ACA04 относительно базового адреса длл после ее загрузки, так?
    дальше я делаю так (не работает):
    Код (Text):
    1.     HMODULE hModule;
    2.     PVOID realProcAddress;
    3.     PVOID bytes;
    4.     hModule = GetModuleHandle("Library.dll");
    5.  
    6.     realProcAddress = hModule + 0x100ACA04;
    7.  
    8.     bytes = DetourClassFunc((BYTE *)realProcAddress, (BYTE *)MyFunction, 8);
    здесь по поводу последнего параметра ( = 8 ) не совсем ясно. что он значит я не понял.
    потом я пишу так:
    Код (Text):
    1.     RetourClassFunc((BYTE *)realProcAddress, (BYTE *)bytes, 8);
    Помогите, пожалуйста!
     
  3. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
  4. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    UTeX, если б мне показалось, я б исправил :)
    это я пытался базовый адрес дллки загруженной получить и сместиться к таблице.
    как надо правильно не подскажешь?
     
  5. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
  6. temp666

    temp666 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2007
    Сообщения:
    141
    По моему тут нет универсального способа. Это практически равносильно написанию патча. Я так думаю потому, что видел разные реализации конструкторов обектов.
    И сама структура объекта может быть разная. Даже если ты получиш This то что с ним делать еще большой вопос. Так что изучай как конструктор создает объект, потом добывай указатель на объект и тд.
     
  7. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    вот если б я перехватывал обычную функцию, то сделал бы так:
    hModule = GetModuleHandle("Library.dll");
    realProcAddress = GetProcAddress(hModule, "NameOfFunction");

    а с vtable проблемы :dntknw:
    вот я и думал найти таким способом смещение таблицы относительно базового адреса длл (я понимаю как адрес, по которому загрузилась Library.dll после вызова LoadLibrary). Library.dll - не моя, а подопытная.
     
  8. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    База у Dll всегда разная при загрузки их в память
     
  9. UTeX

    UTeX New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2007
    Сообщения:
    584
    Только обратил внимание
    Так она что экспортируется?
    Тогда какие проблемы?
     
  10. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    проблема в том, что экспортируется например в виде:
    const CButton::'vftable'
    а нужная мне функция имеет вид:
    public __thiscall CButton::CButton(void)
    из-за thiscall прибегнул к DetourClassFunc из приложенного ранее файла. но как с ним надо работать не пойму :dntknw:
     
  11. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    InTRUEdeR
    мне интересна твоя задачка.. перехват я уже делал.. вот перехват писалса для OpenGL and Dx8-9 www.injhdc.fidep.ru есть одна интересная ссылка.. короче пешы.. (просто сам сижу нечем занятса)
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    С DeTour не разбирался, но думаю что 0x100ACA04 в строке:
    Код (Text):
    1. realProcAddress = hModule + 0x100ACA04;
    некорректно, т.к. IDA (адрес, судя по всему взят оттуда) при загрузке DLL сама производит релокацию, т.е. адрес 0x100ACA04 не относительный, а абсолютный. Относительный (вероятно) будет 0xACA04, т.к. база DLL видимо = 0x10000000. +надо учесть, что DLL может быть загружена по другому адресу, если тот, по которому она была слинкована, занят.
     
  13. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    hModule + 0x100ACA04; круто.. только другая машына другой адрес..
     
  14. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    _mikityak_
    задачка будет решена, если я доберусь до нужной мне функции во время выполнения программы, и правильно воспользуюсь функциями из прикрепленного в первом посте файла...
    в ветке http://www.wasm.ru/forum/viewtopic.php?id=24263 написано, как получить смещение к функции по индексу (умножить его на 4). но нужно еще найти смещение внутри длл к этой таблице виртуальных методов во время выполнения.
    Что мне дает адрес 100ACA04 ? Как он видоизменится (и видоизменится ли) при загрузке Dll в память?
     
  15. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    InTRUEdeR
    Если использование DeTour не принципиально, и речь идет о конкретной DLL то можно пойти немного другим путем. Если тебе известен адрес создаваемого объекта и ты знаешь из чего он состоит (можно посмотреть в отладчике/дизассемблере), то можно получить адрес vtable из самого объекта. Обычно (но не факт, что так будет в твоем случае) указатель на vtable идет как самый последний член класса. Соотвественно из адреса объекта можно получить адрес vtable и поправить ее так, как тебе хочется. Можно попробовать совсем извращенный путь: создать объект из DLL, получить адрес vtable и убить объект с помощью деструктора. Правда тут могут быть побочные эффекты в виде появления/исчезновения кнопки, если она создается в конструкторе и уничтожается в деструкторе. И вообще неизвестно, как как это скажется на ресурсах.
     
  16. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    [​IMG] ой я и неподумал.. што версия DLL всегда одна и таже будет.. (можно изварщатса) [​IMG]
     
  17. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    вот круто... читает адрес функции как FFF7368F, ну т.е. адрес то наоборот 8F36F7FF, ну в отладчике тоже такое число есть. именно там где я его ищу. вроде правильно. но при вызове DetourClassFunc в ней не срабатывает функция VirtualProtect, т.к. не может изменять атрибуты участков памяти в диапазоне 0x80000000 - 0xBFFFFFFF. Мое положение безвыходно?
     
  18. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Кто читает? Откуда читает? Зачем читает? Код покажи, в общем.
     
  19. InTRUEdeR

    InTRUEdeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2007
    Сообщения:
    13
    Код (Text):
    1. void *OldFunctionAddress;
    2. HMODULE hModule;
    3.     hModule = GetModuleHandle("Library.dll");
    4.     VTable = (VOID **)((DWORD)hModule + 0xACA08);
    5.     OldFunctionAddress = VTableFunction(VTable,2);
    после этого OldFunctionAddress = FFF7368F, в отладчике по смещению ACA10 (10 = 8 + 2*4) тоже такое показывает. Это я получил адрес метода в тблице виртуальных методов я так понял. Теперь DetourClassFunc (принципиально до сих пор было) не работает. Думаю просто поменять там адрес на свой, и потом вызвать тот что нужно. не знаю правда сработает или нет.

    VTableFunction просто к VTable добавляет 2*4 (не так как в оригинале): return *(void **)((DWORD)VTabEntry + index*4);
     
  20. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    Код покажи[​IMG][​IMG][​IMG]