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

 eXeL@B —› Программирование —› Запись в адресное пространство приложения
<< . 1 . 2 . 3 . >>
Посл.ответ Сообщение

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

Создано: 15 февраля 2011 15:53
· Личное сообщение · #1

Есть приложение, которое ставит драйвер хукающий NtOpenProcess и NtQuerySystemInformation, дабы спрятать своё присутствие в списке процессов и не дать открыть свой процесс через OpenProcess.
Задача: писать в память этого процесса.

При восстановлении SDT и снятии хуков приложение начинает работать некорректно, поэтому этот способ отпадает. Я инжекчу свою длл в этот процесс, поэтому в принципе все данные по нему и так есть. И даже из этой длл в его адресное пространство можно писать что угодно. Вопрос вот в чём: как в данной ситуации сделать так, чтобы в память этого процесса могло писать любое другое приложение? Тот же самый ArtMoney?




Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

Создано: 17 февраля 2011 20:27 · Поправил: Nightshade
· Личное сообщение · #2

Драйвер фроста
Код там простой. Думаю так будет проще говорить.

da5d_17.02.2011_CRACKLAB.rU.tgz - frost_32.rar
и вот еще веселый кусок на закусь
Code:
  1. 004118F0    6A FF           PUSH -1
  2. 004118F2    68 8A584500     PUSH 0045588A
  3. 004118F7    64:A1 00000000  MOV EAX,DWORD PTR FS:[0]
  4. 004118FD    50              PUSH EAX
  5. 004118FE    81EC 34010000   SUB ESP,134
  6. 00411904    55              PUSH EBP
  7. 00411905    56              PUSH ESI
  8. 00411906    57              PUSH EDI
  9. 00411907    A1 B0ED4600     MOV EAX,DWORD PTR DS:[46EDB0]
  10. 0041190C    33C4            XOR EAX,ESP
  11. 0041190E    50              PUSH EAX
  12. 0041190F    8D8424 44010000 LEA EAX,DWORD PTR SS:[ESP+144]
  13. 00411916    64:A3 00000000  MOV DWORD PTR FS:[0],EAX
  14. 0041191C    8BE9            MOV EBP,ECX
  15. 0041191E    6A 44           PUSH 44
  16. 00411920    8D4424 1C       LEA EAX,DWORD PTR SS:[ESP+1C]
  17. 00411924    6A 00           PUSH 0
  18. 00411926    50              PUSH EAX
  19. 00411927    E8 046D0200     CALL 00438630
  20. 0041192C    83C4 0C         ADD ESP,0C
  21. 0041192F    68 7CA04500     PUSH 0045A07C                            ; ASCII "ntdll.dll"
  22. 00411934    FF15 68834500   CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; kernel32.GetModuleHandleA
  23. 0041193A    8B8C24 54010000 MOV ECX,DWORD PTR SS:[ESP+154]
  24. 00411941    8B3D 9C834500   MOV EDI,DWORD PTR DS:[<&KERNEL32.GetProc>; kernel32.GetProcAddress
  25. 00411947    8BF0            MOV ESI,EAX
  26. 00411949    68 88A04500     PUSH 0045A088                            ; ASCII "ZwOpenProcess"
  27. 0041194E    56              PUSH ESI
  28. 0041194F    894C24 20       MOV DWORD PTR SS:[ESP+20],ECX
  29. 00411953    FFD7            CALL EDI
  30. 00411955    85C0            TEST EAX,EAX
  31. 00411957    74 03           JE SHORT 0041195C
  32. 00411959    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  33. 0041195C    68 98A04500     PUSH 0045A098                            ; ASCII "ZwQuerySystemInformation"
  34. 00411961    56              PUSH ESI
  35. 00411962    894424 34       MOV DWORD PTR SS:[ESP+34],EAX
  36. 00411966    FFD7            CALL EDI
  37. 00411968    85C0            TEST EAX,EAX
  38. 0041196A    74 03           JE SHORT 0041196F
  39. 0041196C    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  40. 0041196F    68 B4A04500     PUSH 0045A0B4                            ; ASCII "ZwQueryVirtualMemory"
  41. 00411974    56              PUSH ESI
  42. 00411975    894424 3C       MOV DWORD PTR SS:[ESP+3C],EAX
  43. 00411979    FFD7            CALL EDI
  44. 0041197B    85C0            TEST EAX,EAX
  45. 0041197D    74 03           JE SHORT 00411982
  46. 0041197F    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  47. 00411982    68 CCA04500     PUSH 0045A0CC                            ; ASCII "ZwReadVirtualMemory"
  48. 00411987    56              PUSH ESI
  49. 00411988    894424 54       MOV DWORD PTR SS:[ESP+54],EAX
  50. 0041198C    FFD7            CALL EDI
  51. 0041198E    85C0            TEST EAX,EAX
  52. 00411990    74 03           JE SHORT 00411995
  53. 00411992    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  54. 00411995    68 E0A04500     PUSH 0045A0E0                            ; ASCII "ZwWriteVirtualMemory"
  55. 0041199A    56              PUSH ESI
  56. 0041199B    894424 44       MOV DWORD PTR SS:[ESP+44],EAX
  57. 0041199F    FFD7            CALL EDI
  58. 004119A1    85C0            TEST EAX,EAX
  59. 004119A3    74 03           JE SHORT 004119A8
  60. 004119A5    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  61. 004119A8    68 F8A04500     PUSH 0045A0F8                            ; ASCII "NtDuplicateObject"
  62. 004119AD    56              PUSH ESI
  63. 004119AE    894424 4C       MOV DWORD PTR SS:[ESP+4C],EAX
  64. 004119B2    FFD7            CALL EDI
  65. 004119B4    85C0            TEST EAX,EAX
  66. 004119B6    74 03           JE SHORT 004119BB
  67. 004119B8    8B40 01         MOV EAX,DWORD PTR DS:[EAX+1]
  68. 004119BB    8D5424 18       LEA EDX,DWORD PTR SS:[ESP+18]
  69. 004119BF    52              PUSH EDX
  70. 004119C0    894424 58       MOV DWORD PTR SS:[ESP+58],EAX
  71. 004119C4    E8 E7EBFFFF     CALL 004105B0
  72. 004119C9    83C4 04         ADD ESP,4
  73. 004119CC    8D4424 5C       LEA EAX,DWORD PTR SS:[ESP+5C]
  74. 004119D0    50              PUSH EAX
  75. 004119D1    FF15 64834500   CALL DWORD PTR DS:[<&KERNEL32.GetSystemI>; kernel32.GetSystemInfo
  76. 004119D7    8B4C24 60       MOV ECX,DWORD PTR SS:[ESP+60]
  77. 004119DB    894C24 28       MOV DWORD PTR SS:[ESP+28],ECX
  78. 004119DF    8D4C24 18       LEA ECX,DWORD PTR SS:[ESP+18]
  79. 004119E3    E8 78E4FFFF     CALL 0040FE60
  80. 004119E8    6A 00           PUSH 0
  81. 004119EA    8D5424 18       LEA EDX,DWORD PTR SS:[ESP+18]
  82. 004119EE    52              PUSH EDX
  83. 004119EF    8B55 00         MOV EDX,DWORD PTR SS:[EBP]
  84. 004119F2    6A 04           PUSH 4
  85. 004119F4    8D4424 1C       LEA EAX,DWORD PTR SS:[ESP+1C]
  86. 004119F8    50              PUSH EAX
  87. 004119F9    6A 44           PUSH 44
  88. 004119FB    8D4C24 2C       LEA ECX,DWORD PTR SS:[ESP+2C]
  89. 004119FF    51              PUSH ECX
  90. 00411A00    68 0824409C     PUSH 9C402408
  91. 00411A05    52              PUSH EDX
  92. 00411A06    C74424 30 00000>MOV DWORD PTR SS:[ESP+30],0
  93. 00411A0E    C74424 34 00000>MOV DWORD PTR SS:[ESP+34],0
  94. 00411A16    FF15 84834500   CALL DWORD PTR DS:[<&KERNEL32.DeviceIoCo>; kernel32.DeviceIoControl
  95.  
  96.  





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

Создано: 18 февраля 2011 09:43
· Личное сообщение · #3

Дело было вечером, делать было нечего. Родился такой немного безумный алгоритм. Идея основана на том, что существует некоторое приложение, защищённое фростом (причём, возможно, его модификация отличается от вышеописанной, и заранее мы не знаем, сколько функций он перехватил в _KiServiceTable), а также есть чит, который либо полностью выполнен в виде исполняемого файла (экзешника), либо существует загрузчик, который посредством каких-то манипуляций в третьем кольце подгружает свои компоненты в приложение, защищённое фростом (целевое). Задача – скрыть чит от фроста, и выполнять все функции чита так, как если бы фроста не существовало. Т.е. если нужно открыть целевой процесс, то чит вызывает OpenProcess с идентификатором целевого процесса, и в ответ получает дескриптор.
Метод реализации такой. Сам экзешник чита запускаем с флагом CREATE_SUSPENDED, далее подгружаем свой дров, который по технологии DKOM скроет процесс чита. Вызываем ResumeThread. Теперь нам нужно в ядре выделить NonPagedPool память для размещения адресов из _KiServiceTable. Логично, что для начала нам нужно эти самые адреса найти. Сделать это можно так – известно, что неэкспортируемая KiInitSystem() в ntoskrnl.exe (или аналогичном) выполняет инициализацию экспортируемой KeServiceDescriptorTable вот так:
Code:
  1. mov     ds:_KeServiceDescriptorTable, offset _KiServiceTable

Собственно, именно offset _KiServiceTable указывает на те значения адресов функций, которые патчатся фростом. НО! На диске в файле ntoskrnl.exe эти значения хранятся в своём первородном виде, поэтому скопировав их оттуда (предварительно пересчитав в соответствии с базой образа ядра), мы получим неперхваченную KiServiceTable. Однако, как же найти этот адрес _KiServiceTable в файле на диске?
Code:
  1. INIT:005EF2F4                 mov     ds:_KeServiceDescriptorTable, offset _KiServiceTable
  2. INIT:005EF2FE                 mov     ds:dword_48B524, esi
  3. INIT:005EF304                 mov     ds:dword_48B52C, offset _KiArgumentTable
  4. INIT:005EF30E                 mov     eax, ecx
  5. INIT:005EF310
  6. INIT:005EF310 loc_5EF310:                             ; CODE XREF: KiInitSystem()+13Dj
  7. INIT:005EF310                 mov     ds:dword_48B528[eax], esi
  8. INIT:005EF316                 add     eax, ecx
  9. INIT:005EF318                 cmp     eax, 40h
  10. INIT:005EF31B                 jb      short loc_5EF310
  11. INIT:005EF31D                 mov     esi, offset _KeServiceDescriptorTable
  12. INIT:005EF322                 mov     edi, offset _KeServiceDescriptorTableShadow


KeServiceDescriptorTable – экспортируемое значение, KeServiceDescriptorTableShadow – можно найти. На основе двух этих значений можно организовать сигнатурный плавающий поиск, т.е. на случай, если между ними (этими значениями) код может варьироваться от версии к версии Windows, то можно найти одно значение, например, первое вхождение KeServiceDescriptorTable, потом предположить, что второе вхождение этого значения может быть в промежутке от +24h до +2Еh и т.д. Ясно, что вхождения следует искать внутри модуля ntoskrnl.exe, ImageBase и ImageSize которого можно найти даже с помощью перехваченной NtQuerySystemInformation и даже в юзермоде. (можно юзать значение KiServiceTable, полученное разыменовываением KeServiceDescriptorTable в памяти, если не боитесь, что оно будет перехвачено новыми версиями фроста).

Далее, вот мы получили оригинальную KiServiceTable в нашем выделенном участке ядерной неподкачиваемой памяти. Теперь следующее. В ntdll.dll загруженного в память чита ищем вот это:

Code:
  1. 7C90CE40 Z>  B8 00000000     MOV EAX,0
  2. 7C90CE45     BA 0003FE7F     MOV EDX,7FFE0300
  3. 7C90CE4A     FF12            CALL NEAR DWORD PTR DS:[EDX]
  4. 7C90CE4C     C2 1800         RETN 18


7FFE0300 – может варьироваться от системы к системе. Так начинается сервис ZwAcceptConnectPort (но не факт), я не знаю утилит или руткитов, которые бы его хукали сплайсингом, поэтому на оригинальность кода можно положиться (или не положиться, и читать код с диска). Короче, найдя этот код по сигнатуре, мы будем знать начало перехводников, которые обращаются к ядру, и, в конечном итоге, к KiServiceTable. Фишка в том, что заполняя нашу ядерную выделенную память нехученными значениями сервисов, мы можем узнать их количество (конец – начало / 4). Так мы будем знать, сколько всего переходников нам нужно поправить. Но на что поправить?

Давайте вспомним, как происходит вызов ядерных функций в KiServiceTable. Номер из юзермода умножается на 4, прибавляется к offset _KiServiceTable, и полученный указатель разыменовывается. Но до этого, чтоб получить offset _KiServiceTable, разыменовывается offset _KeServiceDescriptorTable:

Code:
  1. .text:00406983 mov     edi, [edi]
  2. .text:00406985 mov     ebx, [edi+eax*4]


Значения KeServiceDescriptorTable и KiServiceTable патчить нельзя, тогда остаётся так выбрать номер сервиса, чтоб получить нужный нам адрес, на который потом передастся управление. Т.е. например, (глядя на вышеприведенный ассемблерный код) после первой инструкции edi = 00890540h (адреса взяты из головы для примера). После второй инструкции ebx должен быть равен 00956000 h, что соответствует адресу неперехваченной функции. Как этого добиться? Предположим, что значение 00956000h расположено по адресу 00905030h. Тогда edi+eax*4 должно равняться 00905030h. Отсюда еах = (00905030h – edi) / 4 -> еах = (00905030h – 00890540h) / 4 = 1D2BCh.

Даже если результат будет отрицательный, это – не проблема, поскольку номера имеют размер ULONG. Единственное, что следует упомянуть, так это то, что память должна быть выделена так, чтобы разность делилась на 4, но в описании ExAllocatePoolWithTag не говориться, как это сделать (возможно, никак с её помощью), поэтому придётся выделить на 1 DWORD памяти больше, чем нужно, и с помощью вычислений добиться расположения первого значения так, чтоб (00905030h – edi) подобная разность делилась на 4 нацело.

Теперь, когда всё готово, на финальном этапе с помощью VirtualProtectEx + WriteProcessMemory в адресном пространстве чита мы можем перенастроить переходники – переписать номера сервисов.

При завершении чита драйвер должен освобождать память, ранее выделяемую под неперехваченную таблицу. Это достигается установкой нотификатора через PsSetCreateProcessNotifyRoutine.

Так можно положить болт на всякие модификации этого грёбаного фроста, или нельзя, если я что-то упустил. Жду комментариев.

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





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 18 февраля 2011 11:00
· Личное сообщение · #4

Так можно и в ring3 сделать, как посоветовал арчи, и будет надежнее чем эмпирическое вычисление значений по сигнатурам. ИМХО конечно.

-----
Yann Tiersen best and do not fuck





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

Создано: 18 февраля 2011 14:49
· Личное сообщение · #5

PE_Kill
Можно, но если фрост перехватит новые функции, то придётся заново сидеть и думать, как в каждом конкретном случае эмулировать тот или иной сервис. Да, в общем случае поддерживать всю линейку Windows будет не самой простой задачей, но добиться работоспособности на конкретной оси (например, ХР SP3, даже на всём семействе ХР) я думаю, вполне реально.

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





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 18 февраля 2011 15:02
· Личное сообщение · #6

Nightshade а что если просто подменить адреса функций в этом месте)))) на что-нить ненужное.

