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

 eXeL@B —› Программирование —› Ring0 Трассировщик
Посл.ответ Сообщение


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

Создано: 07 апреля 2011 10:30
· Личное сообщение · #1

Привет, товарищи. Назрел вопрос такого характера. Допустим, я пишу динамический распаковщик, отладочное ядро которого не использует Debug API, а используется перехват исключений в ядре. С IDT и с тем, как её перехватить - всё понятно. Как создать список бряков, где его хранить - тоже нет проблем. Но смотрите, предположим, что я влепил опкод СС в отлаживаемом приложении. Приложение выполнялось-выполнялось, и долшло до этого опкода. Генерируется иксепшн, вызывается мой обработчик. Внутри обработчика оказывается, что сработал бряк, который остановил программу на ОЕР, и сейчас нужно снять дамп. Дамп я хочу снять простым ReadProcessMemory. Как мне снять дамп из моего распаковщика, одновременно с этим стоя на ОЕР? Ведь если мой обработчик KiTrap03 вернёт управление, то продолжится исполнение программы, а мне этого никак нельзя допустить, пока код ещё не сдампился. Объясните, хотя б в теории, как быть. Примеры реализации не обязательны, т.к. где ж и х взять. Достаточно теоретических выкладок. Жду ответов.

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





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

Создано: 07 апреля 2011 10:45
· Личное сообщение · #2

Зависит от реализации обработчика. Если там костыль с разрешением прерываний, возьми да в спячку поток отправь.
Всё это в стриппере от сида реализовано уже лет 5 назад было.



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

Создано: 07 апреля 2011 10:49
· Личное сообщение · #3

ARCHANGEL пишет:
С IDT и с тем, как её перехватить - всё понятно

Еще бы понять что делать с PatchGuard чтобы работало стабильно и везде...


ARCHANGEL пишет:
Объясните, хотя б в теории, как быть.

Сначала нам надо получить нормальный кернелмодный контекст чтобы вызывать апи. Как это сделать - смотри сорс KiTrap03. А лучше сразу хукай KiDispatchException, получишь всё в готовом виде. Как прочитать память - сделай memcpy внутри блока try/except находясь на IRQL = PASSIVE_LEVEL

-----
PGP key <0x1B6A24550F33E44A>





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

Создано: 07 апреля 2011 10:50 · Поправил: ARCHANGEL
· Личное сообщение · #4

Т.е., грубо говоря, трассировщик должен постоянно опрашивать какую-то переменную ядра, как только она стала равной 1, значит бряк сработал. Далее вызываю SuspendThread для потока, в контексте которого сработал бряк, обработчик исключений возвращает управление, а мой распаковщик спокойно делает ReadProcessMemory, после чего переменная состояния в ядре обнуляется. Где-то так? А без циклических опросов никак нельзя?

ntldr
По боку патчгард, пока не до него.

У вас получается, что дампить надо из ядра, даже из самого обработчика, но не факт, что IRQL == PASSIVE_LEVEL внутри него. А читать довольно большие объёмы инфы в NonPagedPool не хочется.

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





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

Создано: 07 апреля 2011 10:52
· Личное сообщение · #5

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



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

Создано: 07 апреля 2011 10:53
· Личное сообщение · #6

ARCHANGEL пишет:
А без циклических опросов никак нельзя?

Я же сказал что можно. Хукаем KiDispatchException или повторяем код идущий перед ней вручную, и мы получим нормальный кернелмодный контекст в котором можно вызывать апи. А там можно будет сделать синхронизацию евентами, передавать сообщения в р3 через APC, и.т.д.

-----
PGP key <0x1B6A24550F33E44A>





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

Создано: 07 апреля 2011 10:56 · Поправил: ARCHANGEL
· Личное сообщение · #7

Archer пишет:
Вот только никто не обещает, что после костыля с разрешением прерываний они будут кошерно работать.

