
Valgrind के VEX IR के लिए Python बाइंडिंग्स।
PyVEX, VEX IR के लिए Python bindings है।
प्रोजेक्ट रिपॉजिटरी: 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])
ध्यान रखें कि यह एक बेसिक ब्लॉक का syntactic प्रतिनिधित्व है। अर्थात्, यह आपको बताएगा कि ब्लॉक का क्या अर्थ है, लेकिन आपके पास यह कहने के लिए कोई संदर्भ नहीं होता कि, उदाहरण के लिए, किसी store निर्देश द्वारा वास्तविक रूप से कौन-सा डेटा लिखा जाता है।
व्यापक रूप से विविध आर्किटेक्चरों से निपटने के लिए, एक intermediate representation पर विश्लेषण करना उपयोगी होता है। एक IR विभिन्न आर्किटेक्चरों से निपटते समय कई आर्किटेक्चर अंतरों को अमूर्त कर देता है, जिससे एक ही विश्लेषण उन सभी पर चलाया जा सकता है:
rax इस मेमोरी स्पेस में address 16 से शुरू होकर संग्रहीत होता है)।एक IR के लिए बहुत सारे विकल्प हैं। हम VEX का उपयोग करते हैं, क्योंकि बाइनरी कोड को VEX में uplift करना काफी अच्छी तरह समर्थित है। VEX कई लक्ष्य मशीन भाषाओं का एक architecture-agnostic, side-effects-free प्रतिनिधित्व है। यह मशीन कोड को एक ऐसे प्रतिनिधित्व में अमूर्त करता है जिसे प्रोग्राम विश्लेषण को आसान बनाने के लिए डिज़ाइन किया गया है। इस प्रतिनिधित्व में मुख्य रूप से पाँच वर्ग के ऑब्जेक्ट होते हैं:
t0 से शुरू होकर। ये temporaries strongly typed होते हैं (अर्थात्, "64-bit integer" या "32-bit float")।VEX IR वास्तव में VEX रिपॉजिटरी में libvex_ir.h फ़ाइल (https://github.com/angr/vex/blob/dev/pub/libvex_ir.h) में काफी अच्छी तरह प्रलेखित है। आलसी लोगों के लिए, हम VEX के कुछ ऐसे भागों का विवरण देंगे जिनके साथ आप संभवतः काफी बार इंटरैक्ट करेंगे। आरंभ करने के लिए, यहाँ कुछ IR Expressions हैं:
| IR Expression | Evaluated Value | VEX Output Example |
|---|---|---|
| Constant | एक स्थिर मान। | 0x4:I32 |
| Read Temp | एक VEX temporary variable में संग्रहीत मान। | RdTmp(t10) |
| Get Register | एक रजिस्टर में संग्रहीत मान। | GET:I32(16) |
| Load Memory | एक मेमोरी address पर संग्रहीत मान, जिसका address एक अन्य IR Expression द्वारा निर्दिष्ट होता है। | LDle:I32 / LDbe:I64 |
| Operation | एक निर्दिष्ट IR Operation का परिणाम, जो निर्दिष्ट IR Expression arguments पर लागू होता है। | Add32 |
| If-Then-Else | यदि दिया गया IR Expression 0 पर evaluate होता है, तो एक IR Expression लौटाएँ। अन्यथा, दूसरा लौटाएँ। | ITE |
| Helper Function | VEX कुछ ऑपरेशनों के लिए C helper functions का उपयोग करता है, जैसे कुछ आर्किटेक्चरों के conditional flags रजिस्टरों की गणना करना। ये functions IR Expressions लौटाते हैं। | function_name() |
इन expressions का उपयोग, बदले में, IR Statements में किया जाता है। यहाँ कुछ सामान्य हैं: