
Liaisons Python pour le VEX IR de Valgrind.
PyVEX est une liaison Python pour le VEX IR.
Dépôt du projet : https://github.com/angr/pyvex
Documentation : https://api.angr.io/projects/pyvex/en/latest/
PyVEX peut être installé via 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])
Gardez à l'esprit qu'il s'agit d'une représentation syntaxique d'un bloc de base. C'est-à-dire qu'elle vous indiquera ce que signifie le bloc, mais vous n'avez aucun contexte pour dire, par exemple, quelles données réelles sont écrites par une instruction de stockage.
Pour traiter des architectures très diverses, il est utile d'effectuer des analyses sur une représentation intermédiaire. Une IR fait abstraction de plusieurs différences d'architecture lors du traitement de différentes architectures, permettant ainsi d'exécuter une seule analyse sur toutes :
rax d'AMD64 est stocké à partir de l'adresse 16 dans cet espace mémoire).Il existe de nombreux choix pour une IR. Nous utilisons VEX, car la conversion du code binaire en VEX est assez bien prise en charge. VEX est une représentation indépendante de l'architecture et sans effets de bord de plusieurs langages machines cibles. Il fait abstraction du code machine en une représentation conçue pour faciliter l'analyse de programme. Cette représentation comporte cinq classes principales d'objets :
t0. Ces temporaires sont fortement typées (c'est-à-dire « entier 64 bits » ou « flottant 32 bits »).Le VEX IR est en fait assez bien documenté dans le fichier libvex_ir.h (https://github.com/angr/vex/blob/dev/pub/libvex_ir.h) du dépôt VEX. Pour les paresseux, nous détaillerons certaines parties de VEX avec lesquelles vous interagirez probablement assez fréquemment. Pour commencer, voici quelques expressions IR :
| Expression IR | Valeur évaluée | Exemple de sortie VEX |
|---|---|---|
| Constant | Une valeur constante. | 0x4:I32 |
| Read Temp | La valeur stockée dans une variable temporaire VEX. | RdTmp(t10) |
| Get Register | La valeur stockée dans un registre. | GET:I32(16) |
| Load Memory | La valeur stockée à une adresse mémoire, l'adresse étant spécifiée par une autre expression IR. | LDle:I32 / LDbe:I64 |
| Operation | Un résultat d'une opération IR spécifiée, appliquée à des arguments d'expression IR spécifiés. | Add32 |
| If-Then-Else | Si une expression IR donnée est évaluée à 0, retourne une expression IR. Sinon, en retourne une autre. | ITE |
| Helper Function | VEX utilise des fonctions d'assistance C pour certaines opérations, comme le calcul des registres d'indicateurs de condition de certaines architectures. Ces fonctions retournent des expressions IR. | function_name() |
Ces expressions sont ensuite utilisées dans les instructions IR. Voici quelques-unes courantes :