-----
[nice coder and reverser]





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

Создано: 18 февраля 2011 15:04
· Личное сообщение · #7

Hellspawn

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

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





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 18 февраля 2011 15:05
· Личное сообщение · #8

ARCHANGEL а если подумать? не адрес другого сервиса ей дать, а ... и тут много вариантов

-----
[nice coder and reverser]





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

Создано: 18 февраля 2011 15:11 · Поправил: ARCHANGEL
· Личное сообщение · #9

Hellspawn

Ну, если подумать, то можно так: сторонняя библиотека подгружается в АП приложения, защищённого фростом, хукается ЕР, чтоб либа отработала до начала исполнения кода, далее либа перехватывает GetProcAddress и вместо адреса того же ZwOpenProcess подсовывает какую-нибудь оччччень редко используемую функу (причём на все функции, которые нужно оставить неперехваченными, подсовывается один и тот же адрес). Тогда есть шанс, но опять же, при малейшем апдейте всё придётся переделывать.

Добавлено
типа, чтоб она перехватила что-то левое в ядре, которое никогда не выполнится? Да, но если нельзя патчить ничего из файлов фроста (даже в памяти нельзя менять), то это не получится сделать.

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





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 18 февраля 2011 15:13
· Личное сообщение · #10

хукнуть DeviceIoControl, и редактировать буфер ловить нужную отправку.

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

