Сейчас на форуме: Lohmaty (+6 невидимых) |
eXeL@B —› Вопросы новичков —› Stack BT |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 12 июля 2018 22:23 · Поправил: Ate · Личное сообщение · #1 Для удобства захотел добавть в свой обработчик исключений (хотя пригодится и в других кейсах) бэктрейс стека, ну думаю вызову CaptureStackBackTrace и дело сделано, но не тут-то было. Оказывается эта "замечательная" функция просто не видит фреймы, если функция не имеет канонических прологов, эпилогов, итп, возвращая бесполезные крохи инфы. Уточню - никаких заигрываний с исходниками нет, нужен просто сырой бэктрейс из любого приложения. Отсюда вопрос номер 1,- есть ли готовые "правильные" решения, в идеале статические lib, на случай, если никто ничего интересного не предложит, фоллбэк такой: буду делать снапшот всего стэка и постфактум разбираться. Например читаем из тиба Code:
В цикле по 4 байта (для х86) копируем в буфер (StackBase-ESP) байт начиная с ESP, потом по желанию можно пройтись по адресам и откоментить для вывода (далее чисто мои размышления и велосипеды),- нули игнорируем, помечаем EBP как текущий фрейм, все что в границах (Stack Limit<-->Stack Base) - адреса стека или параметры, остальные адреса проверяем с помощью GetModuleHandleEx > GetModuleFileName на возможную принадлежности к текущим модулям и добавляем коментарий, была даже идея подтянуть капстоун и проверять предыдущую инструкцию на call чтобы отмаркировать "вручную" фреймы. В итоге, стоит ли делать так? Или есть ли готовые lib (на худой конец dll), или грамотные исходники? Что из моих "фантазий" годно? |
|
Создано: 12 июля 2018 23:14 · Личное сообщение · #2 |
|
Создано: 12 июля 2018 23:37 · Личное сообщение · #3 Archer пишет: Какая архитектура интересует Интересуют обе, просто в данный момент актуально именно х86. Archer пишет: Есть апи для этого CaptureStackBackTrace и есть, но она, как оказалось, не торт... Для DbgHelp StackWalk вообще символы нужны похоже. Archer пишет: В х86 только тыкать пальцем в небо ну я в правильном направлении мыслю? Можно "вручную" фреймы вычислить, или постфактум в отладчике разбираться по снимку стэка? |
|
Создано: 13 июля 2018 01:49 · Поправил: difexacaw · Личное сообщение · #4 Ate Бэктрейс - выделение последовательности процедурных ветвлений. Через стековые фреймы связывается стековое пространство процедур. Что бы определить следующий адрес возврата в стеке на основе текущего нужно знать размер стекового пространства процедуры. Для этого придётся брать исходный известный адрес в код и парсить его, строить граф и определять баланс стека(суммарный размер на который смещается стек каждой инструкцией) для всех ветвей в процедуре, приводящих к call. Это алгоритмически запутанная задача. Если просто все указатели в стеке перебирать, то придётся как то узнать что это указатель в код на адрес возврата. Это двумя способами можно сделать: A. Проверить что P[-N] это инструкция Call. B. Парсить процедуру полностью и получить все её call's. Затем искать их в стеке, поиск оканчивать по последним call's. В данном случае достаточно A. 028a_13.07.2018_EXELAB.rU.tgz - btr.7z ----- vx | Сообщение посчитали полезным: Ate |
|
Создано: 13 июля 2018 04:37 · Поправил: f13nd · Личное сообщение · #5 Ate пишет: Оказывается эта "замечательная" функция просто не видит фреймы, если функция не имеет канонических прологов, Наверное потому что в каноническом прологе этот самый размер фрейма и задается через sub esp,xxx. Самым тупым (а потому универсальным) решением было бы забирать адрес разврата по ebp (ассемблерной вставкой)(либо не связываться с этим, а брать адрес самой функции, еще проще) в начале каждой функции, помещать в своё собственное подобие стека с блекджеком и всей атрибутикой, а при выходе из функции снимать оттуда (либо построить такую же цепочку наподобие SEH на локальных переменных, а адрес крайней хранить в глобальной, как и там). Проблема только в том, как такой неканонический пролог и эпилог закрутить в функции сторонних библиотек, если их тоже надо. ----- 2 оттенка серого |
|
Создано: 13 июля 2018 09:01 · Личное сообщение · #6 Самый нормальный вариант-это разбирать руками. 100% точно автоматикой не запилишь. АПИ если поглядеть, в принципе там есть некоторая угадайка, что сначала пытается по фреймам через ebp идти, а потом начинает тупо брутфорсить. Можно попробовать сделать угадайку, но если поглядывать стек в ольке или виндбг, то косячит угадайка не так и редко. |
|
Создано: 14 июля 2018 09:21 · Личное сообщение · #7 Archer Почему же не запилишь. Задача сводится к классической code vs data. Если ввести дополнительные проверки и построения, можно полностью исключить вероятность ошибки ----- vx |
|
Создано: 16 июля 2018 16:02 · Личное сообщение · #8 |
|
Создано: 17 июля 2018 02:08 · Поправил: VOLKOFF · Личное сообщение · #9 Just for fun запилил на коленке Окошки делать было лень, в консоль не у всех большой вывод влезет, поэтому весь выхлоп в дебаг (Dbgview в комплекте). Для удобства код вынесен в dll с одной экспортируемой функцией, которая все и делает. Приложение test для быстрой наглядности, вызывает цепочку "неправильных" процедур и прыгает на адрес этой функции. После отработки dll киляет приложение. Первой строчкой выводится сколько реальных "фреймов" поймала RtlCaptureStackBackTrace (эти RETURN в списке будут без '*' впереди). Особо не тестил, но все что по руку попало восстановилось полностью, естественно эта поделка демонстрирует лишь базовый принцип, что да - в обычных кейсах на "чистых" приложениях можно так делать. Погоняй на своих пациентах, сразу будет понятно, нужно тебе вообще это, или выбрать другой подход. Так-то в особо тяжких случаях такие задачи решаются с DBI. Вот сравнение выхлопа: [ ss.dll | ollydbg | x64dbg ] Сюда еще прикрутить процедуру резолва имен функций, будет вообще по красоте (но это не было заявлено). Баги есть, но пофег, как наглядный пример пойдет Пасс: ss | Сообщение посчитали полезным: Ate |
|
Создано: 17 июля 2018 20:03 · Личное сообщение · #10 |
|
Создано: 19 июля 2018 22:13 · Личное сообщение · #11 |
|
Создано: 19 июля 2018 22:37 · Личное сообщение · #12 Если отталкиваться от вышенаписанного и предположить, что все сделано по твоему сценарию, могу пованговать Задача сводится к максимальной фильтрации адресов стека и если выпилить весь "мусор" на допроверочной стадии, falsepositive быть не должно. Ate пишет: использую код difexacaw Тут все просто, вызов может быть осуществлен любой бранч инструкцией (Call, Ret, Jmp, условки etc), это нужно учитывать. Инде показал лишь самый простой вариант определения. Ate пишет: ss.dll показывает правильно Тебе просто повезло Чтобы находить все и всегда, без какого-то аналога DBI тулзы будет трудновато обойтись. Например даже приаттаченный отладчик нифига не покажет в случае sm кода. Моя поделка тоже написана "на отвали", для ускорения работы там нет детекта границ функций, поэтому хватит избыточного мусорного кода чтобы "антиотладочные" вызовы перестали детектится итд итп. Так что данный подход только для "чистых" файлов, это без вариантов. | Сообщение посчитали полезным: Ate |
|
Создано: 21 июля 2018 13:20 · Поправил: difexacaw · Личное сообщение · #13 VOLKOFF > вызов может быть осуществлен любой бранч инструкцией Обычный код загружает адрес возврата через call. Вендорами было создано несколько механизмов(cfg/rfg) защиты от передач управления иным путём, так как это используется при OP-атаках. На стеке нормально не может возникнуть адрес, на который будет передано управление через ret, кроме как прежде выполненная call. Указатели в стеке могут быть любые, на код/данные. Например колбек в локальной структуре. Тогда по простому никак не узнать что это адрес возврата - нужно получить все входа в код, для защиты такие маркеры были введены в пе формат, но если их нет, то придётся анализить весь модуль, а если релоков нет, то задача в общем случае стабильно не резолвится. Единственный путь - накопить все вызовы при трассировке, это тот самый dbi/визоры. ----- vx | Сообщение посчитали полезным: VOLKOFF |
|
Создано: 21 июля 2018 17:58 · Личное сообщение · #14 Не перестаю удивляться как можно с таким глубокомысленным видом писать вещи противоречащие окружающей действительности. За это мы все тебя и любим Если бы в какой-то параллельной реальности ты обучал бы программированию, твои ученики имели бы достаточно теории чтобы часами рассуждать о структуре ядра, но не осилили бы написать даже "Hello world!" |
|
Создано: 21 июля 2018 18:03 · Поправил: f13nd · Личное сообщение · #15 VOLKOFF пишет: Не перестаю удивляться как можно с таким глубокомысленным видом писать вещи противоречащие окружающей действительности. Скорей всего речь идет об DEP или чем-то подобном, очень даже вероятно, что это так и работает. Правда подтвердить не могу, ибо и push+ret и тупо подмену адреса разврата в перехватчиках использовал, но может деп тогда в биосе был отрублен. ----- 2 оттенка серого |
|
Создано: 21 июля 2018 18:11 · Поправил: difexacaw · Личное сообщение · #16 VOLKOFF Не понимаю о чём вы. В нт было введено две ключевые защиты от Oriented-Programming атак, это два механизма, которые отслеживают входы(CFG) и выходы(RFG) из кода. Для первого типа используется индирект отслеживание ветвлений, это поддержал железячный вендор(Интел), для второго типа используется софтверный стек(стек ветвлений) и так же было имплементировано в железо. Эти маркеры введены в PE формат как CFG-table's. Имея таблицу cfg можно покрыть весь код конструктором, ссылка была выше. Примеры можите и тут поиском найти. Добавлено спустя 18 минут VOLKOFF Вот пример вам, покрытие всего кода через CFT Брался каждый вход из pe-cfg, ребилдился в буфер, оригинальный код затирался. Конечно при этом в графе любой call имеется. ----- vx |
|
Создано: 21 июля 2018 18:58 · Личное сообщение · #17 |
|
Создано: 21 июля 2018 18:59 · Поправил: difexacaw · Личное сообщение · #18 VOLKOFF А почему вы так решили ? Так как механизм отключен/не_поддерживается и есть кодовая лапша протектора - так я это во втором абзаце написал. Добавлено спустя 20 минут VOLKOFF Давайте я за вас поищу матчасть. PE COFF FG ----- vx |
|
Создано: 22 июля 2018 20:37 · Личное сообщение · #19 |
|
Создано: 22 июля 2018 20:42 · Личное сообщение · #20 Ate пишет: Подскажите какой дизасм на сегодняшний день самый безошибочный? xed, ms, llvm, последний не заводится без написания приличного количества кода. | Сообщение посчитали полезным: Ate |
|
Создано: 22 июля 2018 21:38 · Личное сообщение · #21 Предложу варианты с более дружественным API, чтобы ранней седины не было от процесса написания кода Дисторм с трешки хорош, декомпозиционный интерфейс радует, хотя как легаси оставлен и старый текстовый вывод, маленький и шустрый (юзается в титане). Самые свежие - Зидис и Капс, хотя первый в альфе до сих пор, второй недавно обновился до релизки. Есть вот Из прошлогоднего блога x64dbg про Зидис: Code:
| Сообщение посчитали полезным: Ate |
|
Создано: 22 июля 2018 22:07 · Личное сообщение · #22 не знаю по поводу альфы zydis... буквально сегодня обновился до - v2.0.2 - https://github.com/zyantific/zydis/commits/master есть биндинги для раста, пайтона и паскаля. вот ещё один бенч от разрабов zydis - https://github.com/athre0z/disas-bench zydis реально лучший - лёгкий, быстрый, точный и правильный, лично я советую его если нужно только x86 && x86_x64 | Сообщение посчитали полезным: VOLKOFF |
|
Создано: 22 июля 2018 22:15 · Личное сообщение · #23 |
|
Создано: 22 июля 2018 22:33 · Личное сообщение · #24 |
|
Создано: 22 июля 2018 23:16 · Личное сообщение · #25 |
|
Создано: 22 июля 2018 23:50 · Поправил: RevCred · Личное сообщение · #26 difexacaw пишет: Потестить бы на профайл судя по тому бенчу что я дал(я запускал его у себя тоже), то zydis самый быстрый почти во всём. у zydis три режима 1) zydis-min-no-fmt - это только length disasm тут понятно что это будет быстрее чем любой разбор - самый быстрый 2) zydis-full-no-fmt - на выходе получаем такую структурку - https://github.com/zyantific/zydis/blob/master/include/Zydis/DecoderTypes.h#L817-L1349 раза в полтора медленне чем XED 3) zydis-full-fmt - на выходе получаем строку-мнемонику раза в полтора быстрее чем XED в итоге получаем что это очень хорошая замена capstone в x64dbg, но вам возможно и не подойдёт. difexacaw пишет: Потестить бы на стабильность Absolutely no dependencies — not even libc Should compile on any platform with a working C99 compiler Tested on Windows, macOS, FreeBSD and Linux, both user and kernel mode потом так Credits Intel (for open-sourcing XED, allowing for automatic comparision of our tables against theirs, improving both) в итоге оно стабильное во всех понятиях - как в работе, так и в правильности разбора мнемоники. hypn0 пишет: Вот не в обиду, а Вы вообще для чего его применяете и как? Я реально не знаю. Простите меня. кхе-кхе я когда свой дизасм движок пилил сравнивал всё с zydis. а так да, дизасм двиг очень специфичная штука, относительно мало кому и где она нужна. | Сообщение посчитали полезным: Ate |
|
Создано: 22 июля 2018 23:57 · Личное сообщение · #27 |
|
Создано: 22 июля 2018 23:57 · Личное сообщение · #28 |
|
Создано: 23 июля 2018 00:04 · Личное сообщение · #29 |
|
Создано: 23 июля 2018 00:08 · Поправил: RevCred · Личное сообщение · #30 difexacaw пишет: Хотелось бы реальные цифры увидеть, закрутить в цикл два дизасма и снять статистику. закрутите и поделитесь инфой со всеми, мне тоже было бы интересно посмотреть. Я бы не отказался от более быстрого и точного length дизасма. difexacaw пишет: Нужно собирать это всё и разбираться в интерфейсах. https://github.com/zyantific/zydis/blob/251a83e6f69d9bae3a8162db669ad43a82483b9e/examples/ZydisPerfTest.c#L176 вот пример использования только lde. осталось найти время и сбилдить |
. 1 . 2 . >> |
eXeL@B —› Вопросы новичков —› Stack BT |