Вот в этом-то вся и проблема, я не уверен, будут ли ивенты работать, т.к. их внутри обработчика юзать нельзя, наверное. Плюс SMP - можно ли с помощью аффинити масок заставить отлаживаемое приложение выполняться только на каком-то одном процессоре?

ntldr
Ок, посмотрю, попробую.

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




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

Создано: 07 апреля 2011 10:56
· Личное сообщение · #8

ARCHANGEL пишет:
У вас получается, что дампить надо из ядра, даже из самого обработчика

Не обязательно. Можно сделать синхронизацию и читать как угодно.

ARCHANGEL пишет:
но не факт, что IRQL == PASSIVE_LEVEL внутри него

Внутри обработчика вообще прерывания запрещены. Сначала надо настроить fs, IRQL, PreviousMode и все остальное что делает KiTrap03. После этого делай что хочешь любыми апи.

-----
PGP key <0x1B6A24550F33E44A>




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

Создано: 07 апреля 2011 11:01
· Личное сообщение · #9

ARCHANGEL
Самое простое для тебя решение - похукать KiDispatchException библиотекой http://code.google.com/p/libsplice/

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 07 апреля 2011 15:26
· Личное сообщение · #10

ntldr пишет:
похукать KiDispatchException библиотекой http://code.google.com/p/libsplice/

Зачем же так? Пусть сразу к нам в команду идет)



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

Создано: 07 апреля 2011 15:55
· Личное сообщение · #11

ntldr пишет:
Самое простое для тебя решение - похукать KiDispatchException библиотекой http://code.google.com/p/libsplice/

С libsplice будут проблемы с х64, причем именно при хуке KiDispatchException, есть большая вероятность получить BSOD, почему он происходит для меня пока загадка, возможно потому что стабильно срабатывает какое-либо исключение при хуке. Вобщем то на этом и я сам застопорился когда писал opendbg.
А в х86 там проблем нет.




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

Создано: 07 апреля 2011 16:24
· Личное сообщение · #12

Vol4ok
анхук не предусмотрен, или я не те сырки глядел
и, вопрос - почему не юзать HDE 32/64 как дизасм длин?

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




Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 07 апреля 2011 16:54
· Личное сообщение · #13

ajax пишет:
анхук не предусмотрен

Нет, не предусмотрен. Я ему предлагал алгоритм почти безопасного анхука, он не стал реализовывать.

ajax пишет:
почему не юзать HDE 32/64 как дизасм длин?

лол, потому что он дерьмо



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

Создано: 08 апреля 2011 02:15 · Поправил: Vol4ok
· Личное сообщение · #14

ajax пишет:
анхук не предусмотрен, или я не те сырки глядел

Анхук не предусмотрен, хотя я хотел изначально я его предусматривал, но пришел к выводу что это практически невозможно сделать безопастно в ядре, т е ВСЕГДА есть вероятность получить БСОД, причем вероятность больше чем при установке. Нет никаких гарантий что в какой либо системный тред не окажется на коде обработчика хука во время анхука (особенно для таких функций как KiDispatchException), и на практике это проверить крайне сложно, и даже если проверить то еще сложнее устранить. Цель не оправдывает средства, зачем же тогда писать кучу заведомо кривого кода.

ajax пишет:
и, вопрос - почему не юзать HDE 32/64 как дизасм длин?

Хороший вопрос. Я изучал имеющиеся движки дизасмов прежде чем сел писать свой, в том числе HDE, на который вобщем то сам изначально полагался, но увы, выявил в х64 версии ряд фатальных косяков, которые касались определения инструкций с относительной адресацией, да и не только это, сча уже не могу вспомнить всего. Я связывался с автором на предмет фикса, но автор сказал что не имеет возможности серьезно заниматься поддержкой своего проекта и поэтому фиксить в ближайшее время не планирует. Хотя HDE 32 работает норм.



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 08 апреля 2011 11:34
· Личное сообщение · #15

