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

 eXeL@B —› Программирование —› Изменение DRх регистров в обработчике исключений х64
Посл.ответ Сообщение

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

Создано: 01 октября 2013 18:18 · Поправил: deniskore
· Личное сообщение · #1

Пытаюсь выставить hardware breakpoint внутри SEH обработчика, через контекст (CONTEXT *ctx) который передается в обработчик, путем записи адреса в ctx->Dr0 и выставления соответствующих флагов в ctx->Dr7.
В х86 это работает без проблем, в х64 значение Dr0 и Dr7 не модифицируется.

Если изменять вне исключения dr0, dr7 через SetThreadContext, перед этим остановив thread, то модифицируется без проблем.
Как правильно изменить drx внутри обработчика SEH в х64?




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

Создано: 01 октября 2013 22:21
· Личное сообщение · #2

Во-первых, х64 натив или ВОВ64? А во-вторых, кодес в студию.



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

Создано: 02 октября 2013 13:26 · Поправил: deniskore
· Личное сообщение · #3

натив,
Code:
  1. #include <Windows.h>
  2. #include <stdio.h>
  3.  
  4. int ExtValue=0;
  5.  
  6. int se(CONTEXT *ctx)
  7. {
  8.  
  9.    ctx->ContextFlags|=CONTEXT_DEBUG_REGISTERS;
  10.  
  11.    ctx->Rip+=6; // 6 байт команда деления
  12.  
  13.    ctx->Dr0=(UINT64)&ExtValue;
  14.    ctx->Dr7=0xD0101;
  15.  
  16.    return(EXCEPTION_CONTINUE_EXECUTION);
  17. }
  18.  
  19.  
  20. void main()
  21. {
  22.    __try
  23.    {
  24.       ExtValue/=ExtValue;
  25.    }
  26.    __except(se((GetExceptionInformation())->ContextRecord))
  27.    {
  28.    }
  29.  
  30.    ExtValue=1;
  31. }

Студия остановится (SINGLE_STEP) на ExtValue=1 если Rip в Eip переименовать и скомпилировать под х86.



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

Создано: 04 октября 2013 08:45
· Личное сообщение · #4

Неужели никто из опытных не знает?



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

Создано: 04 октября 2013 14:38
· Личное сообщение · #5

TF-флаг?




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 04 октября 2013 19:08 · Поправил: DenCoder
· Личное сообщение · #6

Заинтересовался проблемой...

