Как получить имя функции по адресу функции, прочитав vtable co-classss?

Мне нужно вызвать функцию сокласса, прочитав ее адрес из vtable методов интерфейса COM. Мне нужен общий способ чтения адресов.

Теперь мне нужно вызвать функцию, у которой будут конкретные адресные (НЕ ИЗВЕСТНЫЕ) аргументы (параметры), которые я собрал из TLB, а также имя. Как этот адрес соответствует имени той функции, которую я собираюсь вызвать.

Для этого мне нужно пройти по vtable, которая содержит функциональные адреса, НАСТОЯЩИМ необходимо сопоставить адрес функции с ИМЯ этой функции. Это я не знаю. Как? Более одной функции с тем же именем может появиться в vtable (случай перегрузки). В этом случае нам нужно различать имена функций и их адреса. Как справиться? С уважением Усмань


С уважением, сэр !!

Я разрабатываю структуру модульного тестирования, для которой мне нужно вытащить все сигнатуры функций определенных COM Exe или COM DLL для отображения в сетке или другом интерфейсе для пользователя, чтобы позже, выбрав определенную сигнатуру функции из этого списка, он / она может выполнить эту функцию после предоставления аргументов (данных в качестве параметров) этой функции. Все это будет происходить динамически во время выполнения, во время выполнения функция будет вызываться как угодно пользователю.

Этого можно добиться разными способами.

Предоставляя TLB (библиотеки типов), мы можем извлекать каждую сигнатуру функции и отображать каждую сигнатуру для элемента управления Grid или элемента управления Tree. Второй шаг - вызвать эти функции во время выполнения, предоставив данные. Для вызова требуются данные и адрес функций (или имена). У меня была бы панель или элемент управления с графическим интерфейсом, который будет принимать данные от пользователя, и эти данные затем станут аргументами.

Теперь возникает настоящая проблема, о которой я писал ранее. Вызов функций / методов этого интерфейса, предоставляемых компонентом COM, реализованным совместным классом. Это требует отслеживания vtable интерфейса, предоставляемого компонентом, нахождения адреса этой функции, а затем необходимо знать, ДЕЙСТВИТЕЛЬНО ЛИ ЭТО АДРЕС, НА КОТОРОЙ Я СОБИРАЮСЬ ВЫЗВАТЬ В КАЧЕСТВЕ ФУНКЦИИ? Таким образом, для этого необходимо преобразовать этот адрес в имя функции, а затем сравнить какое-то сравнение строк, чтобы решить, действительно ли это имя функции, которое ПОЛЬЗОВАТЕЛЬ НАЖИЛ из Tree Control, показывая подписи.

Предложения или рекомендации?


person Usman    schedule 12.03.2010    source источник
comment
Хм, может не стоило удалять свой пост. Похоже, вы действительно изучали этот предмет. Просто комментарий, я не жду голосования, слоты vtable назначаются в интерфейсе и порядке объявления методов, библиотека типов имеет тот же порядок. 3 метода IUnknown всегда являются первыми.   -  person Hans Passant    schedule 12.03.2010
comment
но библиотека типов не даст нам адресов функций. Мы пройдем по vtable для поиска адреса функции и воспользуемся библиотекой типов для имен этих методов. НО настоящая проблема в том, как МЫ МОЖЕМ ПЕРЕВЕСТИ ЭТИ ФУНКЦИОНАЛЬНЫЕ АДРЕСА НА ИХ ИМЕНА? Возможно, в интерфейсе есть несколько методов с одним и тем же именем (случай перегрузки) в этом адресе, которые будут отличать эти функции.   -  person Usman    schedule 12.03.2010


Ответы (1)


Чтобы получить каждая функция и структура FUNCDESC, которую вы возвращаете, содержат индекс vtable в члене oVft. Приведите таблицу интерфейсов к void ** и просто используйте ее как индекс.

Конечно, зачем вам это нужно, я не знаю :)

person tyranid    schedule 12.03.2010
comment
Интересно, что мы не можем использовать член lpVtable. Это скрыто. Каждый раз, когда мы обращаемся к этому члену, например, скажем, pTypeInfo- ›lpVtble. Он выдает ошибку и говорит, что это не член. - person Usman; 12.03.2010
comment
Я думаю, вы не понимаете, как работают COM-объекты. Чтобы выполнить модульное тестирование объекта, вам нужен экземпляр. Итак, вы делаете IInterfaceToTest* pTest; CoCreateInstance(..., IID_IInterfaceToTest, &pTest); (при условии, что вы пишете на C / C ++). Чтобы получить vtable, вы делаете void** pVTable = *((void***)pTest); и, наконец, делаете void* pFunction = pVTable[funcDesc.oVft]; См. Просто. Если вы делаете это на другом языке без доступа к двоичному представлению (скажем, VB), тогда жизнь тяжелая. Если вы используете .NET, вы можете преобразовать библиотеку типов в собственные интерфейсы и вызывать методы. - person tyranid; 13.03.2010
comment
В ПОРЯДКЕ.! Я получил адрес vtable другими способами .. typedef void (FN) (void); int dwPtr = (int *) pIUknown; pFn = (FN) * ((int *) * (& dwPtr [Count]) + funcDesc.oVft); Кстати, как вы заметили, что при приведении pTest с (void **) вы получите массив vTable ..? - person Usman; 15.03.2010
comment
Вы действительно не должны использовать int * для получения указателей, как будто вы когда-нибудь перейдете на 64-битную версию, она испортится :) - person tyranid; 15.03.2010
comment
С уважением, сэр oVft не предоставляет вам надлежащий указатель. Если мой метод помещен в 7-й индекс (который я проверил жестким кодированием) oVft показывает это как 28. Как он показывает QuesryInterface в 0, AddRef в 4-м индексе, Release в 8 и так далее ... - person Usman; 15.03.2010
comment
На самом деле я забираю это обратно oVft - это смещение в байтах, поэтому разделите число на sizeof (void *), мой разум, должно быть, гниет :) - person tyranid; 16.03.2010
comment
спасибо Сэр, теперь все работает .. :-) Как вы заметили, что при приведении типов pTest с (void **) pIsomeInterface вы получите массив vtable? - person Usman; 16.03.2010
comment
Именно так работает COM :) Например, blogs.msdn. com / oldnewthing / archive / 2004/02/05 / 68017.aspx дает хороший обзор. - person tyranid; 16.03.2010
comment
Спасибо за предоставленную мне сенсорную помощь :-) - person Usman; 17.03.2010