-----
[nice coder and reverser]





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

Создано: 18 февраля 2011 15:21
· Личное сообщение · #11

Hellspawn

А что вы собираетесь ловить? И на что менять?

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





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 18 февраля 2011 15:24
· Личное сообщение · #12

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

-----
[nice coder and reverser]





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

Создано: 18 февраля 2011 15:35
· Личное сообщение · #13

я ничего не собираюсь, мне это не интересно, т.к. читами не пользуюсь.

Понял.

Ну вот если б товарищи геймеры скинулись по чуть-чуть (я не жадный), я б им что-то накодил бы, что б читилось хорошо, а так - нет времени.

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





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 18 февраля 2011 17:12
· Личное сообщение · #14

Я говорил не про эмуляцию сервиса, а про создание интерфейса внутри игры и подгрузку своей библиотеки-провайдера в адресное пространство чита. Перехватываем в чите апи работы с процессами, генерим инвалидный специфичный хендл при NtOpenProcess (DEADC0DE например), а все остальные апи фильтруют хендлы, если попадается наш хендл, то через ту же шаред мемори эмулируем апи, редиректя запросы на длл внутри игры. За вечер вполне можно сделать ну и вечер на отладку и при этом не трогаем дров и всё красиво и универсально. С другой стороны под силу ли это ТС.

