Как получить указатель на метод COM для перехвата? - PullRequest
3 голосов
/ 04 апреля 2011

Я знаю, что это кажется переоцененным вопросом, но этот другой. У меня есть этот объект ActiveX, который экспортирует некоторые методы. Мне нужно установить ловушку на один из его методов, а именно Func1, я знаю, как это сделать с помощью VirtualProtect() и т. Д. Если я открою ollydbg и покопаюсь в ActiveX DLL, я вижу именно адрес Func1 где мне нужно установить крючок.

В Visual Studio 2008 я использую директиву прекомпилятора:

#import "myactx.dll" no_namespace, named_guids, raw_interfaces_only

И в своем коде я пытаюсь сделать это:

LPVOID ptr = &IMyActx::Func1;

, который возвращает ошибку при компиляции:

ошибка C2440: «инициализация»: невозможно преобразовать из «HRESULT (__stdcall IMyActx :: *) (BSTR, BSTR)» в «LPVOID».

Я исследовал и обнаружил, что не могу привести метод указателя к классу к указателю на функцию из-за неявного this параметра.

Однако я не собираюсь вызывать эту функцию. Я просто хочу узнать его адрес в памяти, чтобы я мог передать его в свою процедуру перехвата (которая ожидает указатель LPVOID).

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

Любое предложение очень ценится, спасибо за чтение.

EDIT ... Подумайте об этом ... LPVOID ptr = &IMyActx::Func1; не должно работать, потому что IMyActx - чисто виртуальный класс! В любом случае, я попробовал несколько комбинаций, прежде чем создавать экземпляр объекта и пытаться получить необработанный указатель на Func1, но пока ничего не получалось. В ollydbg я вижу, что вызов Func1 генерируется как:

mov edx, [eax];
call dword ptr ds:[edx + 0x1C];

Так что я могу предположить, что мне нужно прочитать DWORD в vptr + 0x1C байтах и ​​вуаля.

Если я правильно помню, объектная модель компонентов гарантирует, что это всегда будет Func1 ptr, лежащий в [vptr + 0x1C] при одном и том же идентификаторе интерфейса. навсегда. Правильно?

Я, вероятно, сделаю что-то подобное в некотором псевдокоде:

#define FUNC1_ENTRY   0x1C / sizeof(LPBYTE)

CoCreateInstance(CLSID_MyActx, 0, CLSCTX_ALL, IID_IMyActxObj, (LPVOID*) &pObj);

LPVOID pToHook = (*pObj)[FUNC1_ENTRY];

Ответы [ 2 ]

1 голос
/ 11 апреля 2011

Методы COM-объектов на самом деле являются обычными функциями. Это то, что позволяет клиентам COM, написанным на C вместо C ++.

Я рекомендую сгенерировать заголовочный файл для клиента C, тогда адрес функции будет легко получен. Однако сначала вам нужен экземпляр класса, который вы намереваетесь подключить.

0 голосов
/ 10 апреля 2011

Если я вас правильно понимаю, вы хотите преобразовать указатель на метод класса в указатель на функцию.

Это на самом деле невозможно.

Простой пример:

class A {
    public:
    void func()
    {
        this->var = 0;
    }
    int var;
};

A myObj;
A::func* ptr2 = &(myObj::func); // works
void* ptr = &(myObj::func); // doesn't: what would "this" in line 5 point to?

Вы даже не можете использовать reinterpret_cast.

Была ли эта проблема тоже однажды.Затем мне просто нужно было создать функцию, которая отображает входное значение на указатель на объект.Может быть, вы могли бы создать функцию-оболочку, в которой вы вызываете метод, имея указатель на него?

...