Форум программистов «Весельчак У»

Направления программирования => Техно => Тема начата: Aether от 04-08-2016 11:39



Название: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 04-08-2016 11:39
Добрый день.

Спрошу, возможно, кто-то уже сталкивался. Для получения списка функций содержащегося в DLL существуют утилиты, например, tiny_impdef, но, как быть, если в DLL содержится COM объект? Естественно, некоторые из функций, явно объявленные в библиотеке, будут являться создателями некоего базового интерфейса, однако, сколько интерфейсов всего? И второе, у интерфейса есть методы - как построить их таблицу? Третье, является ли позиция того или иного метода в vtable статической, или она может "изменяться"?

Какую современную литературу по COM стоит изучить?


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: RXL от 04-08-2016 12:58
Для зарегистрированных в системе компонент можно посмотреть в панели управление/администрирование/компоненты.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 04-08-2016 16:48
Поясню на примере: есть a.dll. Создаю a.def. Внутри оказывается много чего, но меня интересует функция Create_A_interface(...), которая возвращает интерфейс IA. Как я уже понял, интерфейс - это всего лишь указатель на vtable, который является списком указателей на методы данного COM объекта, соответственно, если мне нужен метод IA_start, то мне нужно не просто знать его имя, а знать его позицию в этом vtable. Изучение заголовочных файлов приводит к конструкции вида: STDMETHOD(IA_start)(...), которая как-то не очень понятно разворачивается... В общем, первое, что захотелось осуществить: узнать механизм распознавания методов? Или ситуацию более полно?

И ещё, в параметры Create_A_interface входит GUID - 128 бит идентификатор. Если я буду туда посылать не записанный в a.h, GUID_A, а GUID от IUnknown, то соответственно, должен ли я на выходе получить IUnknown от этого COM объекта? Или это зависит от реализации конкретной функции получения интерфейса?

Извиняюсь за сумбурность, пытаюсь разобраться впервые.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: zubr от 04-08-2016 23:07
Aether, не имея описания методов, по одной длл - тут только реверс поможет. А так, если есть описание, получил интерфейс вызовом Create_A_interface - это и есть адрес vtable. Зная номер нужного метода, исходя из описания умножаешь его на размер указателя (32/64 бита) - получаешь адрес указателя, который содержит адрес метода.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 05-08-2016 05:39
Из описания только заголовочный файл, но он, как понял годится только для MSVC, так как в нём не нахожу явного присваивания методам номеров. Единственное, что есть, конструкции вида:
STDMETHOD ...(QueryInterface)(...)
STDMETHOD ...(Addref)(...)
STDMETHOD ...(Release)(...)
Про эти три прочёл уже, что они идут следом строго в одной последовательности, то есть позиции 0, 1, 2. Предположу, что остальное тоже по списку, и буду пробовать.
Другое дело, каков нормальный путь к распознаванию или какое описание должно поставляться? Иначе как быть, если нет желания пользоваться MSVC или нужно что-то перевести на asm?


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: zubr от 05-08-2016 07:07
В описании, как правило, последовательность методов, соответствует их в vtable.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 06-08-2016 07:54
Да, предположение оказалось правильное: позиции в списке заголовочного файла совпадают с позициями методов в VTable. Вообще очень странная конструкция: для вызова функции необходимо несколько служебных обращений к памяти, и несмотря на работу внутри одного модуля, каждому методу нужно передавать ещё и сам интерфейс. Ладно, главное, что работает. :)


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: zubr от 06-08-2016 20:32
Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 07-08-2016 10:05
Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция.
Если возможно, то на примере. Код приводить не нужно, просто для понимания. На настоящий момент я понимаю так: COM связан с Windows, поэтому внутренняя реализация останется закрытой, по крайней мере, что-то добавить можно лишь там, где это дадут сделать. Второе: как часть DLL редактирование VTable, например, для переадрессации на свою функцию невозможно. Мало того, GUID уникален для каждого интерфейса, и должен оставаться таким. В целом понимаю так: если придерживаться этой концепции, то писать нужно собственный компонент, связывая его известными интерфейсами с другими. Выпуская новую версию компонента, необходимо, присваивать ей новый GUID.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Dale от 07-08-2016 10:41
Когда-то давно, когда еще работал с COM, ответы на все возникающие вопросы находил в этой книге: http://www.softzenware.com/downloads/inside_com.pdf

Полистайте, может, и на Ваши вопросы она ответит.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: zubr от 07-08-2016 12:04
Если возможно, то на примере. Код приводить не нужно, просто для понимания. На настоящий момент я понимаю так: COM связан с Windows, поэтому внутренняя реализация останется закрытой, по крайней мере, что-то добавить можно лишь там, где это дадут сделать. Второе: как часть DLL редактирование VTable, например, для переадрессации на свою функцию невозможно. Мало того, GUID уникален для каждого интерфейса, и должен оставаться таким. В целом понимаю так: если придерживаться этой концепции, то писать нужно собственный компонент, связывая его известными интерфейсами с другими. Выпуская новую версию компонента, необходимо, присваивать ей новый GUID.
К примеру, если надо перехватить события IE, а точнее интерфейса IWebBrowser2, который наследуется от интерфейса IDispath, создается класс наследник IDispath и переопределяется метод Invoke. На низком уровне мы просто получаем адрес этого метода (ведь длл уже загружена в память нашего процесса), и при его выполнении мы получаем нужные параметры, которые уже вставляем в свой метод, к примеру в событие OnDocumentDownload.

И почему невозможна переадресация на свою функцию. Находишь в памяти процесса vtable, а данная таблица содержит указатели на методы, что мешает туда прописать адреса на свои функции? Ну только естественно потом надо будет вернуть управление на оригинальный адрес метода. Я такое как-то реализовывал с DirectShow через инжект, причем с чужим процессом.


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: Aether от 07-08-2016 18:15
И почему невозможна переадресация на свою функцию. Находишь в памяти процесса vtable, а данная таблица содержит указатели на методы, что мешает туда прописать адреса на свои функции?
Я так понимаю, VTable находится в пространстве DLL, и как-то оно должно быть защищено, ведь то, что мы изменим там, измениться и для других задач, её использующих?


Название: Re: Получение списка интерфейсов и их методов в COM
Отправлено: zubr от 08-08-2016 03:55
Никак не защищено, да и никак и не защитишь - вся защита установка флагов не для записи, только ничего не мешает изменить протектшион.
Естественно, если будешь делать хак vtable, то надо предусмотреть, чтобы только в нужных тебе случаях выполнялся подмененный код.

З.Ы. Подмену то надо делать уже в процессе, когда длл загружена туда, а не в самом файле длл, тем более в самом файле это бессмысленно.