Сейчас на форуме: bartolomeo, asfa, _MBK_ (+7 невидимых)

 eXeL@B —› Вопросы новичков —› Рисуем в чужом Direct3D приложении
Посл.ответ Сообщение

Ранг: 10.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 15 ноября 2011 22:50
· Личное сообщение · #1

Всем привет! Есть игра, которая использует DirectDraw7. Понадобилось выводить в углу окна этой игры некоторую информацию. Например FPS. Я перехватил вызов функции DirectDrawCreateEx и дальше незнаю в какую сторону двигаться. Прикрепляю лог сделанный с помощью DirectX Logger. Помогите пожалуйста информацией, примерами.

de6d_15.11.2011_EXELAB.rU.tgz - game.exe.log.rar



Ранг: 281.8 (наставник), 272thx
Активность: 0.250.01
Статус: Участник
Destroyer of protectors

Создано: 16 ноября 2011 03:56 · Поправил: MasterSoft
· Личное сообщение · #2

битком инфы, по твоему запросу в гугле первая ссылка. или гугл сломался? если ищешь готовое, на sf поищи такси - фрапсоаналог)
а вообще я бы на твоём месте смотрел в сторону оверлеев.сорцы тож найти можно если поискать.

Хотя всё эт не совсем по тематике форума.

| Сообщение посчитали полезным: Dynamic

Ранг: 10.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 16 ноября 2011 04:44
· Личное сообщение · #3

Перед тем как создать тему, я потратил много времени на поиск информации. Видел готовые решения, но для Direct3D 9.

Посмотрел я программу "такси". Она делает то что мне необходимо. Но только на приложениях, которые используют Direct3D 8 или Direct3D 9. А в моем случае Direct3D 7.



Ранг: 281.8 (наставник), 272thx
Активность: 0.250.01
Статус: Участник
Destroyer of protectors

Создано: 16 ноября 2011 09:14 · Поправил: MasterSoft
· Личное сообщение · #4

Dynamic
ёпт, ты чо издеваешься? там же почти всё одинаково!

Added:
Вот тут первая ссылка.



Ранг: 30.0 (посетитель), 4thx
Активность: 0.030.01
Статус: Участник

Создано: 18 ноября 2011 15:38
· Личное сообщение · #5

--> Link <--

Code:
  1. DWORD HookCOM(PVOID* lplpI,DWORD offs,DWORD new_fn,DWORD vtbl_size)
  2. {
  3.          DWORD   ret=               NULL;
  4.          DWORD*  ppvtbl=      NULL;
  5.          DWORD*  pvtbl=      NULL;
  6.          DWORD   flOldProtect=      NULL;
  7.          DWORD   flNewProtect=      NULL;
  8.          DWORD   flDontCare=               NULL;
  9.          DWORD*  pOldFN=            NULL;
  10.  
  11.          MEMORY_BASIC_INFORMATION mbi;
  12.          
  13.          ppvtbl = (DWORD*)*lplpI;
  14.          pvtbl = (DWORD*) *ppvtbl;
  15.          
  16.          
  17.  
  18.             
  19.          VirtualQuery( (void*)pvtbl, &mbi, sizeof(mbi) );
  20.  
  21.          // remove ReadOnly and ExecuteRead attributes, add on ReadWrite flag
  22.          flNewProtect = mbi.Protect;
  23.          flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE);
  24.          flNewProtect |= (PAGE_READWRITE);
  25.  
  26.          if ( !VirtualProtect(   (void*)pvtbl, sizeof(PVOID)*vtbl_size,
  27.                                flNewProtect, &flOldProtect) )
  28.          {
  29.                  return false;
  30.          }
  31.  
  32.          //Hook Vtbl
  33.          pOldFN = MakePtr(DWORD*,pvtbl,offs);
  34.          ret=*pOldFN;
  35.          *pOldFN=(DWORD) new_fn;
  36.  
  37.          VirtualProtect((void*)pvtbl, sizeof(PVOID), flOldProtect, &flDontCare);
  38.  
  39.          return ret;
  40.  
  41.  
  42. }


| Сообщение посчитали полезным: Dynamic

Ранг: 10.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 18 ноября 2011 21:18 · Поправил: Dynamic
· Личное сообщение · #6

punxer cпасибо. Очень помогли Ваши куски кода.
С помощью функции HookCOM успешно перехватил IDirectDraw7_SetCooperativeLevel и IDirectDraw7_CreateSurface.
По той же схеме собрался перехватить IDirectDrawSurface7_GetAttachedSurface.
Функция выглядит так:

Code:
  1. HRESULT WINAPI MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
  2. {
  3.          HRESULT ret = pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf) ;
  4.  
  5.          if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER)
  6.                  g_lpDDSurfBack = *lplpSurf;
  7.  
  8.          return ret;
  9. }


Но при запуске приложение крашится.
Посмотрел я в отладчике на эту функцию:

Code:
  1. 676A1410 M> 55               PUSH EBP
  2. 676A1411    8BEC             MOV EBP,ESP
  3. 676A1413    8B45 10          MOV EAX,DWORD PTR SS:[EBP+10]
  4. 676A1416    8B08             MOV ECX,DWORD PTR DS:[EAX]
  5. 676A1418    8B55 0C          MOV EDX,DWORD PTR SS:[EBP+C]
  6. 676A141B    50               PUSH EAX
  7. 676A141C    8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
  8. 676A141F    52               PUSH EDX
  9. 676A1420 C> 50               PUSH EAX
  10. 676A1421    890D 9CE36A67    MOV DWORD PTR DS:[g_lpDDSurfBack],ECX
  11. 676A1427    FF15 A4E36A67    CALL DWORD PTR DS:[pIDirectDrawSurface7_GetAttachedSurface]
  12. 676A142D    5D               POP EBP
  13. 676A142E    C2 0C00          RETN 0C


