Сейчас на форуме: tyns777, zds, JustLife (+4 невидимых)

 eXeL@B —› Программирование —› Как получить адрес оконной функции в Windows Seven 64?
Посл.ответ Сообщение

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

Создано: 28 февраля 2010 16:32
· Личное сообщение · #1

Пытаюсь получить адреса оконных функций в Windows Seven в 64 битном режиме
и не получается функция стандартная API-шная выдвет код ошибки - доступ запрещен.

В 32-битном режиме в той же операционке, тоже приложение, но откомпилированное под 32-бита работает и возвращает адреса, запускаю тоже приложение (но 64-битное) в режиме отладке - функция не выполняется.

В чем может быть проблема (привилегии отладчика и админа у меня есть)?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 28 февраля 2010 16:41
· Личное сообщение · #2

Код в студию.



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

Создано: 28 февраля 2010 17:37
· Личное сообщение · #3

Сначала я перечислял все окна для процесса к которому подключаюсь отладчиком (с этом проблем нету),
а затем для каждого hwnd выполнял слудющие операции (примерно так):

address = GetClassLongA(hwnd, GCL_WNDPROC);

if (GetClassNameA(hwnd, nameA, 255) == 0) nameA[0] = 0;

if (address > 0xffff0000)
{
address = GetClassLongW(hwnd, GCL_WNDPROC);
if (GetClassNameW(hwnd, nameW, 255) == 0) nameW[0] = 0;
}

Это для 32-битного приложения, умничить по поводу того что GetClassLong работает только с 32-битными приложениями не надо, я мсдн читал

Но замена на GetClassLongPtr не дает адекватного результата, пишет достут запрещен.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 28 февраля 2010 18:38 · Поправил: Clerk
· Личное сообщение · #4

Mag_3d
Прежде чем писать отладчик нужно уметь работать с осью. На сколько помню оконную процедуру можно получать только из текущего процесса. Извлекайте инфу из разделяемой памяти шадова, либо исполняете код в контексте целевого процесса.



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

Создано: 28 февраля 2010 18:45
· Личное сообщение · #5

> Прежде чем писать отладчик нужно уметь работать с осью. На сколько помню оконную процедуру
> можно получать только из текущего процесса. Извлекайте инфу из разделяемой памяти шадова, либо
> исполняете код в контексте целевого процесса.

вы не правы, код которой я привел выше, прекрасно работает в 32-битном режиме, мне его просто нужно портировать в 64-битный режим.

Отладчик у меня замечательно работает в 32- и 64-битном режиме, просто начал его наворачивать
для удобного перехвата оконных функций. В 64-битном режиме не получается



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

Создано: 28 февраля 2010 18:46
· Личное сообщение · #6

Подчеркну: отладчик юзер модный, не в режиме ядра



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 28 февраля 2010 18:54
· Личное сообщение · #7

Хотя это изменять ссылку на оконную процедуру нельзя удалённо, читать можно её. В x64 возможно уже нельзя, смотрите почему ошибку возвращает.



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

Создано: 28 февраля 2010 19:00
· Личное сообщение · #8

Ща проверю утилиту Spy++(64 бита) из комплекта разработчика VS,
если там выдает инфу, значит можно.

Что касается ошибки, то выдает Access_deny (точно название константы не помню)



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

Создано: 28 февраля 2010 19:11
· Личное сообщение · #9

Проверил: в ОС Vista64 все четко получает.
Все адреса обработчиков окон вывела утилита



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 28 февраля 2010 19:19
· Личное сообщение · #10

Mag_3d
Отладчиком пройдите и узнайте где ошибка. В x86 NT много инфы содержится в секции шадова и такой код возвращает ссыль на процедуру без обращения к ядру:
Code:
  1. HM_VALIDATE_HANDLE macro
  2. ; Ecx:HANDLE
  3. ; dl:TYPE
  4.          mov eax,dword ptr [_imp__IsMenu]   ; @HMValidateHandle()
  5.          add eax,dword ptr [eax + 10 + 1]
  6.          add eax,15
  7.          call eax
  8. endm
  9.  
  10. TwWndProc                 equ 60H
  11.  
  12. QueryWndProc proc hWnd:HANDLE
  13.          mov ecx,hWnd
  14.          mov dl,TYPE_WINDOW
  15.          HM_VALIDATE_HANDLE
  16.          .if Eax
  17.          mov eax,dword ptr [eax + TwWndProc]
  18.          .endif
  19.          ret
  20. QueryWndProc endp

Как в x64 мне не известно, впрочем продебажить вызов минутное дело



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

Создано: 01 марта 2010 08:37
· Личное сообщение · #11

Еще прикол:
функция GetClassLong возвращает адрес оконной процедуры,
а GetClassLongPtr - нет, пишет, что ACCESS_DENY.



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

Создано: 01 марта 2010 14:40 · Поправил: Mag_3d
· Личное сообщение · #12

Оказалось следующее:

address = GetWindowLongPtr(hwnd, GWL_WNDPROC) - возращает доступ запрещен, а вот

address = GetClassLongPtr(hwnd, GCLP_WNDPROC) - возвращает нужное значение обработчика окна.