Ответ должен быть в ntdll!KiUserExceptionDispatcher. Посмотрев код в WinDbg
Code:
  1. 00000000`77ef2a90 488b05896c0b00  mov     rax,qword ptr [ntdll!NlsMbOemCodePageTag+0x8 (00000000`77fa9720)]
  2. 00000000`77ef2a97 4885c0          test    rax,rax
  3. 00000000`77ef2a9a 740f            je      ntdll!KiUserExceptionDispatcher+0x1b (00000000`77ef2aab)
  4. 00000000`77ef2a9c 488bcc          mov     rcx,rsp
  5. 00000000`77ef2a9f 4881c1d0040000  add     rcx,4D0h
  6. 00000000`77ef2aa6 488bd4          mov     rdx,rsp
  7. 00000000`77ef2aa9 ffd0            call    rax
  8. 00000000`77ef2aab 488bcc          mov     rcx,rsp
  9. 00000000`77ef2aae 4881c1d0040000  add     rcx,4D0h
  10. 00000000`77ef2ab5 488bd4          mov     rdx,rsp
  11. 00000000`77ef2ab8 e8d32bffff      call    ntdll!RtlLookupFunctionEntry+0x460 (00000000`77ee5690)
  12. 00000000`77ef2abd 84c0            test    al,al
  13. 00000000`77ef2abf 740c            je      ntdll!KiUserExceptionDispatcher+0x3d (00000000`77ef2acd)
  14. 00000000`77ef2ac1 488bcc          mov     rcx,rsp
  15. 00000000`77ef2ac4 33d2            xor     edx,edx
  16. 00000000`77ef2ac6 e855020000      call    ntdll!RtlRestoreContext (00000000`77ef2d20)
  17. 00000000`77ef2acb eb15            jmp     ntdll!KiUserExceptionDispatcher+0x52 (00000000`77ef2ae2)
  18. 00000000`77ef2acd 488bcc          mov     rcx,rsp
  19. 00000000`77ef2ad0 4881c1d0040000  add     rcx,4D0h
  20. 00000000`77ef2ad7 488bd4          mov     rdx,rsp
  21. 00000000`77ef2ada 4532c0          xor     r8b,r8b
  22. 00000000`77ef2add e8fee5ffff      call    ntdll!ZwRaiseException (00000000`77ef10e0)
  23. 00000000`77ef2ae2 8bc8            mov     ecx,eax
  24. 00000000`77ef2ae4 e847100600      call    ntdll!RtlRaiseStatus (00000000`77f53b30)


и сравнив его с аналогом на x86
Code:
  1. 7C90E47A  |.  8BFF          MOV     EDI, EDI                         ;
  2. 7C90E47C  |.  8B4C24 04     MOV     ECX, [ESP+4]                     ; ntdll.KiUserExceptionDispatcher(pExceptionRecord,pContext)
  3. 7C90E480  |.  8B1C24        MOV     EBX, [ESP]                       ;
  4. 7C90E483  |.  51            PUSH    ECX                              ;
  5. 7C90E484  |.  53            PUSH    EBX                              ;
  6. 7C90E485  |.  E8 84C00100   CALL    7C92A50E                         ;
  7. 7C90E48A  |.  0AC0          OR      AL, AL                           ;
  8. 7C90E48C  |.  74 0C         JE      SHORT 7C90E49A                   ;
  9. 7C90E48E  |.  5B            POP     EBX                              ;
  10. 7C90E48F  |.  59            POP     ECX                              ;
  11. 7C90E490  |.  6A 00         PUSH    0                                ;
  12. 7C90E492  |.  51            PUSH    ECX                              ;
  13. 7C90E493  |.  E8 C6EBFFFF   CALL    ZwContinue                       ;
  14. 7C90E498  |.  EB 0B         JMP     SHORT 7C90E4A5                   ;
  15. 7C90E49A  |>  5B            POP     EBX                              ;
  16. 7C90E49B  |.  59            POP     ECX                              ;
  17. 7C90E49C  |.  6A 00         PUSH    0                                ;
  18. 7C90E49E  |.  51            PUSH    ECX                              ;
  19. 7C90E49F  |.  53            PUSH    EBX                              ;
  20. 7C90E4A0  |.  E8 09F5FFFF   CALL    NtRaiseException                 ;
  21. 7C90E4A5  |>  83C4 EC       ADD     ESP, -14                         ;
  22. 7C90E4A8  |.  890424        MOV     [ESP], EAX                       ;
  23. 7C90E4AB  |.  C74424 04 010 MOV     DWORD PTR [ESP+4], 1             ;
  24. 7C90E4B3  |.  895C24 08     MOV     [ESP+8], EBX                     ;
  25. 7C90E4B7  |.  C74424 10 000 MOV     DWORD PTR [ESP+10], 0            ;
  26. 7C90E4BF  |.  54            PUSH    ESP                              ;
  27. 7C90E4C0  |.  E8 63000000   CALL    RtlRaiseException                ;
  28. 7C90E4C5  \.  C2 0800       RETN    8                                ;


видим первое отличие - на x64 ZwContinue заменена на RtlRestoreContext. В её внутренностях содержится такой код
Code:
  1. Очень огромный код - сами смотрите :)


deniskore пишет:
В х86 это работает без проблем, в х64 значение Dr0 и Dr7 не модифицируется.

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

Связанная проблема - не могу для более удобного анализа локализовать x64-версию ntdll.dll. (Ида64 анализирует её как 32битную). Даже поиск файла с сигнатурой 4885C0740F488BCC4881C ничего не дал. Чудеса какие-то...

P.S. Дайте Клерку ссылку на книженцию о правилах хорошего тона. Кол-во страниц - не меньше, чем в мануалах интела

-----
IZ.RU





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

Создано: 04 октября 2013 19:52
· Личное сообщение · #7

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

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


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 04 октября 2013 20:26 · Поправил: DenCoder
· Личное сообщение · #8

Да, только со скопированной dll анализ x64-версии.

Ответ тогда прост:
ввиду
Code:
  1. .text:0000000077EF2AC1 000 mov     rcx, rsp        ; ContextRecord
  2. .text:0000000077EF2AC4 000 xor     edx, edx        ; ExceptionRecord
  3. .text:0000000077EF2AC6 000 call    RtlRestoreContext


и

Code:
  1. .text:0000000077EF2D20 000 push    rbp
  2. .text:0000000077EF2D21 008 push    rsi
  3. .text:0000000077EF2D22 010 push    rdi
  4. .text:0000000077EF2D23 018 sub     rsp, 30h
  5. .text:0000000077EF2D27 048 mov     rbp, rsp
  6. .text:0000000077EF2D2A 048 test    rdx, rdx
  7. .text:0000000077EF2D2D 048 jz      loc_77EF2E79
  8. ...
  9.  
  10. .text:0000000077EF2E79 048 fxrstor dword ptr [rcx+100h]
  11. .text:0000000077EF2E80 048 movdqa  xmm0, xmmword ptr [rcx+1A0h]
  12. .text:0000000077EF2E88 048 movdqa  xmm1, xmmword ptr [rcx+1B0h]
  13. .text:0000000077EF2E90 048 movdqa  xmm2, xmmword ptr [rcx+1C0h]
  14. .text:0000000077EF2E98 048 movdqa  xmm3, xmmword ptr [rcx+1D0h]
  15. .text:0000000077EF2EA0 048 movdqa  xmm4, xmmword ptr [rcx+1E0h]
  16. .text:0000000077EF2EA8 048 movdqa  xmm5, xmmword ptr [rcx+1F0h]
  17. .text:0000000077EF2EB0 048 movdqa  xmm6, xmmword ptr [rcx+200h]
  18. .text:0000000077EF2EB8 048 movdqa  xmm7, xmmword ptr [rcx+210h]
  19. .text:0000000077EF2EC0 048 movdqa  xmm8, xmmword ptr [rcx+220h]
  20. .text:0000000077EF2EC9 048 movdqa  xmm9, xmmword ptr [rcx+230h]
  21. .text:0000000077EF2ED2 048 movdqa  xmm10, xmmword ptr [rcx+240h]
  22. .text:0000000077EF2EDB 048 movdqa  xmm11, xmmword ptr [rcx+250h]
  23. .text:0000000077EF2EE4 048 movdqa  xmm12, xmmword ptr [rcx+260h]
  24. .text:0000000077EF2EED 048 movdqa  xmm13, xmmword ptr [rcx+270h]
  25. .text:0000000077EF2EF6 048 movdqa  xmm14, xmmword ptr [rcx+280h]
  26. .text:0000000077EF2EFF 048 movdqa  xmm15, xmmword ptr [rcx+290h]
  27. .text:0000000077EF2F08 048 ldmxcsr dword ptr [rcx+34h]
  28. .text:0000000077EF2F0C 048 mov     ax, [rcx+42h] ; ss
  29. .text:0000000077EF2F10 048 mov     [rsp+20h], ax
  30. .text:0000000077EF2F15 048 mov     rax, [rcx+98h] ; rsp
  31. .text:0000000077EF2F1C 048 mov     [rsp+18h], rax
  32. .text:0000000077EF2F21 048 mov     eax, [rcx+44h] ; eflags
  33. .text:0000000077EF2F24 048 mov     [rsp+10h], eax
  34. .text:0000000077EF2F28 048 mov     ax, [rcx+38h] ; cs
  35. .text:0000000077EF2F2C 048 mov     [rsp+8], ax
  36. .text:0000000077EF2F31 048 mov     rax, [rcx+0F8h] ; rip
  37. .text:0000000077EF2F38 048 mov     [rsp+0], rax
  38. .text:0000000077EF2F3C 048 mov     rax, [rcx+78h]
  39. .text:0000000077EF2F40 048 mov     rdx, [rcx+88h]
  40. .text:0000000077EF2F47 048 mov     r8, [rcx+0B8h]
  41. .text:0000000077EF2F4E 048 mov     r9, [rcx+0C0h]
  42. .text:0000000077EF2F55 048 mov     r10, [rcx+0C8h]
  43. .text:0000000077EF2F5C 048 mov     r11, [rcx+0D0h]
  44. .text:0000000077EF2F63 048 mov     rbx, [rcx+90h]
  45. .text:0000000077EF2F6A 048 mov     rsi, [rcx+0A8h]
  46. .text:0000000077EF2F71 048 mov     rdi, [rcx+0B0h]
  47. .text:0000000077EF2F78 048 mov     rbp, [rcx+0A0h]
  48. .text:0000000077EF2F7F 048 mov     r12, [rcx+0D8h]
  49. .text:0000000077EF2F86 048 mov     r13, [rcx+0E0h]
  50. .text:0000000077EF2F8D 048 mov     r14, [rcx+0E8h]
  51. .text:0000000077EF2F94 048 mov     r15, [rcx+0F0h]
  52. .text:0000000077EF2F9B 048 mov     rcx, [rcx+80h]
  53. .text:0000000077EF2FA2 048 iretq


делается вывод, что не предусмотрена на x64-системах установка DR-регистров в обработчиках или же фильтрах через передаваемую структуру CONTEXT. (смещения DR-регистров: 0x48 .. 0x70)

Если всё же нужно, то можно прямо в обработчике их установить
Code:
  1. mov rax, offset ExtValue
  2. mov dr0, rax
  3. mov rax, 0xd0101
  4. mov dr7, rax


-----
IZ.RU





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

Создано: 04 октября 2013 22:28
· Личное сообщение · #9

Сильно я сомневаюсь, что в обработчике ты их установишь, коль mov DR привилегированная.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 04 октября 2013 23:02 · Поправил: DenCoder
· Личное сообщение · #10

отт точно ))

SetThreadContext() тогда

Code:
  1. int se(CONTEXT *ctx)
  2. {
  3.    ctx->Rip+=6; // 6 байт команда деления
  4.  
  5.   CONTEXT dbg_ctx;
  6.   ZeroMemory(&dbg_ctx, sizeof(CONTEXT));
  7.  
  8.   dbg_ctx.ContextFlags|=CONTEXT_DEBUG_REGISTERS;
  9.   dbg_ctx.Dr0=(UINT64)&ExtValue;
  10.   dbg_ctx.Dr7=0xD0101;
  11.   SetThreadContext(GetCurrentThread(), &dbg_ctx);
  12.  
  13.    return(EXCEPTION_CONTINUE_EXECUTION);
  14. }


-----
IZ.RU




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

Создано: 06 октября 2013 17:18
· Личное сообщение · #11

DenCoder, на х64 тоже смотрел под отладчиком, последний пример работать не будет. Спасибо.
Похоже остается только останавливать поток и устанавливать, но такое решение для меня не подходит.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 07 октября 2013 16:59 · Поправил: DenCoder
· Личное сообщение · #12

Должен сказать, что да - под Win32 не работает установка dr-регистров посредством ф-ции SetThreadContext перед выходом из обработчика, поскольку по завершению обработки ось забирает весь контекст в соответствии с флагами. И также бесполезно, находясь ещё в обработчике, устанавливать контекст из другого потока.

