eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
обновлён 2 декабря!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: ioan33, Dream_, 3ton, spinz (+1 невидимый пользователь)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Вопросы новичков —› Stack BT
. 1 . 2 . >>
Посл.ответ Сообщение

Ранг: 8.3 (гость)
Статус: Участник

Создано: 12 июля 2018 22:23 · Поправил: Ate New!
Цитата · Личное сообщение · #1

Для удобства захотел добавть в свой обработчик исключений (хотя пригодится и в других кейсах) бэктрейс стека, ну думаю вызову CaptureStackBackTrace и дело сделано, но не тут-то было. Оказывается эта "замечательная" функция просто не видит фреймы, если функция не имеет канонических прологов, эпилогов, итп, возвращая бесполезные крохи инфы.
Уточню - никаких заигрываний с исходниками нет, нужен просто сырой бэктрейс из любого приложения.
Отсюда вопрос номер 1,- есть ли готовые "правильные" решения, в идеале статические lib, на случай, если никто ничего интересного не предложит, фоллбэк такой:

буду делать снапшот всего стэка и постфактум разбираться.
Например читаем из тиба

Code:
  1. mov eax, FS:[0x04] ; Stack Base
  2. mov eax, FS:[0x08] ; Stack Limit (на случай если будет нужно)


В цикле по 4 байта (для х86) копируем в буфер (StackBase-ESP) байт начиная с ESP, потом по желанию можно пройтись по адресам и откоментить для вывода (далее чисто мои размышления и велосипеды),- нули игнорируем, помечаем EBP как текущий фрейм, все что в границах (Stack Limit<-->Stack Base) - адреса стека или параметры, остальные адреса проверяем с помощью GetModuleHandleEx > GetModuleFileName на возможную принадлежности к текущим модулям и добавляем коментарий, была даже идея подтянуть капстоун и проверять предыдущую инструкцию на call чтобы отмаркировать "вручную" фреймы.

В итоге, стоит ли делать так?
Или есть ли готовые lib (на худой конец dll), или грамотные исходники?
Что из моих "фантазий" годно?


Ранг: 1995.9 (!!!!)
Статус: Модератор
retired

Создано: 12 июля 2018 23:14 New!
Цитата · Личное сообщение · #2

Какая архитектура интересует, х86 или х64? А х64 есть инфа по фреймам стека и местами даже обязательная. В х86 только тыкать пальцем в небо. Есть апи для этого, как вариант-их посмотреть. Но по сути они тоже пальцем в небо тычут, если инфу не найдут.

Ранг: 8.3 (гость)
Статус: Участник

Создано: 12 июля 2018 23:37 New!
Цитата · Личное сообщение · #3

Archer пишет:
Какая архитектура интересует

Интересуют обе, просто в данный момент актуально именно х86.
Archer пишет:
Есть апи для этого

CaptureStackBackTrace и есть, но она, как оказалось, не торт...
Для DbgHelp StackWalk вообще символы нужны похоже.
Archer пишет:
В х86 только тыкать пальцем в небо

ну я в правильном направлении мыслю? Можно "вручную" фреймы вычислить, или постфактум в отладчике разбираться по снимку стэка?


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 13 июля 2018 01:49 · Поправил: difexacaw New!
Цитата · Личное сообщение · #4

Ate

Бэктрейс - выделение последовательности процедурных ветвлений. Через стековые фреймы связывается стековое пространство процедур. Что бы определить следующий адрес возврата в стеке на основе текущего нужно знать размер стекового пространства процедуры. Для этого придётся брать исходный известный адрес в код и парсить его, строить граф и определять баланс стека(суммарный размер на который смещается стек каждой инструкцией) для всех ветвей в процедуре, приводящих к call. Это алгоритмически запутанная задача.

Если просто все указатели в стеке перебирать, то придётся как то узнать что это указатель в код на адрес возврата. Это двумя способами можно сделать:

A. Проверить что P[-N] это инструкция Call.
B. Парсить процедуру полностью и получить все её call's. Затем искать их в стеке, поиск оканчивать по последним call's. В данном случае достаточно A.

{ Атач доступен только для участников форума } - btr.7z

| Сообщение посчитали полезным: Ate



Ранг: 228.1 (наставник)
Статус: Участник

Создано: 13 июля 2018 04:37 · Поправил: f13nd New!
Цитата · Личное сообщение · #5