работает в 32-битном и 64-битном режиме

Вдруг кому надо будет ...




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 01 марта 2010 15:20
· Личное сообщение · #13

Clerk Пробую собрать твой код, но компилятор ругается на _imp__IsMenu
Как её определить?


Code:
  1. HM_VALIDATE_HANDLE macro
  2. ; Ecx:HANDLE
  3. ; dl:TYPE
  4.          mov eax,dword ptr [_imp__IsMenu]   ; @HMValidateHandle()
  5.          add eax,dword ptr [eax + 10 + 1]
  6.          add eax,15
  7.          call eax
  8. endm
  9.  
  10. TwWndProc                 equ 60H
  11. TYPE_WINDOW                  equ 1
  12. HMINDEXBITS equ 00000FFFFh;
  13. HMUNIQSHIFT equ 16;
  14. HMUNIQBITS  equ 0FFFF0000h;
  15.  
  16. QueryWndProc proc hWnd:HANDLE
  17.          mov ecx,hWnd
  18.          mov dl,TYPE_WINDOW
  19.          HM_VALIDATE_HANDLE
  20.          .if Eax
  21.          mov eax,dword ptr [eax + TwWndProc]
  22.          .endif
  23.          ret
  24. QueryWndProc endp
  25. Entry:
  26.          
  27. invoke GetForegroundWindow
  28. invoke QueryWndProc, eax
  29. ret
  30. end Entry


-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes





Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 01 марта 2010 15:37 · Поправил: mak
· Личное сообщение · #14

Mag_3d

уже работает

Вызов функции SetClassLongPtr с индексом GCLP_WNDPROC создает подкласс класса окна, который воздействует на все окна, впоследствии созданные с классом. Приложение может поделить на подклассы системный класс, но не должно делить на подклассы класс окна, созданный другим процессом.

Таким образом, ошибка Access Denied может быть тогда когда окно не от этого процесса ,но окно зарегистрировано в этом процессе.

Выход из такого положения это инжект в чужой процесс.


Coderess

msdn.microsoft.com/en-us/library/ms647989(VS.85).aspx

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 01 марта 2010 15:41
· Личное сообщение · #15

Coderess
Обычный прототип определите для редактора связей(обычно это динамически определяют):
Code:
  1. HMENU typedef HANDLE
  2. _imp__IsMenu proto hMenu:HMENU

Ну или так:
Code:
  1. _imp__IsMenu proto :dword

Константы HM* это для извлечения ссылки на обьект из таблицы описателей на основе описателя(хэндла), здесь не нужно, ибо группа функций менеджера HMValidateHandle() и пр. это сами делают. Если вручную, то так:
Code:
  1. ; +
  2. ; Верификация описателя.
  3. ; Eax - ссылка на обьект в пользовательской проекции.
  4. ; Ecx - ссылка на обьект в ядерной проекции.
  5. ; Edx - ссылка на описатель обьекта.
  6. ;
  7. ValidateHandle proc SharedInformation:PSHAREDINFO, ObjectType:ULONG, Handle:HANDLE
  8.          mov ecx,SharedInformation
  9.          mov edx,Handle
  10.          mov eax,SHAREDINFO.psi[ecx]
  11.          and edx,HMINDEXBITS
  12.          cmp SERVERINFO.cHandleEntries[eax],edx      ; limit.
  13.          mov ecx,SHAREDINFO.aheList[ecx]
  14.          jb Error
  15.          lea edx,[edx + edx*2]     ; sizeof(HANDLEENTRY) = 12
  16.          mov eax,Handle
  17.          lea edx,[ecx + edx*4]     ; p + n*12 = p + (n*3)*4
  18.          shr eax,HMUNIQSHIFT
  19.          mov ecx,ObjectType
  20.          assume edx:PHANDLEENTRY
  21.          cmp [edx].wUniq,ax
  22.          jne Error
  23.          cmp [edx].bType,cl
  24.          jne Error
  25.          mov ecx,fs:[CLIENTINFO.pDeskInfo[TEB.Win32ClientInfo]]
  26.          mov eax,[edx].phead
  27.          cmp DESKTOPINFO.pvDesktopBase[ecx],eax      ; range.
  28.          jnb Error
  29.          cmp DESKTOPINFO.pvDesktopLimit[ecx],eax
  30.          mov ecx,eax
  31.          jb Error
  32.          sub eax,fs:[CLIENTINFO.ulClientDelta[TEB.Win32ClientInfo]]
  33.          jbe Error
  34. Exit:
  35.          ret
  36. Error:
  37.          xor eax,eax
  38.          xor ecx,ecx
  39.          xor edx,edx
  40.          jmp Exit
  41. ValidateHandle endp

Вобще извлечение инфы из памяти менеджера обьктов(gpHmgrSharedHandleSection в ядре) это тру техника.



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

Создано: 01 марта 2010 18:32
· Личное сообщение · #16

> Таким образом, ошибка Access Denied может быть тогда когда окно не от этого процесса ,но окно
> зарегистрировано в этом процессе.

Решение задачи рассматривается при условии, что наше приложение - отладчик процесса.
Короче со своей стороны обсуждение закрываю, поскольку решение простое найдено


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


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