-----
Yann Tiersen best and do not fuck





Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 18 февраля 2011 18:00 · Поправил: ajax
· Личное сообщение · #15

PE_Kill
Было бы под силу, топик бы не возник
А в дрова нет смысла лезть без ну очень крайней необходимости. Даже в pace это особо не требовалось.

-----
От многой мудрости много скорби, и умножающий знание умножает печаль




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

Создано: 18 февраля 2011 21:17
· Личное сообщение · #16

ARCHANGEL
> как же найти этот адрес _KiServiceTable

1. Менеджер сискалов берёт линк на SDT из описателя текущего потока, это ETHREAD.ServiceTable. Это значение не может быть изменено до конвертации потока в гуи.
2. Обычно SST не перемещают в памяти, хотя этому ничто не мешает.

Можно переместить всю сст в нужное место. Можно вобще погрузить ядро и загрузить в сст ссылку на содержащуюся в нём таблицу(да и вобще перенаправить вызовы сервисов на оригинальные в новой проекции).

> значениями сервисов, мы можем узнать их количество (конец – начало / 4). Так мы будем знать, сколько всего переходников нам нужно поправить.
Число их описано в SST.



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

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

Для XP фрост ломается из юзермода патчем драйвера (чтобы выкинуть нотификаторы и не лезть в ядро), исправлением SDT через гейт physicalmemory, перенаправлением загрузки драйвера (хук CreateServiceW - там именно так загружается дров) и убийством "теневого" контрольного потока в защищаемом процессе (там на самом деле их несколько, какой из них прибить - дело другое))