Перед выполнением RETN 0C верхушка стека выглядит так:

Code:
  1. 0018FB04  /0018FB9C
  2. 0018FB08  |00404379  RETURN to program.00404379
  3. 0018FB0C  |0093C4A0
  4. 0018FB10  |0018FB20
  5. 0018FB14  |0018FE48
  6. 0018FB18  |0079E950  program.0079E950
  7. 0018FB1C  |00000006
  8. 0018FB20  |0000007C
  9. 0018FB24  |0004100E
  10. 0018FB28  |00000400

При выполнении RETN 0C попадаем на 0018FB9C и падаем.
Стоит изменить функцию к виду:

Code:
  1. HRESULT WINAPI MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
  2. {
  3.          return pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf);
  4. }


и приложение нормально работает через MyIDirectDrawSurface7_GetAttachedSurface функцию.

Code:
  1. 676A1410 M> 55               PUSH EBP
  2. 676A1411    8BEC             MOV EBP,ESP
  3. 676A1413    5D               POP EBP
  4. 676A1414    FF25 A0E36A67    JMP DWORD PTR DS:[pIDirectDrawSurface7_GetAttachedSurface]


Подскажите пожалуйста в чем может быть проблема. Компилирую с помощью VS2010.



Ранг: 2.0 (гость), 2thx
Активность: 0=0
Статус: Участник

Создано: 24 ноября 2011 17:10
· Личное сообщение · #7

Из моего скромного опыта по перехвату API усвоил, что в процедурах обработки перехваченных функций не стоит использовать локальные переменные. Так же по возможности стоит использовать ассемблерные вставки аля CMP:JXX вместо конструкций IF:ENDIF

| Сообщение посчитали полезным: Dynamic


Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 24 ноября 2011 21:53
· Личное сообщение · #8

Dynamic

Проблема в прототипе:

Code:
  1. HRESULT WINAPI MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, 
  2. LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
  3. {


А надо:

Code:
  1. HRESULT WINAPI  MyIDirectDraw7_CreateSurface(LPVOID lplpDD,LPDDSURFACEDESC2 lpDDSurfdesc2, LPDIRECTDRAWSURFACE7 FAR *lpDDSurf7, IUnknown FAR * pUnk)


В вашем объявлении на один параметр меньше, поэтому stdcall соглашение не очищает полностью стек, и вместо адреса возврата на вершине стека этот параметр, что приводит к иксепшену.

foxmail пишет:

Из моего скромного опыта по перехвату API усвоил, что в процедурах обработки перехваченных функций не стоит использовать локальные переменные.

Это неправда. Их юзать как раз можно, никаких проблем нет. Да и быть не может, только если вы не создаёте какой-то огромный локальный буфер, который настолько здоровенный, что вызывает переполнение стэка.

-----
Stuck to the plan, always think that we would stand up, never ran.


| Сообщение посчитали полезным: Dynamic

Ранг: 10.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 24 ноября 2011 22:29 · Поправил: Dynamic
· Личное сообщение · #9

ARCHANGEL, если бы

Вы написали прототип функции DirectDraw7_CreateSurface, а не IDirectDrawSurface7_GetAttachedSurface.

Вот что я нашел в ddraw.h:
Code:
  1. #define IDirectDrawSurface_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)

Code:
  1. STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE;

msdn: --> Link <--
Так что проблема не в прототипе.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 24 ноября 2011 22:31
· Личное сообщение · #10

Dynamic
Тьфу, точно. Вот я ... даже на название не глянул, вот что значит спешка.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 74.1 (постоянный), 34thx
Активность: 0.030
Статус: Участник

Создано: 26 ноября 2011 19:15
· Личное сообщение · #11

Приветствую

Логгер Директикса из первого поста поддерживает плагины, так что вручную перехваты ставить не надо.
надо написать обработчик и указать ему, возможно этот путь будет более легким для топикстартера
http://blackninja2000.narod.ru/rus/directx_logger.html

| Сообщение посчитали полезным: Dynamic

Ранг: 30.0 (посетитель), 4thx
Активность: 0.030.01
Статус: Участник

Создано: 29 ноября 2011 00:32 · Поправил: punxer
· Личное сообщение · #12

Dynamic
Код перехвата покажите весь
Откуда устанавливается перехват pSurf->GetAttachedSurface?
Куда указывает lplpThis
Code:
  1. HRESULT WINAPI MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 <b>lplpThis</b>, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf)
  2. {
  3.          HRESULT ret = pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf) ;
  4.  
  5.          if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER)
  6.                  g_lpDDSurfBack = *lplpSurf;
  7.  
  8.          return ret;
  9. }


Из моего скромного опыта по перехвату API усвоил, что в процедурах обработки перехваченных функций не стоит использовать локальные переменные. Так же по возможности стоит использовать ассемблерные вставки аля CMP:JXX вместо конструкций IF:ENDIF

Это отнють не так. И как правило в таких перехватах на с++ в ассемблере нет особой нужды вообще


 eXeL@B —› Вопросы новичков —› Рисуем в чужом Direct3D приложении
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати