Перехват COM на примере IDirectDraw

Тема в разделе "WASM.WIN32", создана пользователем punxer, 3 апр 2010.

  1. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Здравствуйте, собственно в теме указано с чем нужна помощь.
    Мне нужно рисовать на поверхности DD7 приложения. DirectDrawCreateEx перехвачена, теперь я хочу создать свой интерфейс, поддерживающий IDirectDraw7
    Код (Text):
    1. #undef  INTERFACE
    2. #define INTERFACE   myIDirectDraw7
    3.  
    4. DECLARE_INTERFACE_(INTERFACE, IDirectDraw7)
    5. {
    6.     BEGIN_INTERFACE
    7.  
    8.  
    9.     STDMETHOD(CreateSurface)(THIS_  LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE7 FAR *, IUnknown FAR *) PURE;
    10.  
    11.  
    12.     STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC2) PURE;
    13.  
    14.  
    15.     STDMETHOD(RestoreDisplayMode)(THIS) PURE;
    16.     STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE;
    17.     STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE;
    18.  
    19.  
    20.     END_INTERFACE
    21. };
    Переопределить там нужные для перехвата методы, создать класс, поддерживающий новый интерфейс и подсовывать всю эту кухню в DirectDrawCreateEx в параметре lplpDD, но что то подсказывает что я брешу)

    Какие будут комментарии, ссылки, идеи, готовые куски кода.
    Заранее спасибо!
     
  2. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Или как ?
     
  3. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Ну и оадно, диалог не удался, устроим монолог. Может кому решение и понадобится)
    Код (Text):
    1. HRESULT WINAPI MyDirectDrawCreateEx(GUID *lpGuid,LPVOID *lplpDD,const IID &iid,IUnknown *pUnkOuter)
    2. {
    3. #define CREATE_SURFACE_OFFSET 24
    4.  
    5.     HRESULT ret=            NULL;
    6.     DWORD*  ppvtbl=         NULL;
    7.     DWORD* pvtbl=           NULL;
    8.     DWORD flOldProtect=     NULL;
    9.     DWORD flNewProtect=     NULL;
    10.     DWORD flDontCare=       NULL;
    11.     DWORD* pCreateSurface=  NULL;
    12.  
    13.     MEMORY_BASIC_INFORMATION mbi;
    14.     OutputDebugString("!!in MyDirectDrawCreateEx");
    15.  
    16.     ret=pDirectDrawCreateEx(lpGuid,lplpDD,iid,pUnkOuter);
    17.  
    18.     ppvtbl = (DWORD*)*lplpDD;
    19.     pvtbl = (DWORD*) *ppvtbl;
    20.    
    21.    
    22.  
    23.            
    24.     VirtualQuery( (void*)pvtbl, &mbi, sizeof(mbi) );
    25.  
    26.  
    27.     flNewProtect = mbi.Protect;
    28.     flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE);
    29.     flNewProtect |= (PAGE_READWRITE);
    30.  
    31.     if ( !VirtualProtect(   (void*)pvtbl, sizeof(PVOID)*31,
    32.                           flNewProtect, &flOldProtect) )
    33.     {
    34.         OutputDebugString("cant unprotect memory. return false");
    35.         return false;
    36.     }
    37.  
    38.     //Hook Vtbl
    39.     pCreateSurface = MakePtr(DWORD*,pvtbl,CREATE_SURFACE_OFFSET);
    40.     pIDirectDraw7_CreateSurface=(HRESULT (__stdcall PASCAL *)
    41.         (LPVOID lplpDD,LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE7 FAR *, IUnknown FAR *))*pCreateSurface;
    42.     *pCreateSurface=(DWORD) MyIDirectDraw7_CreateSurface;
    43.  
    44.     VirtualProtect((void*)pvtbl, sizeof(PVOID), flOldProtect, &flDontCare);
    45.  
    46.     return ret;
    47.  
    48. }
     
  4. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. HRESULT __stdcall PASCAL MyIDirectDraw7_CreateSurface(LPVOID lplpDD,LPDDSURFACEDESC2 lpDDSurfdesc2, LPDIRECTDRAWSURFACE7 FAR *lpDDSurf7, IUnknown FAR * pUnk)
    2. {
    3.     HRESULT ret=NULL;
    4.  
    5.     ret=pIDirectDraw7_CreateSurface(lplpDD,lpDDSurfdesc2,lpDDSurf7,pUnk);
    6.     OutputDebugString("In lpDD->CreateSurface");
    7.     return ret;
    8. }
     
  5. tex32

    tex32 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2009
    Сообщения:
    202
    Здравствуйте. Не могли бы вы рассказать какая практическая польза от этого алгоритма, что дает это решение?
     
  6. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    tex32
    Здравствуйте, чую сарказм, но все же это дает возможность вывода поверх приложений использующих директдро7 и ниже, а по аналогии и D3D.
     
  7. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    А зачем такие хитрые манипуляции с указателем таблицы виртеальных функций, ради экономии на подсчёте ссылок? По моему проще определить класс реализующий IDirectDraw7 и возвращать указатель на его экземпляр в MyDirectDrawCreateEx
     
  8. tex32

    tex32 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2009
    Сообщения:
    202
    punxer интересуюсь для общего развития, а не ради сарказма. То есть это даст возможность вывода изображений поверх обычного, или это позволяет модифицировать старое приложение под свои нужды путем подтасовок параметров и указателей? Какова скорость фпс в таком случае у приложения пропатченного таким образом и если можно приведите источник откуда черпаете информацию по данной теме. Еще один вопрос, а можно вашим методом перевести приложение из Д7 под Д9. Понимаю, звучит глупо, но все же, есть ли перспектива написать такую программу?
     
  9. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    tex32
    Выводить поверх приложения свои данные. Информацию черпаю из мозга и интернета.)
    Теоретически можно перевести. Но все теоретисчески, я пока прошол этап перехвата и получения указателя на первичную поверхность, вроде получаю задний буфер...но пока как то не пойму где и на какой поверхности свое рисовать. В перехваченном флипе думаю и рисовать нужно на заднем буфере, предварительно залочив его, а потом вызвать таки натуральный флип, может кто опытный подтянется подскажет??
     
  10. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    J0E
    Я думал об этом, но потом пришол к выводу что лучше пропатчу что нужно мне и не буду городить огород, да и подсчет ссылок...
     
  11. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Может исходники чего то схожего есть?
     
  12. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    там FRAPS... например
     
  13. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. HRESULT __stdcall PASCAL MyIDirectDraw7_CreateSurface(LPVOID lplpDD,LPDDSURFACEDESC2 lpDDSurfdesc2, LPDIRECTDRAWSURFACE7 FAR *lpDDSurf7, IUnknown FAR * pUnk)
    2. {
    3. #define IDirectDrawSurface7_Flip_OFFSET 44
    4. #define GetAttachedSurface_OFFSET       48
    5.  
    6.     HRESULT ret=            NULL;
    7.  
    8.     ret=pIDirectDraw7_CreateSurface(lplpDD,lpDDSurfdesc2,lpDDSurf7,pUnk);
    9.    
    10.    
    11.  
    12.     OutputDebugString("!!!In lpDD->CreateSurface");
    13.  
    14.     if(lpDDSurfdesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    15.     {
    16.         //Hook flip and other
    17.         OutputDebugString("!!!!!!Primary surface founded");
    18.         g_lpDDSurfPrimary=(LPDIRECTDRAWSURFACE7)*lpDDSurf7;
    Код (Text):
    1. HRESULT __stdcall   PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
    2. {
    3.     HRESULT ret;
    4.     OutputDebugString("!!!!!!Primary surface->GetAttachedSurface");
    5.     if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER)
    6.     {
    7.         OutputDebugString("!!!!!!!!!!!Back Buffer Founded");
    8.         g_lpDDSurfBack=*lplpSurf;
    9.     }
    10.     ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf);
    11.     return ret;
    12. }
    Код (Text):
    1. HRESULT __stdcall   PASCAL MyIDirectDrawSurface7_Flip(LPDIRECTDRAWSURFACE7 lplpThis,LPDIRECTDRAWSURFACE7* lplpSurf7,DWORD param)
    2.  
    3. {
    4.     LPDIRECTDRAWSURFACE7 lpDDs;
    5.     HRESULT ret=NULL;
    6.     DDSURFACEDESC2 SD;
    7.     DDSCAPS2 caps;
    8.     RECT rc;
    9.     BYTE*   ptr=            NULL;
    10.  
    11.     OutputDebugString("!!!In lpDDPrimarySurf7->Flip");     
    12.  
    13.     caps.dwCaps=DDSCAPS_BACKBUFFER;
    14.     pIDirectDrawSurface7_GetAttachedSurface(g_lpDDSurfPrimary,&caps,&lpDDs);
    15.     if (lpDDs)
    16.     {
    17.         OutputDebugString("!!!In lpDDPrimarySurf7->Flip!!!BackBuffer obtained");   
    18.     }
    19.  
    20.     ret=pIDirectDrawSurface7_Flip(lplpThis,lplpSurf7,param);
    21.    
    22.    
    23.     return ret;
    24. }
    Так вот во флипе g_lpDDSurfBack=0 А pIDirectDrawSurface7_GetAttachedSurface(g_lpDDSurfPrimary,&caps,&lpDDs);
    отрабатывает ну что то совсем поздно. g_lpDDSurfPrimary находится нормально.
    Очень много флипов прорходит без успешного pIDirectDrawSurface7_GetAttachedSurface.
     
  14. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Вот лог
     
  15. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Не аттачится(
     
  16. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. 00000081    12:53:27    [688] In MyCreateWindowExA 
    2. 00000082    12:53:27    [688] !!in MyDirectDrawCreateEx
    3. 00000083    12:53:27    [688] !!CreateSurface hooked   
    4. 00000084    12:53:27    [688] !!!In lpDD->CreateSurface
    5. 00000085    12:53:27    [688] !!!!!!Primary surface founded
    6. 00000086    12:53:27    [688] !!!!!!Primary surface->GetAttachedSurface
    7. 00000087    12:53:27    [688] !!!!!!!!!!!Back Buffer Founded   
    8. 00000088    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    9. 00000089    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    10. 00000090    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    11. 00000091    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    12. 00000092    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    13. 00000093    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    14. 00000094    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    15. 00000095    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    16. 00000096    12:53:27    [688] !!!In lpDDPrimarySurf7->Flip 
    17. 00000097    12:53:28    [688] !!!In lpDDPrimarySurf7->Flip 
    18. 00000098    12:53:28    [688] !!!In lpDDPrimarySurf7->Flip 
    19. 00000099    12:53:28    [688] !!!In lpDDPrimarySurf7->Flip 
    20. 00000100    12:53:28    [688] !!!In lpDDPrimarySurf7->Flip 
    21. 00000101    12:53:28    [688] !!!In lpDD->CreateSurface
    22. 00000102    12:53:28    [688] !!!In lpDD->CreateSurface
    23. 00000103    12:53:28    [688] !!!In lpDD->CreateSurface
    24. 00000104    12:53:28    [688] !!!In lpDD->CreateSurface
    25. 00000105    12:53:28    [688] !!!In lpDD->CreateSurface
    и в самом конце
    Код (Text):
    1. 00014742    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    2. 00014743    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    3. 00014744    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    4. 00014745    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    5. 00014746    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    6. 00014747    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    7. 00014748    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    8. 00014749    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    9. 00014750    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    10. 00014751    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    11. 00014752    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    12. 00014753    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip 
    13. 00014754    12:54:52    [688] !!!In lpDDPrimarySurf7->Flip!!!BackBuffer obtained
     
  17. tex32

    tex32 New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2009
    Сообщения:
    202
    punxer глянь программу DirectX Logger на http://blackninja2000.narod.ru Она тоже может хватать ddraw.dll и вести лог по Д7.
     
  18. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. HRESULT __stdcall   PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
    2. {
    3.     HRESULT ret;
    4.     OutputDebugString("!!!!!!Primary surface->GetAttachedSurface");
    5.     if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER)
    6.     {
    7.         OutputDebugString("!!!!!!!!!!!Back Buffer Founded");
    8.         g_lpDDSurfBack=*lplpSurf;
    9.     }
    10.     ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf);
    11.     return ret;
    12. }
    а вот правильный вариант))
    Код (Text):
    1. HRESULT __stdcall   PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
    2. {
    3.     HRESULT ret;
    4.     OutputDebugString("!!!!!!Primary surface->GetAttachedSurface");
    5.            [b]ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf);[/b]
    6.     if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER)
    7.     {
    8.         OutputDebugString("!!!!!!!!!!!Back Buffer Founded");
    9.         g_lpDDSurfBack=*lplpSurf;
    10.     }
    11.    
    12.     return ret;
    13. }
     
  19. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    tex32
    я и сам это могу)