-----
продавец резиновых утёнков




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

Создано: 19 февраля 2011 13:25 · Поправил: Clerk
· Личное сообщение · #18

ARCHANGEL
Не поленился собрать пруфкод. Всё завязано на графы. Для поиска IDT используем также анализ графа. Находим KiSystemService(), далее kssdoit и интегрируем на это место наш код. И этот код может быть загружен в дескрипторы для сервисного прерывания. Для фастколов необходимо поправить линк в #DB. Вот исходный менеджер:
http://img607.imageshack.us/i/30253296.png/
Вот конечный:
http://img810.imageshack.us/i/outm.png/
Разумеется это не полноценный код, а только пример показывающий на сколько просто такие манипуляции выполнять.

218f_19.02.2011_CRACKLAB.rU.tgz - Service.zip




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

Создано: 21 февраля 2011 09:54 · Поправил: ARCHANGEL
· Личное сообщение · #19

Уфф, начну по порядку.

Мой вышеприведенный алгоритм требует переработки. Дело в том, что нельзя (без патчинга ядра) вызывать сервисы по произвольным номерам (стандартно). Т.е., для примера, такой код:

Code:
  1. 7C90CE40 Z>  B8 00000000     MOV EAX,0
  2. 7C90CE45     BA 0003FE7F     MOV EDX,7FFE0300
  3. 7C90CE4A     FF12            CALL NEAR DWORD PTR DS:[EDX]
  4. 7C90CE4C     C2 1800         RETN 18


Прекрасно отработает, а вот такой:

Code:
  1. 7C90CE40 Z>  B8 00000000     MOV EAX,888895
  2. 7C90CE45     BA 0003FE7F     MOV EDX,7FFE0300
  3. 7C90CE4A     FF12            CALL NEAR DWORD PTR DS:[EDX]
  4. 7C90CE4C     C2 1800         RETN 18


Вернёт ошибку о неверной функции. Дело в том, что номера сервисов в ядре проходят проверку на валидность, а именно внутри _KiSystemService выполняется такой код:

Code:
  1. .text:00406944 and     eax, 0FFFh
  2. .text:00406949 cmp     eax, [edi+8]
  3. .text:0040694C jnb     _KiBBTUnexpectedRange


(кстати, видно на рисунке Clerk'a )Не трудно догадаться, что в еах – номер сервиса. Во второй строчке он сравнивается с общим числом сервисов, что происходит дальше – очевидно из имени метки. Но самым интересным является то, что число сервисов берётся не из SYSTEM_SERVICE_TABLE, на которую указывает KeServiceDescriptorTable. Оно берётся из её копии, на которую указывает ETHREAD.ServiceTable потока. Изменив эту копию (подсунув туда адрес непадченной KiServiceTable) можно добиться работы в обход перехватов. Как писал Great, это поле очень интересно (Clerk, сэнкс, что обратили на него моё внимание), но Great (в своей статье "Планировщик, потоки и процессы") писал неверно, что оно содержит содержимое (простите за повторы) либо KeServiceDescriptorTable, либо KeServiceDescriptorTableShadow. Оно содержит либо KeServiceDescriptorTable, либо обе, если поток стал Gui. Я тож собрал пруфкод, но пока ещё не до конца отладил - не разобрался, как принудительно конвертить поток в ГУИ, если я не могу исполнять код в его адресном пространстве. Думаю, через пару дней выложу.

Далее, дизасм драйвера, выложенного Nightshade, дал результаты. Во-первых, сокрытие по DKOM не даст результата, поскольку дров фроста ставит нотификаторы на создание процесса и загрузку модулей – он всё равно всё сдетектит. Поэтому мы пойдём другим путём. Давайте подумаем, что он конкретно может сдетектить. Имя и контрольную сумму части образа. Поэтому переименовываем чит и упаковываем его любым упаковщиком на выбор. Но, если фрост в будущем (в текущей версии я не видел таких проверок) будет юзать поиск по объектам ядра (мьютексам, событиям, именованым каналам и т.д.), опираясь на конкретные имена, то от этого, в общем случае, не защититься.

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

Ну, в общем, пока всё, будут отлаживать свой код, чтоб было, что показать. В связи с отладкой вот таккой вот вопрос, прямо не касающийся фроста, но, может, кто знает. Скачал я с офсайта отладочные символы для ХР, стал их юзать, и понял, что нифига-то символы не загружаются, то ли не подходят, то ли хз ещё что. Тогда подгрузил символы из WinDbg (скачанные через него), и всё запахало. Но для Семёрки я не могу подгрузить символы из WinDbg, где бы достать нормальные?

HiEndsoft
Как вы используете PhysicalMemory на XP SP3?

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




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

Создано: 21 февраля 2011 21:48
· Личное сообщение · #20

ARCHANGEL
> Я тож собрал пруфкод, но пока ещё не до конца отладил - не разобрался, как принудительно конвертить поток в ГУИ, если я не могу исполнять код в его адресном пространстве.
Поток в гуи конвертирует функа PsConvertToGuiThread(), она загружает теневую сст и расширяет ядерный стек. Можно дёрнуть для этого любой теневой сервис, но при этом понадобится както обойти вызов пользовательского apfn-колбека. Ну с этим проблем вобщем не должно быть.
Шадов не доступен из процесса System не потому, что поток не гуи, а потомучто шадов находится в адресном пространстве сессии и для отображения туда его нужно выполнить аттач, тоже и для иных сессий. Для этого нужно дёрнуть MmAttachSession(), напрямую никак, но можно через колбек ExpWin32SessionCallout, вызываемый из ObjectType-процедур для обьекта "Desktop". Дето был пруфкод мой в инетах..
Обычно это в пределах текущей сессии не делают, а просто выполняют аттач к гуи-процессу(например csrss по имени порта и тп.).



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 22 февраля 2011 01:31
· Личное сообщение · #21

ARCHANGEL пишет:
Как вы используете PhysicalMemory на XP SP3?

ошибся server2003sp2 была тогда. а вообще достаточно драйвер пропатчить, в другое место его переместить и на него через хук CreateServiceW (или LdrLoadDriver) перенапралять.

-----
продавец резиновых утёнков





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

Создано: 22 февраля 2011 10:34
· Личное сообщение · #22

Clerk пишет:
Можно дёрнуть для этого любой теневой сервис

Да, я так и делаю. Про PsConvertToGuiThread прочитал у Great'a, да и после перехода на _KiBBTUnexpectedRange там через несколько инструкций её вызов идёт, а выполнять код в АП требуемого процесса решил через APC. Пока вот прикладываю PoC. На картинках запусщенный HideTools с установленым драйвером, RKU показывает наличие перехватов HideTools, чтоб не подумали, будто их кто-то снял. А Pe Tools перенастроен так, что все его потоки обращаются к чистой KiServiceTable. Соответственно, Pe Tools палит HideTools.

Шадов не доступен из процесса System
Не вижу необходимости делать его там доступным.

Clerk
Скачал ваш код, посмотрел, хотелось бы задать вам несколько вопросов, но, думаю, что они не будут прямо относиться к теме топика, поэтому позже (1-2 дня на продумывание, может, сам догадаюсь) стукну в личку. Странно, что больше тут никто ничего по этому поводу не написал, наверное, всем остальным и так всё ясно.


7c61_21.02.2011_CRACKLAB.rU.tgz - Archive.rar

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




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

Создано: 22 февраля 2011 18:23
· Личное сообщение · #23

ARCHANGEL
> а выполнять код в АП требуемого процесса решил через APC.
Для этого есть Ke[Stack]AttachProcess().

> Скачал ваш код, посмотрел, хотелось бы задать вам несколько вопросов
Спрашивайте.




Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 22 февраля 2011 18:38
· Личное сообщение · #24

ARCHANGEL пишет:
Странно, что больше тут никто ничего по этому поводу не написал, наверное, всем остальным и так всё ясно.

Остальные либо шарят, либо "курят" в сторонке (в т.ч. я

-----
От многой мудрости много скорби, и умножающий знание умножает печаль





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

Создано: 23 февраля 2011 10:51
· Личное сообщение · #25

Clerk пишет:
Для этого есть Ke[Stack]AttachProcess().


Наконец-то собрал всё воедино, и выкладываю рабочий загрузчик процессов. В архиве батник, в котором описан пример запуска блокнота через загрузчик. Просьба потетсить на фросте (у кого есть такая возможность), т.е. посмотреть, заработали ли читы (тот же артмани). Загрузчик совместим пока только с ХР, но если кому-то очень надо - пишите, будем что-то решать с более новыми ядрами.



54fe_22.02.2011_CRACKLAB.rU.tgz - Release.rar

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




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

Создано: 23 февраля 2011 17:34 · Поправил: Clerk
· Личное сообщение · #26

ARCHANGEL
Стрёмно запускать, впрочем как и вам мои кодесы =))



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 23 февраля 2011 20:33
· Личное сообщение · #27