Ate пишет:
Оказывается эта "замечательная" функция просто не видит фреймы, если функция не имеет канонических прологов,

Наверное потому что в каноническом прологе этот самый размер фрейма и задается через sub esp,xxx. Самым тупым (а потому универсальным) решением было бы забирать адрес разврата по ebp (ассемблерной вставкой)(либо не связываться с этим, а брать адрес самой функции, еще проще) в начале каждой функции, помещать в своё собственное подобие стека с блекджеком и всей атрибутикой, а при выходе из функции снимать оттуда (либо построить такую же цепочку наподобие SEH на локальных переменных, а адрес крайней хранить в глобальной, как и там). Проблема только в том, как такой неканонический пролог и эпилог закрутить в функции сторонних библиотек, если их тоже надо.


Ранг: 1995.9 (!!!!)
Статус: Модератор
retired

Создано: 13 июля 2018 09:01 New!
Цитата · Личное сообщение · #6

Самый нормальный вариант-это разбирать руками. 100% точно автоматикой не запилишь. АПИ если поглядеть, в принципе там есть некоторая угадайка, что сначала пытается по фреймам через ebp идти, а потом начинает тупо брутфорсить. Можно попробовать сделать угадайку, но если поглядывать стек в ольке или виндбг, то косячит угадайка не так и редко.


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 14 июля 2018 09:21 New!
Цитата · Личное сообщение · #7

Archer

Почему же не запилишь. Задача сводится к классической code vs data. Если ввести дополнительные проверки и построения, можно полностью исключить вероятность ошибки --> Link <--

Ранг: 8.3 (гость)
Статус: Участник

Создано: 16 июля 2018 16:02 New!
Цитата · Личное сообщение · #8

Добрался до рабочего ПК, буду смотреть что можно сделать. Спасибо!

Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 17 июля 2018 02:08 · Поправил: VOLKOFF New!
Цитата · Личное сообщение · #9

Just for fun запилил на коленке концепт (он даже должен работать ) по обсуждаемой "методике", можешь потыкать.
Окошки делать было лень, в консоль не у всех большой вывод влезет, поэтому весь выхлоп в дебаг (Dbgview в комплекте).
Для удобства код вынесен в dll с одной экспортируемой функцией, которая все и делает. Приложение test для быстрой наглядности, вызывает цепочку "неправильных" процедур и прыгает на адрес этой функции.
После отработки dll киляет приложение. Первой строчкой выводится сколько реальных "фреймов" поймала RtlCaptureStackBackTrace (эти RETURN в списке будут без '*' впереди).

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



[ ss.dll | ollydbg | x64dbg ]

Сюда еще прикрутить процедуру резолва имен функций, будет вообще по красоте (но это не было заявлено).
Баги есть, но пофег, как наглядный пример пойдет Пасс: ss

| Сообщение посчитали полезным: Ate



Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 17 июля 2018 20:03 New!
Цитата · Личное сообщение · #10

VOLKOFF

Почему не выложить сурец, опять нужно копать отладчиком. Даже не охота это делать.

Ранг: 8.3 (гость)
Статус: Участник

Создано: 19 июля 2018 22:13 New!
Цитата · Личное сообщение · #11

Еще раз спасибо, сделал свой вариант, но есть вопросы. Пробовал на разных программах и иногда бывают ложные срабатывания, а на некоторых наоборот не видно возвратов (использую код difexacaw), хотя ss.dll показывает правильно. Почему такое может быть?

Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 19 июля 2018 22:37 New!
Цитата · Личное сообщение · #12

Если отталкиваться от вышенаписанного и предположить, что все сделано по твоему сценарию, могу пованговать
Задача сводится к максимальной фильтрации адресов стека и если выпилить весь "мусор" на допроверочной стадии, falsepositive быть не должно.

Ate пишет:
использую код difexacaw

Тут все просто, вызов может быть осуществлен любой бранч инструкцией (Call, Ret, Jmp, условки etc), это нужно учитывать. Инде показал лишь самый простой вариант определения.

Ate пишет:
ss.dll показывает правильно

Тебе просто повезло
Чтобы находить все и всегда, без какого-то аналога DBI тулзы будет трудновато обойтись. Например даже приаттаченный отладчик нифига не покажет в случае sm кода. Моя поделка тоже написана "на отвали", для ускорения работы там нет детекта границ функций, поэтому хватит избыточного мусорного кода чтобы "антиотладочные" вызовы перестали детектится итд итп. Так что данный подход только для "чистых" файлов, это без вариантов.