Vol4ok
Я же предлагал тебе расставлять "кардоны". Вот давай я твой код поправлю и дам тебе на тестирование? Гарантирую, что это примерно также опасно, как и ставить хук.



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

Создано: 08 апреля 2011 12:14
· Личное сообщение · #16

int пишет:
Я же предлагал тебе расставлять "кардоны". Вот давай я твой код поправлю и дам тебе на тестирование? Гарантирую, что это примерно также опасно, как и ставить хук.

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



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 08 апреля 2011 13:51
· Личное сообщение · #17

Vol4ok
Там один байт изменяется во время анхука))) Риск только в том, что время ожидания завершения функции будет больше чем задумано. Т.е. пока модули вертятся в бесконечном цикле, наш дров снимает хук патчем байта в jmp. Т.е. возможна ситуация при анхуке определенных API, что возникнет синяк, когда один из модулей не сможет отработать эту API. Также возможно зависание, когда наш анхукер никогда не получит управление, пока хуки не будут сняты, а их снять будет некому.




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

Создано: 12 апреля 2011 09:56
· Личное сообщение · #18

Смотрел, думал - возник вопрос такого характера. Для того, чтоб иметь возможность вызывать ядерные API после возникновения иксепшена мне нужно воспроизвести только лишь макрос ENTER_TRAP, или ещё обязательно лезть в CommonDispatchException? Вопрос возник, т.к. выше советуют хукать KiDispatchException, но мне нужно, чтоб при срабатывании моего брейкпоинта исключение не разворачивалось в юзермоде. Т.е. зачем мне выполнение юзермодного кода в отлаживаемом приложении с KiUserExceptionDispatcher? В случае, если мой обработчик обнаруживает, что возникло исключение в моей точке останова, я должен адекватно отреагировать (сдампить, поставить другой брейкпоинт, трейсить...), после чего iret возвратит управление из KiTrap. Но если я перехвачу CommonDispatchException и далее, то управление никогда не вернётся назад в случае, если CommonDispatchException начнёт выполнятся. Или я чего-то не понял?

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




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

Создано: 12 апреля 2011 10:01
· Личное сообщение · #19

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

-----
PGP key <0x1B6A24550F33E44A>





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

Создано: 12 апреля 2011 10:10
· Личное сообщение · #20

ntldr
Смотрел WRK, но то ли я чего-то не нашёл, но сам код KiDispatchException там отсутствует. Хотя его вызовы имеются. Осуществлял поиск по проекту через студию, так что она должна была всё найти, что там есть.

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




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

Создано: 12 апреля 2011 10:15
· Личное сообщение · #21

http://thepiratebay.org/torrent/3497574/Windows_2000_source_code
Тут всё есть.

З.Ы. в WRK тоже есть, поиск студии говно.

-----
PGP key <0x1B6A24550F33E44A>




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

Создано: 12 апреля 2011 10:20
· Личное сообщение · #22

Обработчик должен быть примерно такой:

Code:
  1. static void
  2.   NewKiDispatchException(
  3.     PEXCEPTION_RECORD ExceptionRecord,
  4.     PKEXCEPTION_FRAME ExceptionFrame,
  5.     PKTRAP_FRAME      TrapFrame,
  6.     KPROCESSOR_MODE   PreviousMode,
  7.     BOOLEAN           FirstChance
  8.     )
  9. {
  10.          if (PreviousMode == UserMode)
  11.          {
  12.                  if (dbg_process_exception(ExceptionRecord, FirstChance) != 0) {
  13.                         return;
  14.                  }
  15.          }
  16.  
  17.          OldKiDispatchException(
  18.                  ExceptionRecord, ExceptionFrame, TrapFrame,
  19.                  PreviousMode, FirstChance
  20.                  );
  21. }


Т.е. простой return из обработчика возвращает управление приложению. Чтобы поправить контекст надо менять содержимое TrapFrame.
--> http://code.google.com/p/opendbg/source/browse/ <--

-----
PGP key <0x1B6A24550F33E44A>


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


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