ARCHANGEL
Unable to create Process N
WinXP x32 SP3

-----
продавец резиновых утёнков





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

Создано: 24 февраля 2011 09:43
· Личное сообщение · #28

HiEndsoft
Хм, а в отладчике не смотрели, почему процесс не создаётся? Мало ли, мож имя не то, или нет такого процесса, попробуйте полный адрес задать, или если через батник пользуйетесь, то кириллицу из полного адреса убрать.

Clerk
Ну, так вы под варей попробуйте, хотя б просто запускается ли, работает ли и т.д.

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




Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 24 февраля 2011 13:03 · Поправил: HiEndsoft
· Личное сообщение · #29

ARCHANGEL пишет:
Хм, а в отладчике не смотрели, почему процесс не создаётся?

--если честно времени нет;
Мало ли, мож имя не то, или нет такого процесса, попробуйте полный адрес задать, или если через батник пользуйетесь, то кириллицу из полного адреса убрать.
-- получилось заинжектится только если файл notepad'a лежит в одной папке с вашей прогой (раньше в system32 был). Функционал посмотрю позже

-----
продавец резиновых утёнков




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

Создано: 05 марта 2011 08:32
· Личное сообщение · #30

ARCHANGEL этот код вообще работает?




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

Создано: 06 марта 2011 17:53
· Личное сообщение · #31

kannabis
работает

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



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


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