| Сообщение посчитали полезным: Ate



Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 21 июля 2018 13:20 · Поправил: difexacaw New!
Цитата · Личное сообщение · #13

VOLKOFF

> вызов может быть осуществлен любой бранч инструкцией

Обычный код загружает адрес возврата через call. Вендорами было создано несколько механизмов(cfg/rfg) защиты от передач управления иным путём, так как это используется при OP-атаках. На стеке нормально не может возникнуть адрес, на который будет передано управление через ret, кроме как прежде выполненная call. Указатели в стеке могут быть любые, на код/данные. Например колбек в локальной структуре. Тогда по простому никак не узнать что это адрес возврата - нужно получить все входа в код, для защиты такие маркеры были введены в пе формат, но если их нет, то придётся анализить весь модуль, а если релоков нет, то задача в общем случае стабильно не резолвится. Единственный путь - накопить все вызовы при трассировке, это тот самый dbi/визоры.

| Сообщение посчитали полезным: VOLKOFF


Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 21 июля 2018 17:58 New!
Цитата · Личное сообщение · #14

Не перестаю удивляться как можно с таким глубокомысленным видом писать вещи противоречащие окружающей действительности. За это мы все тебя и любим

Если бы в какой-то параллельной реальности ты обучал бы программированию, твои ученики имели бы достаточно теории чтобы часами рассуждать о структуре ядра, но не осилили бы написать даже "Hello world!"


Ранг: 228.1 (наставник)
Статус: Участник

Создано: 21 июля 2018 18:03 · Поправил: f13nd New!
Цитата · Личное сообщение · #15

VOLKOFF пишет:
Не перестаю удивляться как можно с таким глубокомысленным видом писать вещи противоречащие окружающей действительности.

Скорей всего речь идет об DEP или чем-то подобном, очень даже вероятно, что это так и работает. Правда подтвердить не могу, ибо и push+ret и тупо подмену адреса разврата в перехватчиках использовал, но может деп тогда в биосе был отрублен.


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 21 июля 2018 18:11 · Поправил: difexacaw New!
Цитата · Личное сообщение · #16

VOLKOFF

Не понимаю о чём вы. В нт было введено две ключевые защиты от Oriented-Programming атак, это два механизма, которые отслеживают входы(CFG) и выходы(RFG) из кода. Для первого типа используется индирект отслеживание ветвлений, это поддержал железячный вендор(Интел), для второго типа используется софтверный стек(стек ветвлений) и так же было имплементировано в железо. Эти маркеры введены в PE формат как CFG-table's. Имея таблицу cfg можно покрыть весь код конструктором, ссылка была выше.

Примеры можите и тут поиском найти.

Добавлено спустя 18 минут
VOLKOFF

Вот пример вам, покрытие всего кода через CFT --> Link <--

Брался каждый вход из pe-cfg, ребилдился в буфер, оригинальный код затирался. Конечно при этом в графе любой call имеется.

Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 21 июля 2018 18:58 New!
Цитата · Личное сообщение · #17

Вы что оба наркоманы?


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 21 июля 2018 18:59 · Поправил: difexacaw New!
Цитата · Личное сообщение · #18

VOLKOFF

А почему вы так решили ?

Так как механизм отключен/не_поддерживается и есть кодовая лапша протектора - так я это во втором абзаце написал.

Добавлено спустя 20 минут
VOLKOFF

Давайте я за вас поищу матчасть.

PE COFF --> Link <-- IMAGE_DLLCHARACTERISTICS_GUARD_CF и далее по флагу директория и есчо несколько по теме.

FG --> Link <--

Ранг: 8.3 (гость)
Статус: Участник

Создано: 22 июля 2018 20:37 New!
Цитата · Личное сообщение · #19

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

Ранг: 0.0 (гость)
Статус: Участник

Создано: 22 июля 2018 20:42 New!
Цитата · Личное сообщение · #20

Ate пишет: Подскажите какой дизасм на сегодняшний день самый безошибочный?

xed, ms, llvm, последний не заводится без написания приличного количества кода.

| Сообщение посчитали полезным: Ate


Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 22 июля 2018 21:38 New!
Цитата · Личное сообщение · #21

Предложу варианты с более дружественным API, чтобы ранней седины не было от процесса написания кода

