Очевидно для анализа самомодифицирующегося кода в статике (и пофиг, что эта статика не особо возможна без динамики). Тс же сказал, что хочет видеть программу во всех ее состояниях сразу, в виде картинки. То ли плугин к иде лабает, то ли еще чего, но необходимость рисовать этот граф на экране как бы указывает на средство ручного анализа.
А что там должно отображать состояния, какие узлы, что представляют ребра? Если это блоки/бранчи, то как они отобразят состояния?
Ребра - бранчи или вызовы. Узлы - то, что между ними. Отображать можно как ида отображает для статики. Кстати разные состояния прекрасно ложатся в коцепцию гидры с ее разными адресными пространствами, куда можно насувать модифицированного кода и ловко расставить бранчи. И часть работы себе можно сократить, пусть гидра обходит и визуализирует. Правда я в последнее время замечаю, что деконпиль гидры пока не очень любит альтернативные адресные пространства.
Ну а какой конечный смысл в этом? Кто-нибудь вообще графом в иде пользуется? По-моему проще в ассемблерный листинг смотреть, тем более в декомпиль. Единственное практическое применение, которое пока на ум приходит это дифф, как в биндиффе. Ну и кодефлоу/порядок вызовов каких-нибудь апи, чтобы быстро понять, что под капотом у какого-то сложного метода, например.
Можно пару примеров использования? У меня это белое окошко с мешаниной из черточек и декорированых имен, выглядит не очень юзабельно.
Пример использования - нажать и смотреть) Да, в иде убого сделано, по сути она формирует dot-файл и скрампливает внешнему приложению для рисования графа, никак с ним не взаимодействуя. В гидре эта же возможность сделана treeview'шками, в которые можно кликать. Но как бы примерное представление о том, как изучаемый участок программы устроен, даже такие графы дают.
С тем же успехом можно смотреть в ковер. Все пути идут в обработчик ошибок, а виртуальные методы ожидаемо идут лесом. И разглядеть что-то можно только в тех масштабах, в которых, опять же, проще в дизасме. Вариант с тривью звучит интереснее, наверное пора браться за гидру.
ни в какой лес они не идут. просто ставь бряк на запись первого элемента, то бишь на то что вернёт new - и вуаля - у тебя в руках вся иерархия классов. иными словами - конструктор работает так: вызов базового конструктора, установка собственной вфптр, вызов всех конструкторов членов класса, исполнение кода конструктора. всё. и возврат в предыдущий фрейм.
Вроде все слова знакомые, а... Ида отладчик мне что, иерархию классов где-то автоматом отрисует? И xref'ы на виртуальные методы поставит? А если там метод у пачки классов-наследников из одного и того же места дергается, и в динамике их не так просто дернуть все по очереди?
f13nd, Я же говорил что попробую https://exelab.ru/f/index.php?action=vthread&forum=5&topic=26141#20 Промежуточная задача - оптимизация текущей реализации визора, что бы по быстрому. Двоичная трансляция не продумана полностью, на архитектуру уйдут недели. Единственный способ - выполнять только код в целевом образе. Для этого нужно получить события передачи управления в этот модуль. Эта задача сводится к задаче отличия кода от данных, если бы код был маркирован(pe-cfg), то можно было бы его весь выделить за затереть. Таким образом попытка выполнения привела бы к ловушке и можно было бы модифицировать эти EP. Но так как входы(EP) не известны, данные трогать нельзя, то единственный вариант - заблокировать исполнение в образе. Для этого включается NX, с проекции снимается X(R/W). При каждой передаче управления в образ срабатывает ловушка, из стека берётся адрес возврата, вызывающее проц. ветвление патчится на стаб, запускающий визор. Тогда следующее такое событие не наступит для вызывающего call. Так накапливаются EP, затем можно их применить при перезапуске апп. Причём тут графы ? q2e74, Тебе тоже будет интересно, как раз по теме. Просто переместить call в буфер нельзя, будут ошибки. Во первых размер должен быть >5, что бы влезл near-jmp. Если же размер инструкции менее 5 байт, то необходимо пересобрать всю текущую ветвь. Это нужно как минимум что бы узнать что после изменения более одной инструкции они присутствуют в текущей ветви(после call может быть jmp и далее чужой код). Это классическая проблема патчей. Для этого весь кодес вместе с call пересобирается в буфер(это всё делается через работу с графами). При тесте на квакухе(quake3) - EP всего несколько(4), вызывающих их call - сотни. Буфер с пересобираемыми ветвями не влез в 64k(но влез в 1М). Один call не патчится - call(2b)/jmp(2b)/не_наш_код, из за этого довольно много генерится фаултов. Квак заводится полтора часа и сильно очень лагает.
дополню немного: найти в проге место где подменить jnz на jmp - это кряк. а вот декомпилировать всю функцию/метод - вот это уже реверс. --- Сообщение объединено, 7 ноя 2019 --- слова - это всё хорошо. тыбы расшарил для начала исходный код.
Насколько я понял,стек вызовов функций в виде графа нужен для решения кракмов, где чото там прячиццо от реверсера, пакеры, протекторы Это точно уровень новичка?
sn0w, > тыбы расшарил для начала исходный код. Конструктор опенсорсный, он был в inception ezine. В кайт граф представляет собой довольно сложное дерево, это существенный недостаток. Так например в примере выше нужно было вставить инструкцию в начало блока, это оказалось не так просто сделать, тк я не помню всё дерево, я сделал иначе, но это не правильно. Если вы про визор, то билд вам весь не нужен, основной цикл паблик.