added align parameter to llvm.mc.Disassembler.decode
i cant find any method in llvm to automatically get the correct instruction alignment for disassembling. i thought it would be MCAsmInfo.getMinInstAlignment, but that value is 1 for the ARM target machine. since that is clearly the wrong instruction alignment for disassembling arm, the user should be able to configure the alignment to whatever is needed.
This commit is contained in:
parent
3743146121
commit
aa264cee2d
2 changed files with 19 additions and 7 deletions
|
|
@ -184,14 +184,21 @@ class Disassembler(object):
|
|||
def bad_instr(self, mcinst):
|
||||
return BadInstr(mcinst, self.tm)
|
||||
|
||||
def decode(self, bs, base_addr):
|
||||
def decode(self, bs, base_addr, align=None):
|
||||
'''
|
||||
decodes some the bytes in @bs into instructions and yields
|
||||
each instruction as it is decoded. @base_addr is the base address
|
||||
where the instruction bytes are from (not an offset into
|
||||
@bs). yields instructions in the form of (addr, data, inst) where
|
||||
addr is an integer, data is a tuple of integers and inst is an instance of
|
||||
llvm.mc.Instr
|
||||
llvm.mc.Instr. @align specifies the byte alignment of instructions and
|
||||
is only used if an un-decodable instruction is encountered, in which
|
||||
case the disassembler will skip the following bytes until the next
|
||||
aligned address. if @align is unspecified, the default alignment
|
||||
for the architecture will be used, however this may not be ideal
|
||||
for disassembly. for example, the default alignment for ARM is 1, but you
|
||||
probably want it to be 4 for the purposes of disassembling ARM
|
||||
instructions.
|
||||
'''
|
||||
|
||||
if isinstance(bs, str) and sys.version_info.major >= 3:
|
||||
|
|
@ -201,7 +208,8 @@ class Disassembler(object):
|
|||
|
||||
code = api.llvm.StringRefMemoryObject.new(bs, base_addr)
|
||||
idx = 0
|
||||
align = self.mai.getMinInstAlignment()
|
||||
if not isinstance(align, int) or align < 1:
|
||||
align = self.mai.getMinInstAlignment()
|
||||
|
||||
while(idx < code.getExtent()):
|
||||
inst = api.llvm.MCInst.new()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ if llvm.version >= (3, 4):
|
|||
|
||||
llvm.target.initialize_all()
|
||||
|
||||
def print_instructions(dasm, bs):
|
||||
def print_instructions(dasm, bs, align=None):
|
||||
branch_properties = [
|
||||
'is_branch',
|
||||
'is_cond_branch',
|
||||
|
|
@ -21,7 +21,7 @@ if llvm.version >= (3, 4):
|
|||
]
|
||||
|
||||
print("print instructions")
|
||||
for (addr, data, inst) in dasm.decode(bs, 0x4000):
|
||||
for (addr, data, inst) in dasm.decode(bs, 0x4000, align):
|
||||
|
||||
if inst is None:
|
||||
print("\t0x%x => (bad)" % (addr))
|
||||
|
|
@ -55,6 +55,10 @@ if llvm.version >= (3, 4):
|
|||
"\xea\x00\x00\x06",
|
||||
"\xe2\x4d\xd0\x20",
|
||||
"\xe2\x8d\xb0\x04",
|
||||
"\xe5\x0b\x00\x20"
|
||||
"\xe5\x0b\x00\x20",
|
||||
"\x03\x30\x22\xe0", #bad instruction to test alignment
|
||||
"\x73\x20\xef\xe6", #bad instruction to test alignment
|
||||
"\x18\x00\x1b\xe5",
|
||||
"\x10\x30\xa0\xe3"
|
||||
]
|
||||
print_instructions(Disassembler(arm), "".join(map(lambda s: s[::-1], code)))
|
||||
print_instructions(Disassembler(arm), "".join(map(lambda s: s[::-1], code)), 4)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue