![]() |
eXeL@B —› Программирование —› ctx.EFlags |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 11 марта 2009 01:23 · Поправил: daFix · Личное сообщение · #1 Не могу понять одну штуку - ставлю EFlags равным 0x100, и по идее при возникновении отладочного события, флаг должен автоматом сброситься. Только вот проблема - он как-то не стабильно работает. Иногда мы ловим 2 синглстепа. Мож кто подтолкнёт на путь истинный? Почему так? Code:
----- Research For Food ![]() |
|
Создано: 11 марта 2009 02:29 · Личное сообщение · #2 |
|
Создано: 11 марта 2009 02:34 · Личное сообщение · #3 |
|
Создано: 11 марта 2009 02:42 · Личное сообщение · #4 |
|
Создано: 11 марта 2009 02:47 · Поправил: daFix · Личное сообщение · #5 Clerk Давай лучше на теории... По идее должно быть так - получаем исключение, флаг восстанавливается, и при следующем ContinueDebugEvent, прога должна запуститься. Какие ещё существуют условия/ньюансы при работе с данным флагом? Clerk пишет: В диспетчер исключений не возможен повторный вход для обработки трассировочного исключения Забыл уточнить. Второе исключение мы получаем уже по другому адресу ----- Research For Food ![]() |
|
Создано: 11 марта 2009 03:26 · Личное сообщение · #6 Давай в теории. Во первых. Код для ISR #DB(KiTrap01): Code:
Тоесть TF сбрасывается при входе в юзермодный диспетчер исключений, также сбрасывается Dr7, что не позволит исполнить аппаратный останов. Возможен вход в диспетчер исключений с взведённым TF при возникновении исключения, отличного от #DB(STATUS_SINGLE_STEP), тогда выполняется есчо раз вход в диспетчер с взведённым TF, после исполнения первой его инструкции возникает трассировочное исключение и снова вход в диспетчер исключений. Но два фрейма, которые находятся в стеке не могут содержать одинаковую причину STATUS_SINGLE_STEP. Второе. Абсолютно ничего не известно как обрабатывается исключение у тебя. Для начала необходимо разобраться что делоет строка вкоде: Code:
При исполнении операции Or флажёк ZF не зависит от исходного бита. Не понятно что это. > Какие ещё существуют условия/ньюансы при работе с данным флагом? Их множество, всё описывать сдесь не имеет смысла, вдобавок посредством дебугапи нельзя выполнить полноценную трассировку(ядро сделано криво). ![]() |
|
Создано: 11 марта 2009 03:37 · Поправил: daFix · Личное сообщение · #7 Clerk Я так понял что нет смысла лезть в дебри. Легче код обработчика исключений написать так, чтобы он обрабатывал втотое исключение, как ложное Спасибо за такой достаточно содержательный ответ ![]() Тему пока не закрываю, может быть по ходу написания всё-же придётся разобраться в этом. Но пока на время вопрос снят ----- Research For Food ![]() |
|
Создано: 11 марта 2009 03:49 · Поправил: daFix · Личное сообщение · #8 |
|
Создано: 11 марта 2009 04:00 · Поправил: Clerk · Личное сообщение · #9 Это |= весьма похоже на условие.. Проверка для процессора будет такой: Code:
Если нужно сбросить флажёк: Code:
Если нужно установить флажёк: Code:
Кстати если нужно совместить проверку с установкой бита в одной инструкции юзой BTS/BTR, например: Code:
Либо что быстрее: Code:
![]() |
|
Создано: 11 марта 2009 07:12 · Личное сообщение · #10 |
|
Создано: 11 марта 2009 07:31 · Личное сообщение · #11 BoRoV пишет: если в том что здесь, то скажи, а если нет, то можнт тебе еще и весь проект предоставить Давно уже пора понять что клерку нужен бинарный код, чтобы посмотреть на асм кодес, чтобы найти траблу – не прет его в высокоуровневом(гуано) кодесе копашиццо - ИМХО ЗЫ: все знать невозможно! Сталобыть все правильно он пишет, ибо daFix пишет: cntxt.EFlags |= 0x100|cntxt.EFlags; топикстартера надо отправлять учить/заново читать RTFM! Вон отец дерматолог десяток лет учил свою гуано вм обрабатывать "div" командочку %)) здесь нет ничего удивительного что у него нах ничего не пашет, после такого гуано кодеса %)), хоть это и выполняет поставленную задачу("установку TF"), но так писать – это жесть ЗЫ: неизвестно что у него там в !!!других местах!!!, если у него такая лажа в 4 строчках Поэтому это Clerk пишет: daFix В коде баг, модуль в студию Действительно в тему было написано! cntxt.EFlags |= 0x100; cntxt.EFlags = 0x100|cntxt.EFlags; это на асме or dword ptr [X],100h где X – это ячейко в памяти куда указывает CONTEXT.EFlags --> "or cntxt.EFlags,EFLAGS_TF" с оптимизацией действительно будеД or byte ptr [cntxt.EFlags + 1],01h ----- ЗЫ: истЕна где-то рядом, Welcome@Google.com ![]() |
|
Создано: 11 марта 2009 07:45 · Личное сообщение · #12 |
|
Создано: 11 марта 2009 08:00 · Поправил: Clerk · Личное сообщение · #13 Demon666 В точку, абсолютно верно сказано! > Второе исключение мы получаем уже по другому адресу Какой хоть адрес(если в нтдлл), или это тоже секретно.. В принципе отладка элементарна, единтственный момент - процесс может иметь только один отладочный порт, тоесть под одним отладчиком работать, это решается отладкой самого твоего отладчика, либо использование ядерного(для сисер просто bpint 01 и смотрим фрейм). ![]() |
|
Создано: 11 марта 2009 11:52 · Личное сообщение · #14 Zorn пишет: (разберись с синтаксисом) Demon666 пишет: но так писать – это жесть Demon666 пишет: если у него такая лажа в 4 строчках Demon666 пишет: топикстартера надо отправлять учить/заново читать RTFM! Закончили? К слову - я его учу методом тыка. Не читал по нему книжек. До этого только на VB писал, поэтому слегка сложновато освоить всё с наскоку за пару месяцев А теперь отойдём от моей беграмотности и перейдём к делу. Zorn пишет: И еще, синглстеп срабатывает при железном бряке. Ты случайно ими не балуешься ? Балуюсь, но их уже отладил, работают нормально. За код спасибо RSI. Clerk пишет: Какой хоть адрес(если в нтдлл), или это тоже секретно.. Протрассируй до адреса 0040129A и запусти(debug event) На EP стоит ещё два бряка - железный и int3 бряк(сделано для отладки бряков), поэтому не пугайся этим двум брякам Откомпилено с гавнобиблами, чтобы размер был меньше ![]() ----- Research For Food ![]() |
|
Создано: 11 марта 2009 18:31 · Личное сообщение · #15 daFix Гы-гы, надобыло начинать так %)) Clerk пишет: Второе. Абсолютно ничего не известно как обрабатывается исключение у тебя. Для начала необходимо разобраться что делоет строка вкоде: cntxt.EFlags |= 0x100|cntxt.EFlags; daFix пишет: Zorn пишет: (разберись с синтаксисом) Demon666 пишет: но так писать – это жесть Demon666 пишет: если у него такая лажа в 4 строчках Demon666 пишет: топикстартера надо отправлять учить/заново читать RTFM! daFix пишет: Закончили? Да у нас с тобой ничего и не было.. %)) скажем так, мой пост от твоих вопросов очень далек, короче не обращай на мну здесь внимание ЗЫ: просто как-то не фантан, вначале глумление над Крипто про упх, теперь вот как-то тут вот так.. Сишный компиль, это что-то наподобие макросов в masm Там-то и конструкций (которые он генерит смешное количество), достаточно пару дней покомпилить и посмотреть что он генерит, чтобы потом смотреть на сишный код и иметь представление что за асм кодес будет после компиляции...(ну там без учета регистров и место положения команд..) Си взят за основу во многих синтаксисах (паскаль тоже присутствует, но незначительно) Но! зато в связке (масм32+макросы) + СИ++ + ООП(шаблоны/классы/etc) + x64! Все это компилит один пакет от мягкотелых(где постоянно развивающийся "асм компиль"), можно с помощью СИ++ компилить асм сырки вообще их не изменяя (не забываем еще про одного зверя GC...) До таких возможностей фасм еще.. кстати по сути фасм и похоронил асм как вид! ЗЫ: ну и реверсить ядро не обязательно, достаточно посмотреть на его исходники Короче C/C++ знать надо!, хоть плюнь - хоть выплюнь..(многое тайное станет явью!) ----- ЗЫ: истЕна где-то рядом, Welcome@Google.com ![]() |
|
Создано: 11 марта 2009 22:23 · Личное сообщение · #16 daFix Не работает, требует какието паскалевские компоненты(vcl100.bpl и другие). Demon666 > ЗЫ: ну и реверсить ядро не обязательно, достаточно посмотреть на его исходники Мелкомягкие так и делают, наоборот некоторые товарищи за отсутствием полноценных сурцов реверсят его. > СИ++ + ООП(шаблоны/классы/etc) Верно замечено, даже тут модуль собраный с говна нормальноо не работает.. ![]() |
|
Создано: 11 марта 2009 22:48 · Личное сообщение · #17 Clerk Цепляю нормально откомпиленный ![]() ----- Research For Food ![]() |
|
Создано: 11 марта 2009 23:19 · Личное сообщение · #18 |
|
Создано: 12 марта 2009 00:00 · Личное сообщение · #19 Clerk пишет: требует какието паскалевские компоненты(vcl100.bpl и другие) Clerk пишет: Верно замечено, даже тут модуль собраный с говна нормальноо не работает.. Уже мильен раз здесь на форуме обсуждалось, что борланд сишный дает 50% багов, без хаков и бубна вступать и компиривовать невозможно! Старые версии еще сносные были..(это те, которые лет 7 назад юзали) в одной теме здесь на лабе особенно основательно обсуждение было, тоже че-то банально начиналось неправильной компиляции строк, что-то там.. уже не помню точно... все же думали что компиль от Microsoft, а там через пол&топика узнали что борланд топикстартеру посоветовали выпить йаду и забыть о нормальной компиляции, ибо сишный компиль от борланд там !!!просто жопа!!! Скорость написания кода падает в раз пять, если не больше и это ни теория, а реалии жизни - при этом гарантируюццо постоянные грабли непонятных ошибок..! Чтоже касается MS, то тут зависит только от самого кодера и ООП тут не причем, его надо просто грамотно уметь готовить!!!(процентов 90% сишных кодеров - это просто школьнеги написавшие 20 000 строк(и то под вопросом) и думающих, что теперь все они могут%)) ) – ИМХО Тут даже добавлю пожалуй – просто на асме надо попробовать написать прогу, ну размером 3-4мб(хотя 1-2мб для асма это уже вышка) и все станет на свои места Да хотябы просто отладчег ринга0 на асме, этого уже достаточно будет Ай знаю что на асме можно юзать библы(считай тоже самое ООП с абстракцией), но речь идет именно о совместимости языков программирования, чтобы расширить возможности кодинга ЗЫ: помню себя мну ломал около месяца, чтобы только скомпилить хелоуворд на СИ %)))) P. S. Да вот взять к примеру это beatrix2004.free.fr/BeaEngine/BeaEngineSources.rar я раньше его не видел, но автор утверждает что код был на масме32, но сейчас переписал его на СИ.. ----- ЗЫ: истЕна где-то рядом, Welcome@Google.com ![]() |
|
Создано: 12 марта 2009 00:20 · Личное сообщение · #20 |
|
Создано: 12 марта 2009 01:00 · Поправил: Clerk · Личное сообщение · #21 daFix Запустилось, в общем только посмотрев на адрес стало понятно. Останов происходит на BaseThreadStartThunk(). Тоесть при создании потока в контексте его устанавливается TF. При создании потока он не начинает исполняться с указанного адреса, собственно начало работы потока это обработка APC. Диспетчер исполняется в контексте вновь созданного потока, он выполняет LdrInitializeThunk(), собственно это нотификация загрузчика, тут не важно. При исполнении этого кода поток не трассируется, но для передачи управления на пользовательский код(назовём этот адрес Win32StartAddress) используется сервис NtContinue(передача управления через Call, но на BaseThreadStartThunk посредством указанного сервиса), а контекст находится в стеке и в нём взведён TF. Адрес в контексте в регистре Eip ведь не Win32StartAddress, а BaseThreadStartThunk. Вот при передаче управления посредством NtContinue и генерируется трассировочное исключение после исполнения первой инструкции этой процедуры. Это если кратко, более подробно я описывал как поток создаётся например тут http://wasm.ru/forum/viewtopic.php?id=30111&p=2 http://wasm.ru/forum/viewtopic.php?id=30111&p=2 , #30. Не раззбирался в коде, но могу предположить что ты создаёшь поток суспендинным и взводишь в его контексте TF. ![]() |
|
Создано: 12 марта 2009 02:11 · Личное сообщение · #22 мля, подредился %)) daFix ты этот второй аттач сам-то пробовал дебажить? Че там и как я не стал разбираццо, но мну уверен что компиль генерит код, не тот что ты подразумеваешь Короче.. я опишу что сделал, а ты уже дальше сам пробуй %))) Ищем в Project1.exe GetThreadContext их там около 6, но нас интересует 00402D23 Code:
Жертва траблы предположительно здесь 00402D34, проверим Ставим бряк на 00402CFC и запускаем Project1.exe Там жмем Run! потом Debug Event и Single Step стопоримся на бряке (че к чему я не стал разбираццо) Предположительно там в edx должно быть 100h(0x100) судя по коду daFix пишет: cntxt.EFlags |= 0x100|cntxt.EFlags; 00402D34 or [ecx+160h], edx 160h-0A0h=0C0h Хм.. а че в edx? (mov edx,[eax+2334h]) Тресим F7 и видим 0x200(у меня так - как у тебя хз.), а должно быть 0x100 Сталобыть дальше не стал ничего смотреть, все файлеги кильнул и продолжаю думать что все траблы в компиле, еще где гарантии что ООП борланда при компиляции в дебаг/реал режиме не ставит свой обработчик исключений ;)) ЗЫ: несколько минут потребовалось, а ты тут тупо на теме уже два дня виснешь %))) daFix пишет: а по теме можешь что нибудь сказать? Реально по теме тебе советую компилить такие вещи на асме(весь код, ты уже сам контролируешь) и не париццо!!! - ИМХО И да.. не читай посты, которые не тебе пишут - если че ;) ----- ЗЫ: истЕна где-то рядом, Welcome@Google.com ![]() |
|
Создано: 12 марта 2009 02:33 · Личное сообщение · #23 |
|
Создано: 12 марта 2009 02:48 · Поправил: Clerk · Личное сообщение · #24 daFix Он их правильно обрабатывает, Demon666 не туда залез ![]() Просто не верная последовательность действий исполняется. Есть одна особенность, а именно регистр флагов будет такимже в стековом фрейме, который далее восстанавливается в NtContinue, как и в самом контексте потока, тоесть он копируется в контекст диспетчера APC. Это нельзя обойти нормальным способом, более-менее оптимальный вариант это пропустить трассировочное исключение, иначе придётся извлекать из стека контекст при первом трассировочном исключении(который в стеке диспетчера APC) и там сбрасывать флажёк TF. ![]() |
|
Создано: 12 марта 2009 03:04 · Поправил: daFix · Личное сообщение · #25 о_О Уже отрекаюсь от реальности Перевёл код на ассемблер и ошибка пропала О_о Думаю что данный вопрос исчерпан, хотя и не понятно как)) Хотя может быть в коде было две ошибки - та о которой говорил Демон и та, о которой говорил Клерк Тему пока закрывать не буду, т.к. чувствую что ещё будут вопросы подобного плана Отдельное спасибо Демону и Клерку Наверное лучше начать переводить код на ассемблерный, но под билдер ----- Research For Food ![]() |
|
Создано: 12 марта 2009 03:10 · Личное сообщение · #26 daFix > Перевёл код на ассемблер и ошибка пропала Это не так. Твой код вероятно уязвим. Значит сейчас ты сбрасываешь сразу в контексте нового потока TF, затем стартуешь его. Он уже работает без трассировки, тоесть ты не сможешь его трассировать ![]() А если перед запуском взведёшь TF, затем стартуешь поток и пропускаешь первое трассировочное исключение второе будет всёравно сгенерировано на BaseThreadStartThunk() ![]() ![]() |
|
Создано: 12 марта 2009 03:38 · Личное сообщение · #27 |
|
Создано: 12 марта 2009 03:50 · Поправил: Clerk · Личное сообщение · #28 Насчёт моего отношения к любому коду, который использует ожидание трассировочного исключения с помощью дебугапи - думою знают многие, я считаю данный механизм не пригодным для применения в отладчиках, поэтому мне абсолютно не интересен этот код. Другими словами такая трассировка бесполезна, нет возможности обнаружить исполнение некоторых сервисов, в частности тогоже NtContinue(посредством него поток выходит из под трассировки) без модификации ядра. Да, простейший способ это проверка регистра Eax(номер сервиса) перед вызовом его, но это также бесполезно, ибо код может быть перекрёстным, да и вообще способов модификации кода на лету множество. Имхо подобные механизмы не должны применяться. ![]() |
|
Создано: 12 марта 2009 19:28 · Личное сообщение · #29 |
|
Создано: 12 марта 2009 22:12 · Личное сообщение · #30 |
. 1 . 2 . >> |
![]() |
eXeL@B —› Программирование —› ctx.EFlags |