Дисторм с трешки хорош, декомпозиционный интерфейс радует, хотя как легаси оставлен и старый текстовый вывод, маленький и шустрый (юзается в титане).
Самые свежие - Зидис и Капс, хотя первый в альфе до сих пор, второй недавно обновился до релизки.

Есть вот такой бенч 8-ми месячной давности, хз насколько капс стал за это время лучше.

Из прошлогоднего блога x64dbg про Зидис:
Code:
  1. *Support for many lesser known and undocumented instructions
  2.  We collected and diffed our data-tables from and against various different sources, such as Intel XED, LLVM and even did a full sweep through the Intel SDM for the sake of checking side-effects of all instructions
  3. *(minor) boost in performance
  4.  Zydis is about 50% faster than Capstone
  5.  500% faster when decoding to binary structure only, without formatting to human readable text assembly (CS doesn’t leave the user a choice right now)
  6. *A decrease in binary size
  7.  Zydis is about 1/3 the size of Capstone (CS X86 only, all features compiled in)

| Сообщение посчитали полезным: Ate


Ранг: 19.7 (новичок)
Статус: Участник

Создано: 22 июля 2018 22:07 New!
Цитата · Личное сообщение · #22

не знаю по поводу альфы zydis...
буквально сегодня обновился до - v2.0.2 - https://github.com/zyantific/zydis/commits/master
есть биндинги для раста, пайтона и паскаля.

вот ещё один бенч от разрабов zydis - https://github.com/athre0z/disas-bench

zydis реально лучший - лёгкий, быстрый, точный и правильный, лично я советую его если нужно только x86 && x86_x64

| Сообщение посчитали полезным: VOLKOFF


Ранг: 35.9 (посетитель)
Статус: Участник

Создано: 22 июля 2018 22:15 New!
Цитата · Личное сообщение · #23

RevCred пишет:
zydis реально лучший

Вот не в обиду, а Вы вообще для чего его применяете и как?
Я реально не знаю. Простите меня.

Ранг: 134.3 (ветеран)
Статус: Участник

Создано: 22 июля 2018 22:33 New!
Цитата · Личное сообщение · #24

RevCred пишет:
буквально сегодня обновился до - v2.0.2

Ога, релиз был 5 часов назад


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 22 июля 2018 23:16 New!
Цитата · Личное сообщение · #25

RevCred

Потестить бы на профайл и стабильность, может оно быстрее кседа, тогда и мне пригодится.

Ранг: 19.7 (новичок)
Статус: Участник

Создано: 22 июля 2018 23:50 · Поправил: RevCred New!
Цитата · Личное сообщение · #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



Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 22 июля 2018 23:57 New!
Цитата · Личное сообщение · #27

RevCred

> тут понятно что это будет быстрее чем любой разбор - самый быстрый

Хотелось бы реальные цифры увидеть, закрутить в цикл два дизасма и снять статистику.

Ранг: 35.9 (посетитель)
Статус: Участник

Создано: 22 июля 2018 23:57 New!
Цитата · Личное сообщение · #28

RevCred пишет:
кхе-кхе

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

Добавлено спустя 2 минуты
difexacaw пишет:
Хотелось бы реальные цифры увидеть, закрутить в цикл два дизасма

Неужели это большая проблема для такого Мэтра, как Вы?
Закрутите!


Ранг: 316.3 (мудрец)
Статус: Участник

Создано: 23 июля 2018 00:04 New!
Цитата · Личное сообщение · #29

hypn0

Нужно собирать это всё и разбираться в интерфейсах. На это нужно время, проще спросить у тех, кто это использовал.

Ранг: 19.7 (новичок)
Статус: Участник

Создано: 23 июля 2018 00:08 · Поправил: RevCred New!
Цитата · Личное сообщение · #30

difexacaw пишет:
Хотелось бы реальные цифры увидеть, закрутить в цикл два дизасма и снять статистику.

закрутите и поделитесь инфой со всеми, мне тоже было бы интересно посмотреть.
Я бы не отказался от более быстрого и точного length дизасма.

difexacaw пишет:
Нужно собирать это всё и разбираться в интерфейсах.

https://github.com/zyantific/zydis/blob/251a83e6f69d9bae3a8162db669ad43a82483b9e/examples/ZydisPerfTest.c#L176
вот пример использования только lde.
осталось найти время и сбилдить
. 1 . 2 . >>
 eXeL@B —› Вопросы новичков —› Stack BT

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS