Защита от патчинга в памяти

Тема в разделе "WASM.WIN32", создана пользователем Flasher, 9 окт 2008.

  1. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Есть программа которую надо защитить.
    У этой программы по конкретному адресу в памяти надо не дать чужим программам менять "jl" на "jmp". Как это реализовать без использования дров ?
    В голову приходит только один метод - каждую секунду проверять этот адрес..
    Есть-ли другие способы решения данной проблемки?
    Звучит фантастически, но могет вожможно сместить этот адрес куда-нить другое место ? :)
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Теоретически можно перебазировать сегмент кода где-нибудь по-тихому, а потом обращаться с учетом смещения, и адрес, который будет виден в дизассемблере, не будет соответствовать реальному линейному, можно почитать тут немного.
     
  3. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Перемещать бесполезно. Если прога чемто защищена (запакована), то реверсироваться будет дамп. Так что остается только постоянно считать контрольную сумму своего кода в памяти, и надеяться что код который эту сумму сравнивает не найдут.
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    У меня тоже когдато была эта идея. Оказывается вызов сервиса через Sysenter(KiFastCallEntry), либо Int2e(KiSystemService) восстановит при возврате все сигментные регистры в нормальные значения. Поток сможет обращаться к защищённой памяти только до вызова любого сервиса.
    Как вариант - необходимо перезагружать контекст(сег. регистры) по возврату из сервиса. Если он юзается через Sysenter(KiFastCallEntry), проблем не будет, так как адрес возврата не зависит от адреса Sysenter. По дефолту она и юзается. Просто перехватить KiFastSystemCallRet, либо подменить адрес возврата. Энди ну это ты сам хорошо знаешь. Если юзаетсь Int2e то есть проблема. Обычно приложение может юзать KiIntSystemCall(), тогда тут перехват очевиден. Но приложения юзающие 2е шлюз инструкция вызова которого отличается от KiIntSystemCall - тут могут появиться проблемы. Возврат из прерывания выполняется на следующую инструкцию. Поэтому если ты его юзаешь стави после Int2e инструкцию перехода на хэндлер(если макро то удобно). Хэндлер будет перезагружать контекст.
    GoldFinch
    Не бесполезно, дизасмом это не разобрать.
    Есть функция MmSecureVirtualMemory, один из теневых сервисов позволяет её заюзать, тока не помню какой. Но это наверно не то, защитит память от удаления и изменения прав доступа.
     
  5. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Clerk, не совсем понял :)
    Речь не антихуковских трюках.. если я правильно понял тебя..
    А о том что, есть по статистическому адресу 01D60127h - инструкция "jl"
    Любая иная программа делав вот так
    Код (Text):
    1.            mov byte ptr [JmpBuf],0ebh ;jmp
    2.            invoke ZwWriteVirtualMemory,ProcessHandle,01D60127h,addr JmpBuf,1,0
    смогет изменить jl на jmp. Как этого защитится :)
     
  6. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Clerk
    И действительно, прикольно, а в каком месте это происходит, если не секрет, ну т.е. в KiServiceExit вроде бы достаются из стека сегментные регистры, которые там вроде как должны сохраняться, или я чего-то не догоняю/не замечаю ?
    UPD: все, посмотрел сисером, он действительно жестко забивает в ds, es 23h, но cs - то по идее должен восстанавливаться...
     
  7. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Flasher
    Советую глянуть в сторону ВМ протов (например VMP). При этом никаких дров и сложность реверсинга.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Flasher
    Не правильно понял. Хук чтобы восстанавливать сегментные регистры.
    Velheart
    Восстанавливается в EXIT_ALL. Загружается в ENTER_SYSCALL.
     
  9. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Может баян, и точно оффтоп ), заметил странную штуку:
    при трассировке в сисере такой вот фигни:
    Код (Text):
    1. LDT_Entry dw 0ffffh
    2.  
    3. db 0,10h,40h
    4. db 11111010b
    5. db 11000000b
    6. db 0
    7.  
    8.  
    9. ntdll db "ntdll", 0
    10. NtSetLdtEntries db "NtSetLdtEntries",0
    11. NtClose db "NtClose", 0
    12.  
    13. .code
    14. start:
    15.      
    16.    
    17.     invoke GetModuleHandle, offset ntdll
    18.     push eax
    19.  
    20.     invoke GetProcAddress, eax, offset NtSetLdtEntries
    21.  
    22.         push 0
    23.         push 0
    24.         push 0
    25.         push dword ptr [LDT_Entry+4]
    26.     push dword ptr [LDT_Entry]
    27.     push 1111111b
    28.     call eax
    29.  
    30.     pop eax
    31.     invoke GetProcAddress, eax, offset NtClose
    32.  
    33.    
    34.  
    35.    
    36. ;push   cs
    37. push   01111111b
    38.  
    39. push offset lbl - 401000h
    40.      
    41. retf
    42.    
    43. lbl:
    44.             nop
    45.         mov     eax, 19h        ; NtClose
    46.                mov     edx, 7FFE0300h
    47.            ; sub edx, 401000h    ;Если раскомментировать -- будет бсод при трассировке в Сисере
    48.            ;call edx
    49.  
    50.                call wer
    51.  wer:
    52.               mov edx, esp
    53.               db 0fh, 34h ;sysenter
    54.  
    55.    
    56.  
    57. end start
    выскакивает бсод при попытке call edx, а еще когда-то замечал, что если в коде каллгейта в ядре поставить в сисере брэйк, то после "отпускания" по ф5 тоже бсод..
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Странно очень, позже проверю.
    Тут шлюзы вызовов не причём, если юзается калгейт с установленным TF в юзермоде то конечно будет бсод, ибо начинает исполнятся код с DPL=0, а хэндлер исключений не установлен.
    Походу это кривые хуки сисера. Стоит взглянуть.
    Посмотри аварийный дамп, почему падает и поставь на оригинальный хэндлер исключений(Int ?) бряк в сисире, чтобы узнать контекст и стек сразу после исключения. Условие для точки останова: (PID == #).]
     
  11. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Clerk
    Вот что выяснил:
    бсодит только при обращении к 7FFE0300h и близлежащим адресам, это же вроде бы и есть shared memory, или я что-то путаю? Эксепшн происходит в ядре, в обработчике 0хd прерывания(upd: выяснил, что не знал=) ) припопытке /*тут наврал сначала*/ читать по адресу 0x51, а это -- eip инструкции jmp edx, которая все и бсодит. вот анализ:
    Код (Text):
    1. Microsoft (R) Windows Debugger Version 6.8.0004.0 X86
    2. Copyright (c) Microsoft Corporation. All rights reserved.
    3.  
    4.  
    5. Loading Dump File [D:\WinRvrs\MEMORY.DMP]
    6. Kernel Summary Dump File: Only kernel address space is available
    7.  
    8. Symbol search path is: srv*d:\symbols*http://msdl.microsoft.com/download/symbols
    9. Executable search path is: C:\windows
    10. Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible
    11. Product: WinNt, suite: TerminalServer SingleUserTS
    12. Built by: 2600.xpsp_sp2_rtm.040803-2158
    13. Kernel base = 0x804d7000 PsLoadedModuleList = 0x805531a0
    14. Debug session time: Fri Oct 10 12:05:17.178 2008 (GMT+3)
    15. System Uptime: 0 days 18:52:59.671
    16. Loading Kernel Symbols
    17. ............................................................................................................
    18. Loading User Symbols
    19. PEB is paged out (Peb.Ldr = 7ffdf00c).  Type ".hh dbgerr001" for details
    20. Loading unloaded module list
    21. ...
    22. *******************************************************************************
    23. *                                                                             *
    24. *                        Bugcheck Analysis                                    *
    25. *                                                                             *
    26. *******************************************************************************
    27.  
    28. Use !analyze -v to get detailed debugging information.
    29.  
    30. BugCheck A, {51, 1e, 0, 8053f3be}
    31.  
    32.  
    33. PEB is paged out (Peb.Ldr = 7ffdf00c).  Type ".hh dbgerr001" for details
    34.  
    35. PEB is paged out (Peb.Ldr = 7ffdf00c).  Type ".hh dbgerr001" for details
    36. Probably caused by : ntkrnlpa.exe ( nt!KiTrap0D+48e )
    37.  
    38. Followup: MachineOwner
    39. ---------
    40.  
    41. kd> !analyze -v
    42. *******************************************************************************
    43. *                                                                             *
    44. *                        Bugcheck Analysis                                    *
    45. *                                                                             *
    46. *******************************************************************************
    47.  
    48. IRQL_NOT_LESS_OR_EQUAL (a)
    49. An attempt was made to access a pageable (or completely invalid) address at an
    50. interrupt request level (IRQL) that is too high.  This is usually
    51. caused by drivers using improper addresses.
    52. If a kernel debugger is available get the stack backtrace.
    53. Arguments:
    54. Arg1: 00000051, memory referenced
    55. Arg2: 0000001e, IRQL
    56. Arg3: 00000000, bitfield :
    57.     bit 0 : value 0 = read operation, 1 = write operation
    58.     bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
    59. Arg4: 8053f3be, address which referenced memory
    60.  
    61. Debugging Details:
    62. ------------------
    63.  
    64.  
    65. PEB is paged out (Peb.Ldr = 7ffdf00c).  Type ".hh dbgerr001" for details
    66.  
    67. PEB is paged out (Peb.Ldr = 7ffdf00c).  Type ".hh dbgerr001" for details
    68.  
    69. READ_ADDRESS:  00000051
    70.  
    71. CURRENT_IRQL:  1e
    72.  
    73. FAULTING_IP:
    74. nt!KiTrap0D+48e
    75. 8053f3be ac              lods    byte ptr [esi]
    76.  
    77. DEFAULT_BUCKET_ID:  DRIVER_FAULT
    78.  
    79. BUGCHECK_STR:  0xA
    80.  
    81. PROCESS_NAME:  tst.exe
    82.  
    83. TRAP_FRAME:  f793dce0 -- (.trap 0xfffffffff793dce0)
    84. ErrCode = 00000000
    85. eax=0000000d ebx=817897e8 ecx=0000000f edx=7fbdf300 esi=00000051 edi=00000051
    86. eip=8053f3be esp=f793dd54 ebp=f793dd64 iopl=0         nv up ei ng nz na po cy
    87. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010283
    88. nt!KiTrap0D+0x48e:
    89. 8053f3be ac              lods    byte ptr [esi]             ds:0023:00000051=??
    90. Resetting default scope
    91.  
    92. LAST_CONTROL_TRANSFER:  from 8053f3be to 8053f853
    93.  
    94. STACK_TEXT:  
    95. f793dce0 8053f3be badb0d00 7fbdf300 00401033 nt!KiTrap0E+0x233
    96. f793dd64 00000051 badb0d00 7fbdf300 0000003c nt!KiTrap0D+0x48e
    97. WARNING: Frame IP not in any known module. Following frames may be wrong.
    98. 0012fff0 00000000 00000000 00000000 00000000 0x51
    99.  
    100.  
    101. STACK_COMMAND:  kb
    102.  
    103. FOLLOWUP_IP:
    104. nt!KiTrap0D+48e
    105. 8053f3be ac              lods    byte ptr [esi]
    106.  
    107. SYMBOL_STACK_INDEX:  1
    108.  
    109. SYMBOL_NAME:  nt!KiTrap0D+48e
    110.  
    111. FOLLOWUP_NAME:  MachineOwner
     
  12. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Прикольно получается, бсодит, насколько я понял, в обработчике GP, при попытке читать инструкцию вызвавшую исключение, но при этом eip естественно невалидный, но при чем тут трассировка, ну т.е. должен бсод как бы всегда возникать..
     
  13. Folk Acid

    Folk Acid New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2005
    Сообщения:
    432
    Адрес:
    Ukraine
    Использовать пакер с полиморфной логикой, меняющимся при каждой обработке бинарника.
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Velheart
    Это кривые хуки сисера. При трассировке с заходом в процедуру бсод не возникает. Если не заходить в процедуру, то падает. В этом случае сисер записывает 0xCC(Int3) после Call Edx. Тут неопределённый момент, возникает исключение, которое хэндлеры сисера неправильно обрабатывают. Непонятно почему.
     
  15. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Folk Acid, я не своё тело защищаю, а чужое.. :)