COM, как получить информацию об объекте через IMarshal

Тема в разделе "WASM.WIN32", создана пользователем katrus, 29 апр 2007.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Возникла следующая проблема: в процессе есть неизвестный объект, в другом процессе этот объект представленн как proxy имплементирующий IMarshal. Как получить информацию об самом объекте (в процессе родителе) через его proxy? В идеале, было-б здорово получить CLSID, или адрес в памяти.
     
  2. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    katrus
    Как правило любой интерфейс это потомок IUnkonwn что тебе мешает этот факт заюзать? Или я что-то не так в вопросе понял?!
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    katrus
    Проверь не поддерживает ли случайно этот объект интерфейс IPersist (или производные от него IPersistStream, IPersistFile, IPersistStorage, IMoniker и что там ещё из стандартного). В случае успеха, можно воспользоваться методом IPersist::GetClassID.
    Можно также попробовать вызвать GetClassID через IDispatch (если таковой имеется).

    А адреса объекта в чужом процессе средствами СОМ не получить - это противоречит самой комовской идеологии.
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    EvilsInterrupt
    Да, конечно, это потомок IUnknown, но как мне это может помочь получить информацию о самом объекте?

    green
    IPersist, к сожалению, не реализуется. IDispatch есть, но его GetTypeInfo возвращает E_NOTIMPL.
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    katrus
    А зачем тебе ITypeInfo?
    Попробуй просто:
    получаешь ID метода GetClassID: IDispatch::GetIDsOfNames
    если получилось, вызываешь сам метод: IDispatch::Invoke.

    Шансов, конечно, мало...
    ---
    Также проверь не только IPersist, но и производные от него интерфейсы IPersist*, IMoniker*.
    Не всегда базовый интерфейс можно получить через QueryInterface.

    Хотя, я думаю, проще будет ручное решение, с использованием отладчика.
    Попробуй перехватить создание этого объекта.
     
  6. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    green
    Такой трюк я уже пробовал. GetIDsOfNames возвращает E_NOTIMPL.

    Ну ведь как-то COM "понимает" как связать прокси с конкретным объектом?
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    katrus
    В данном случае СОМ runtime учавствует только в создании объекта. Дальше (поскольку реализован IMarshal) все взаимодействие прокси-объект осуществляется кастомными методами (может быть тот же RPC, но оптимизированный под объект, пайпы, оконные сообщения, короче любые средства IPC).

    Короче, надо смотреть в отладчике. Попробуй перехватить создание этого объекта. Отслеживай вызовы CoCreateInstance(Ex), CoGetClassObject.

    Также стоит обратить внимание на процессы, имеющие общие с данным открытые объекты ядра.
     
  8. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    На самом деле создание этого объекта я ловлю. Проблема найти соответствие между proxy и конкретным объектом. То есть, скажем, в процессе родителе созданны объекты obj1, obj2, obj3. В другом процессе у меня есть proxyA, proxyB, proxyC. Но как определить какой obj соответствует, скажем, proxyB?
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    katrus
    а... ну тогда, стало быть, и CLSID известен.

    Тогда в серверном процессе поставь бряк на метод IClassFactory::CreateInstance фабрики данного класса.
    Узнать его адрес можно, перехватив вызов CoRegisterClassObject в сервере (он вызывается при старте сервера, т.е. серверный процесс должен стартовать под отладчиком).
    Или посмотреть код, регистрирующий фабрики (т.е. вызывающий CoRegisterClassObject) в дизасме.
    Впрочем одно другому не мешает. :derisive:

    Можно и более "прямым" путём - перехватывая PRC-шный диспетчер в серверном процессе. Я когда-то так делал, но куда там ставить бряки забыл совершенно. :)