Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Получение списка интерфейсов и их методов в COM  (Прочитано 124213 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 04-08-2016 11:39 » 

Добрый день.

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

Какую современную литературу по COM стоит изучить?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-08-2016 12:58 » 

Для зарегистрированных в системе компонент можно посмотреть в панели управление/администрирование/компоненты.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 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 объекта? Или это зависит от реализации конкретной функции получения интерфейса?

Извиняюсь за сумбурность, пытаюсь разобраться впервые.
Записан
zubr
Гость
« Ответ #3 : 04-08-2016 23:07 » 

Aether, не имея описания методов, по одной длл - тут только реверс поможет. А так, если есть описание, получил интерфейс вызовом Create_A_interface - это и есть адрес vtable. Зная номер нужного метода, исходя из описания умножаешь его на размер указателя (32/64 бита) - получаешь адрес указателя, который содержит адрес метода.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 05-08-2016 05:39 » 

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

В описании, как правило, последовательность методов, соответствует их в vtable.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 06-08-2016 07:54 » 

Да, предположение оказалось правильное: позиции в списке заголовочного файла совпадают с позициями методов в VTable. Вообще очень странная конструкция: для вызова функции необходимо несколько служебных обращений к памяти, и несмотря на работу внутри одного модуля, каждому методу нужно передавать ещё и сам интерфейс. Ладно, главное, что работает. Улыбаюсь
Записан
zubr
Гость
« Ответ #7 : 06-08-2016 20:32 » 

Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 07-08-2016 10:05 » 

Фишка в том, что у com-интерфейса могут быть абстрактные методы, которые ты можешь реализовать сам - отсюда и такая конструкция.
Если возможно, то на примере. Код приводить не нужно, просто для понимания. На настоящий момент я понимаю так: COM связан с Windows, поэтому внутренняя реализация останется закрытой, по крайней мере, что-то добавить можно лишь там, где это дадут сделать. Второе: как часть DLL редактирование VTable, например, для переадрессации на свою функцию невозможно. Мало того, GUID уникален для каждого интерфейса, и должен оставаться таким. В целом понимаю так: если придерживаться этой концепции, то писать нужно собственный компонент, связывая его известными интерфейсами с другими. Выпуская новую версию компонента, необходимо, присваивать ей новый GUID.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 07-08-2016 10:41 » 

Когда-то давно, когда еще работал с COM, ответы на все возникающие вопросы находил в этой книге: http://www.softzenware.com/downloads/inside_com.pdf

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

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

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
zubr
Гость
« Ответ #10 : 07-08-2016 12:04 » 

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

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

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 07-08-2016 18:15 » 

И почему невозможна переадресация на свою функцию. Находишь в памяти процесса vtable, а данная таблица содержит указатели на методы, что мешает туда прописать адреса на свои функции?
Я так понимаю, VTable находится в пространстве DLL, и как-то оно должно быть защищено, ведь то, что мы изменим там, измениться и для других задач, её использующих?
Записан
zubr
Гость
« Ответ #12 : 08-08-2016 03:55 » new

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

З.Ы. Подмену то надо делать уже в процессе, когда длл загружена туда, а не в самом файле длл, тем более в самом файле это бессмысленно.
« Последнее редактирование: 08-08-2016 03:57 от zubr » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines