
Привязки Python для VEX IR от Valgrind.
PyVEX — это привязки Python для VEX IR.
Репозиторий проекта: https://github.com/angr/pyvex
Документация: https://api.angr.io/projects/pyvex/en/latest/
PyVEX можно установить с помощью pip:
pip install pyvex
import pyvex
import archinfo
# translate an AMD64 basic block (of nops) at 0x400400 into VEX
irsb = pyvex.lift(b"\x90\x90\x90\x90\x90", 0x400400, archinfo.ArchAMD64())
# pretty-print the basic block
irsb.pp()
# this is the IR Expression of the jump target of the unconditional exit at the end of the basic block
print(irsb.next)
# this is the type of the unconditional exit (i.e., a call, ret, syscall, etc)
print(irsb.jumpkind)
# you can also pretty-print it
irsb.next.pp()
# iterate through each statement and print all the statements
for stmt in irsb.statements:
stmt.pp()
# pretty-print the IR expression representing the data, and the *type* of that IR expression written by every store statement
import pyvex
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print("Data:", end="")
stmt.data.pp()
print("")
print("Type:", end="")
print(stmt.data.result_type)
print("")
# pretty-print the condition and jump target of every conditional exit from the basic block
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Exit):
print("Condition:", end="")
stmt.guard.pp()
print("")
print("Target:", end="")
stmt.dst.pp()
print("")
# these are the types of every temp in the IRSB
print(irsb.tyenv.types)
# here is one way to get the type of temp 0
print(irsb.tyenv.types[0])
Имейте в виду, что это синтаксическое представление базового блока. То есть оно покажет вам смысл блока, но у вас не будет контекста, чтобы определить, например, какие реальные данные записываются инструкцией store.
Для работы с широким разнообразием архитектур полезно проводить анализ на промежуточном представлении. IR абстрагирует несколько различий между архитектурами при работе с разными платформами, позволяя запустить один и тот же анализ для всех из них:
rax в AMD64 хранится начиная с адреса 16 в этом адресном пространстве).Существует множество вариантов IR. Мы используем VEX, поскольку поддержка трансляции бинарного кода в VEX довольно хорошо развита. VEX представляет собой независимую от архитектуры, лишенную побочных эффектов модель для ряда целевых языков машинного кода. Она абстрагирует машинный код в представление, предназначенное для упрощения анализа программ. Это представление имеет пять основных классов объектов:
t0. Они имеют строгую типизацию (например, «64-битное целое» или «32-битное число с плавающей точкой»).VEX IR на самом деле довольно хорошо документирован в файле libvex_ir.h (https://github.com/angr/vex/blob/dev/pub/libvex_ir.h) в репозитории VEX. Для ленивых мы подробно рассмотрим некоторые части VEX, с которыми вы, вероятно, будете взаимодействовать довольно часто. Начнем с некоторых выражений IR:
| IR Expression | Значение после вычисления | Пример вывода VEX |
|---|---|---|
| Constant | Константное значение. | 0x4:I32 |
| Read Temp | Значение, сохраненное во временной переменной VEX. | RdTmp(t10) |
| Get Register | Значение, сохраненное в регистре. | GET:I32(16) |
| Load Memory | Значение, сохраненное по адресу в памяти, где адрес задается другим выражением IR. | LDle:I32 / LDbe:I64 |
| Operation | Результат указанной операции IR, примененной к аргументам выражений IR. | Add32 |
| If-Then-Else | Если данное выражение IR вычисляется в 0, вернуть одно выражение IR. В противном случае вернуть другое. | ITE |
| Helper Function | VEX использует вспомогательные функции C для определенных операций, таких как вычисление регистров флагов условий для некоторых архитектур. Эти функции возвращают выражения IR. | function_name() |
Затем эти выражения, в свою очередь, используются в операторах IR. Вот некоторые из них:
| IR Statement | Значение | Пример вывода VEX |
|---|---|---|
| Write Temp | Установить временную переменную VEX равной значению данного выражения IR. | WrTmp(t1) = (IR Expression) |
| Put Register | Обновить регистр значением данного выражения IR. | PUT(16) = (IR Expression) |
| Store Memory | Обновить ячейку в памяти (заданную как выражение IR) значением (также заданным как выражение IR). | STle(0x1000) = (IR Expression) |
| Exit | Условный выход из базового блока, где целевой адрес перехода задается выражением IR. Условие также задается выражением IR. | if (condition) goto (Boring) 0x4000A00:I32 |