Но! Рассмотренная особенность x64, по крайней мере на Windows XP, позволяет установить DR-регистры методом в посте выше. Установил x64 tools, настроил отладку x64.

Код:
Code:
  1. #define SETDR_METHOD 2
  2.  
  3. DWORD ExtVar = 0;
  4.  
  5. HANDLE hEvent;
  6.  
  7. DWORD __stdcall SetDr(void* ThreadId)
  8. {
  9.          HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, false, (DWORD)ThreadId);
  10.  
  11.          CONTEXT dbg_ctx;
  12.          ZeroMemory(&dbg_ctx, sizeof(CONTEXT));
  13.          dbg_ctx.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
  14.          dbg_ctx.Dr0 = (UINT64)&ExtVar;
  15.          dbg_ctx.Dr7 = 0xD0101;
  16.  
  17.          SuspendThread(hThread);
  18.          SetThreadContext(hThread, &dbg_ctx);
  19.          ResumeThread(hThread);
  20.          CloseHandle(hThread);
  21.          SetEvent(hEvent);
  22.  
  23.          return 0;
  24. }
  25.  
  26. LONG filter(LONG excode, EXCEPTION_POINTERS* ep)
  27. {
  28.          /*ep->ContextRecord->Eip += 6;*/
  29.          ep->ContextRecord->Rip += 6;
  30.  
  31. #if SETDR_METHOD == 1
  32.          CloseHandle(CreateThread(NULL, 0, SetDr, (void*)GetCurrentThreadId(), 0, NULL));
  33.          WaitForSingleObject(hEvent, INFINITE);
  34. #else
  35.          CONTEXT dbg_ctx;
  36.          ZeroMemory(&dbg_ctx, sizeof(CONTEXT));
  37.          dbg_ctx.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
  38.          dbg_ctx.Dr0 = (UINT64)&ExtVar;
  39.          dbg_ctx.Dr7 = 0xD0101;
  40.  
  41.          SetThreadContext(GetCurrentThread(), &dbg_ctx);
  42. #endif
  43.  
  44.          return EXCEPTION_CONTINUE_EXECUTION;
  45. }
  46.  
  47. int _tmain(int argc, _TCHAR* argv[])
  48. {
  49.          hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  50.  
  51.          __try
  52.          {
  53.                  ExtVar /= ExtVar;
  54.          }
  55.          __except(filter(GetExceptionCode(), GetExceptionInformation()))
  56.          {
  57.          }
  58.  
  59.          ExtVar = 1;
  60.  
  61.          CloseHandle(hEvent);
  62.  
  63.          CONTEXT dbg_ctx;
  64.          ZeroMemory(&dbg_ctx, sizeof(CONTEXT));
  65.          dbg_ctx.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
  66.  
  67.          GetThreadContext(GetCurrentThread(), &dbg_ctx);
  68.  
  69.          return 0;
  70. }


Работает и для SETDR_METHOD = 1 и для SETDR_METHOD = 2. То есть GetThreadContext() после исключения получает в обоих случаях то, что мы хотели установить. Вопрос только отладчика - будет ли он реагировать на исключения отладки, которые не были установлены в его среде? ) Будет! У меня просто сначала была ошибка - устанавливал DWORD вместо UINT64 )

-----
IZ.RU





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

Создано: 07 октября 2013 18:06
· Личное сообщение · #13

Вся эта махинация с установкой контекста работающего потока андок, посему я бы не рассчитывал, что оно везде будет нормально работать.

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


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 08 октября 2013 02:22
· Личное сообщение · #14

Archer
< 0.001% в данном случае

-----
IZ.RU



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


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