Что нужно ОП, так это дисциплинированный подход к выполнению этой задачи.
Ему нужен хороший синтаксический анализатор исходного кода на ассемблере, чтобы он знал, что у него есть точное его представление. Помимо чистой части синтаксического анализа, ему придется полностью эмулировать ассемблер, включая все сложности, такие как макросы, условные блоки, счетчики нескольких местоположений, абсолютные/относительные/внешние символы и т. д. (Создайте хороший синтаксический анализатор, полагаясь исключительно на на регулярных выражениях не будет работать.)
Затем ему нужно будет вычислить первую оценку графа потока управления, проверив последовательности машинных инструкций и ветвей. Это может быть сложнее сделать, чем кажется; в больших, сложных ассемблерных кодах люди злоупотребляют точками входа в процедуры, так что иногда бывает трудно отличить, что такое инструкция, а что данные.
(Вот трюк, который я использую в большом x86-приложении. Я хочу добавить проверку работоспособности в свой код во многих местах. Тесты работоспособности выглядят так:
<test for some sane condition>
jf location+3 ; this branchs to a breakpoint in the middle of the next instruction
cmp al, 0xCC ; the immediate value is a BREAKPOINT opcode
Они компактны, и точка останова возникает, когда происходит что-то плохое. Но при анализе этой программы на предмет потока управления "jmp false" иногда переходит в то, что кажется серединой инструкции. Как ОП это смоделирует?)
Следующей сложностью являются указатели на код. Код на ассемблере часто генерирует много указателей на другие инструкции, а затем прячет эти указатели в разных местах (инструкция вызова помещает их в стек данных для x86), извлекает их, а затем выполняет «непрямой jmp». Если вы хотите знать, куда может пойти этот jmp, вам нужно отслеживать возможные значения, которые могут содержаться в ячейке памяти, что означает, что вам нужно выполнить анализ потока данных (как значения попадают туда и откуда) и объединить с графом вызовов построение (не можете добраться до этой функции? Хорошо, тогда то, куда она идет, не повлияет на этот код), чтобы вычислить разумный ответ.
Выполнение всего этого специальными методами приведет к неточным (бесполезным) ответам. ОП должен найти основу для создания своего синтаксического анализатора и реализовать качественные алгоритмы анализа точек, если он надеется получить хороший результат.
C не предназначен специально для поддержки этой задачи. Он может сделать это с достаточным количеством дополнительного пота, но это верно для любого языка программирования.
(Проверьте мою биографию на наличие такого фреймворка. OP может использовать любой фреймворк, который ему подходит).
person
Ira Baxter
schedule
20.02.2016