uses binding of printInst on MCInstPrinter for printing instruction. also fixed a bug in llvm.mc.Disassembler.decode: idx should start at zero, and we should pass code.getBase() + idx to getInstruction. idx must start at zero because the while loop compares it against code.getExtent() which returns only the length of bs.
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
import llvm
|
|
|
|
if llvm.version >= (3, 4):
|
|
|
|
from llvm.target import TargetMachine
|
|
from llvm import mc
|
|
from llvm.mc import Disassembler
|
|
|
|
llvm.target.initialize_all()
|
|
|
|
def print_instructions(dasm, bs):
|
|
print("print instructions")
|
|
for (addr, inst) in dasm.decode(bs, 0x4000):
|
|
if inst is None:
|
|
print("\t0x%x => (bad)" % (addr))
|
|
else:
|
|
ops = ", ".join(map(lambda op: repr(op), inst.operands()))
|
|
if isinstance(inst, mc.BadInstr):
|
|
print("\t0x%x (bad) ops = %s" % (addr, ops))
|
|
else:
|
|
print("\t0x%x ops = %s" % (addr, ops))
|
|
|
|
for line in str(inst).split("\n"):
|
|
print("\t%s" % (line))
|
|
|
|
|
|
x86 = TargetMachine.x86()
|
|
print("x86: LE=%s" % x86.is_little_endian())
|
|
print_instructions(Disassembler(x86), "\x01\xc3\xc3\xcc\x90")
|
|
|
|
x86_64 = TargetMachine.x86_64()
|
|
print("x86-64: LE=%s" % x86_64.is_little_endian())
|
|
print_instructions(Disassembler(x86_64), "\x55\x48\x89\xe8")
|
|
|
|
arm = TargetMachine.arm()
|
|
print("arm: LE=%s" % arm.is_little_endian())
|
|
code = [
|
|
"\xe9\x2d\x48\x00",
|
|
"\xea\x00\x00\x06",
|
|
"\xe2\x4d\xd0\x20",
|
|
"\xe2\x8d\xb0\x04",
|
|
"\xe5\x0b\x00\x20"
|
|
]
|
|
print_instructions(Disassembler(arm), "".join(map(lambda s: s[::-1], code)))
|