class Disassemble: """allows to disassemble code segments of a BinImage""" def __init__(self, use_objdump=False, cpu='68000'): self.disasm = DisAsm(use_objdump, cpu) def _get_line_info(self, segment, addr, size): infos = [] # info about src line d = segment.find_debug_line(addr) if d is not None: f = d.get_file() infos.append( "src %10s:%d [%s]" % (f.get_src_file(), d.get_src_line(), f.get_dir_name())) # info about relocation r = segment.find_reloc(addr, size) if r is not None: delta = r[2] - addr infos.append("reloc +%02d: (#%02d + %08x)" % (delta, r[1].id, r[0].addend)) return infos def disassemble(self, segment, bin_img): # make sure its a code segment if segment.seg_type != SEGMENT_TYPE_CODE: return None # generate raw assembly data = segment.data lines = self.disasm.disassemble(data) # process lines result = [] for l in lines: addr = l[0] word = l[1] code = l[2] # try to find a symbol for this addr symbol = segment.find_symbol(addr) if symbol is not None: line = "\t\t\t\t%s:" % symbol result.append(line) # create final line line = "%08x\t%-20s\t%-30s " % (addr, " ".join( map(lambda x: "%04x" % x, word)), code) # create line info size = len(word) * 2 info = self._get_line_info(segment, addr, size) if info is None or len(info) == 0: result.append(line) else: result.append(line + "; " + info[0]) spc = " " * len(line) for i in info[1:]: result.append(spc + "; " + i) return result
class Disassemble: """allows to disassemble code segments of a BinImage""" def __init__(self, use_objdump=False, cpu='68000'): self.disasm = DisAsm(use_objdump, cpu) def _get_line_info(self, segment, addr, size): infos = [] # info about src line d = segment.find_debug_line(addr) if d is not None: f = d.get_file() infos.append("src %10s:%d [%s]" % (f.get_src_file(), d.get_src_line(), f.get_dir_name())) # info about relocation r = segment.find_reloc(addr, size) if r is not None: delta = r[2] - addr infos.append("reloc +%02d: (#%02d + %08x)" % (delta, r[1].id, r[0].addend)) return infos def disassemble(self, segment, bin_img): # make sure its a code segment if segment.seg_type != SEGMENT_TYPE_CODE: return None # generate raw assembly data = segment.data lines = self.disasm.disassemble(data) # process lines result = [] for l in lines: addr = l[0] word = l[1] code = l[2] # try to find a symbol for this addr symbol = segment.find_symbol(addr) if symbol is not None: line = "\t\t\t\t%s:" % symbol result.append(line) # create final line line = "%08x\t%-20s\t%-30s " % (addr," ".join(map(lambda x: "%04x" %x, word)),code) # create line info size = len(word) * 2 info = self._get_line_info(segment, addr, size) if info is None or len(info) == 0: result.append(line) else: result.append(line + "; " + info[0]) spc = " " * len(line) for i in info[1:]: result.append(spc + "; " + i) return result
def handle_blkdev(self, blkdev): n = len(self.opts) if n == 0: print "Usage: boot ( show [hex] [asm] | read <file> | write <file> | install [boot1x] | clear )" return 1 cmd = self.opts[0] # fetch boot blcok bb = BootBlock(blkdev, 0) bb.read() # boot show [hex] [asm] if cmd == 'show': bb.dump() if bb.valid and bb.boot_code != None: if 'hex' in self.opts: print_hex(bb.boot_code) if 'asm' in self.opts: dis = DisAsm() code = dis.disassemble(bb.boot_code) dis.dump(code) return 0 # boot read <file> elif cmd == 'read': if n > 1: if bb.valid: if bb.boot_code != None: f = open(self.opts[1], "wb") f.write(bb.boot_code) f.close() return 0 else: print "No Boot Code found!" return 2 else: print "Invalid Boot Block!" return 1 else: print "No file name!" return 1 # boot write <file> elif cmd == 'write': if n > 1: f = open(self.opts[1], "rb") data = f.read() f.close() ok = bb.set_boot_code(data) if ok: bb.write() return 0 else: print "Boot Code invalid!" return 2 else: print "No file name!" return 1 # boot install [<name>] elif cmd == 'install': if n == 1: # default boot code name = "boot2x3x" else: name = self.opts[1] # boot code directory bc_dir = bb.get_boot_code_dir() if bc_dir == None: print "No boot code directory found!" return 1 path = os.path.join(bc_dir, name + ".bin") if not os.path.exists: print "Boot code '%s' not found!" % path return 1 # read data f = open(path, "rb") data = f.read() f.close() ok = bb.set_boot_code(data) if ok: bb.write() return 0 else: print "Boot Code invalid!" return 2 # boot clear elif cmd == 'clear': bb.set_boot_code(None) bb.write() return 0 # boot ? else: print "Unknown boot command!" return 1
def __init__(self, use_objdump=False, cpu='68000'): self.disasm = DisAsm(use_objdump, cpu)
def handle_blkdev(self, blkdev): n = len(self.opts) if n == 0: print("Usage: boot ( show [hex] [asm] | read <file> | write <file> | install [boot1x] | clear )") return 1 cmd = self.opts[0] # fetch boot blcok bb = BootBlock(blkdev, 0) bb.read() # boot show [hex] [asm] if cmd == 'show': bb.dump() if bb.valid and bb.boot_code != None: if 'hex' in self.opts: print_hex(bb.boot_code) if 'asm' in self.opts: dis = DisAsm() code = dis.disassemble(bb.boot_code) dis.dump(code) return 0 # boot read <file> elif cmd == 'read': if n > 1: if bb.valid: if bb.boot_code != None: f = open(self.opts[1], "wb") f.write(bb.boot_code) f.close() return 0 else: print("No Boot Code found!") return 2 else: print("Invalid Boot Block!") return 1 else: print("No file name!") return 1 # boot write <file> elif cmd == 'write': if n > 1: f = open(self.opts[1], "rb") data = f.read() f.close() ok = bb.set_boot_code(data) if ok: bb.write() return 0 else: print("Boot Code invalid!") return 2 else: print("No file name!") return 1 # boot install [<name>] elif cmd == 'install': if n == 1: # default boot code name = "boot2x3x" else: name = self.opts[1] # boot code directory bc_dir = bb.get_boot_code_dir() if bc_dir == None: print("No boot code directory found!") return 1 path = os.path.join(bc_dir, name + ".bin") if not os.path.exists: print("Boot code '%s' not found!" % path) return 1 # read data f = open(path,"rb") data = f.read() f.close() ok = bb.set_boot_code(data) if ok: bb.write() return 0 else: print("Boot Code invalid!") return 2 # boot clear elif cmd == 'clear': bb.set_boot_code(None) bb.write() return 0 # boot ? else: print("Unknown boot command!") return 1
class HunkDisassembler: def __init__(self, use_objdump=False, cpu='68000'): self.disasm = DisAsm(use_objdump, cpu) def get_symtab(self, hunk): for h in hunk[1:]: if h['type'] == Hunk.HUNK_SYMBOL: return h['symbols'] return None def find_symbol(self, hunk, offset, always): symtab = self.get_symtab(hunk) if symtab == None: if always: return "%08x" % offset else: return None symmap = {} for s in symtab: symmap[s[1]] = s[0] offs = sorted(symmap.keys()) last = None last_offset = 0 for o in offs: if o == offset: return symmap[o] if always: if o < offset: # approximate to last symbol if last != None: return last + " + %08x" % (o - last_offset) else: return "%08x" % offset last = symmap[o] last_offset = o if always: return "%08x" % offset else: return None def find_src_line(self, hunk, addr): for h in hunk[1:]: if h['type'] == Hunk.HUNK_DEBUG and h['debug_type'] == 'LINE': src_map = h['src_map'] for e in src_map: src_line = e[0] src_addr = e[1] + h['debug_offset'] if src_addr == addr: return (h['src_file'], src_line) return None # map reloc type to number of words to be relocated map_reloc_to_num_words = { Hunk.HUNK_ABSRELOC32: 2, Hunk.HUNK_DREL16: 1, Hunk.HUNK_DREL32: 2 } # find_reloc # return # 0 - rel_offset to addr reloc begin (in words) # 1 - size of reloc (in words) # 2 - hunk number reloc references # 3 - relative offset in hunk (in bytes) # 4 - reloc hunk def find_reloc(self, hunk, addr, word): end_addr = addr + len(word) * 2 for h in hunk[1:]: valid = self.map_reloc_to_num_words.has_key(h['type']) if valid: num_words = self.map_reloc_to_num_words[h['type']] reloc = h['reloc'] for hunk_num in reloc: offsets = reloc[hunk_num] for off in offsets: if off >= addr and off + num_words * 2 <= end_addr: word_offset = (off - addr) / 2 # in words # calc offset addr = 0 for i in xrange(num_words): addr = addr * 0x10000 + word[word_offset + i] reloc_type_name = h['type_name'].replace( "HUNK_", "").lower() return (word_offset, num_words, hunk_num, addr, reloc_type_name) return None map_ext_ref_to_num_words = { Hunk.EXT_ABSREF32: 2, Hunk.EXT_RELREF16: 1, Hunk.EXT_DEXT16: 1 } # find_ext_ref # return # 0 - word offset to word begin (in words) # 1 - size of reloc (in words) # 2 - name of external symbol # 3 - type name of ext ref def find_ext_ref(self, hunk, addr, word): end_addr = addr + len(word) * 2 for h in hunk[1:]: if h['type'] == Hunk.HUNK_EXT: for ext in h['ext_ref']: refs = ext['refs'] valid = self.map_ext_ref_to_num_words.has_key(ext['type']) if valid: num_words = self.map_ext_ref_to_num_words[ext['type']] for ref in refs: if ref >= addr and ref < end_addr: word_offset = (ref - addr) / 2 type_name = ext['type_name'].replace( "EXT_", "").lower() return (word_offset, num_words, ext['name'], type_name) return None # search the HUNK_EXT for a defintion def find_ext_def(self, hunk, addr): for h in hunk[1:]: if h['type'] == Hunk.HUNK_EXT: for ext in h['ext_def']: if addr == ext['def']: return ext['name'] return None # search the index of a lib for a definition def find_index_def(self, hunk, addr): main = hunk[0] if main.has_key('index_hunk'): info = main['index_hunk'] if info.has_key('defs'): for d in info['defs']: if d['value'] == addr: return d['name'] return None def find_symbol_or_def(self, hunk, addr, always): symbol = self.find_symbol(hunk, addr, False) if symbol == None: symbol = self.find_ext_def(hunk, addr) if symbol == None: symbol = self.find_index_def(hunk, addr) if symbol == None and always: return "%08x" % addr return symbol # ----- show disassembly ----- def show_disassembly(self, hunk, seg_list, start): main = hunk[0] lines = self.disasm.disassemble(main['data'], start) # show line by line for l in lines: addr = l[0] word = l[1] code = l[2] # try to find a symbol for this addr symbol = self.find_symbol_or_def(hunk, addr, False) # create line info info = [] # find source line info line = self.find_src_line(hunk, addr) if line != None: (src_file, src_line) = line info.append("src: %s:%d" % (src_file, src_line)) # find an extref ext_ref = self.find_ext_ref(hunk, addr, word) if ext_ref != None: ref_symbol = ext_ref[2] ref_type = ext_ref[3] info.append("%s: %s" % (ref_type, ref_symbol)) # find a relocation reloc = self.find_reloc(hunk, addr, word) if reloc != None: hunk_num = reloc[2] offset = reloc[3] reloc_type_name = reloc[4] # a self reference reloc_symbol = self.find_symbol_or_def(seg_list[hunk_num], offset, True) if hunk_num == main['hunk_no']: src = "self" else: src = "#%03d %s" % (hunk_num, seg_list[hunk_num][0]['type_name']) info.append("%s: %s: %s" % (reloc_type_name, src, reloc_symbol)) # build comment from all infos if len(info) > 0: comment = "; " + ", ".join(info) else: comment = "" # create final line if symbol != None: print "\t\t\t\t%s:" % symbol print "%08x\t%-20s\t%-30s %s" % (addr, " ".join( map(lambda x: "%04x" % x, word)), code, comment)
def __init__(self, use_objdump = False, cpu = '68000'): self.disasm = DisAsm(use_objdump, cpu)
class HunkDisassembler: def __init__(self, use_objdump = False, cpu = '68000'): self.disasm = DisAsm(use_objdump, cpu) def get_symtab(self, hunk): for h in hunk[1:]: if h['type'] == Hunk.HUNK_SYMBOL: return h['symbols'] return None def find_symbol(self, hunk, offset, always): symtab = self.get_symtab(hunk) if symtab == None: if always: return "%08x" % offset else: return None symmap = {} for s in symtab: symmap[s[1]] = s[0] offs = sorted(symmap.keys()); last = None last_offset = 0 for o in offs: if o == offset: return symmap[o] if always: if o < offset: # approximate to last symbol if last != None: return last + " + %08x" % (o - last_offset) else: return "%08x" % offset last = symmap[o] last_offset = o if always: return "%08x" % offset else: return None def find_src_line(self, hunk, addr): for h in hunk[1:]: if h['type'] == Hunk.HUNK_DEBUG and h['debug_type'] == 'LINE': src_map = h['src_map'] for e in src_map: src_line = e[0] src_addr = e[1] + h['debug_offset'] if src_addr == addr: return (h['src_file'],src_line) return None # map reloc type to number of words to be relocated map_reloc_to_num_words = { Hunk.HUNK_ABSRELOC32 : 2, Hunk.HUNK_DREL16 : 1, Hunk.HUNK_DREL32 : 2 } # find_reloc # return # 0 - rel_offset to addr reloc begin (in words) # 1 - size of reloc (in words) # 2 - hunk number reloc references # 3 - relative offset in hunk (in bytes) # 4 - reloc hunk def find_reloc(self, hunk, addr, word): end_addr = addr + len(word) * 2 for h in hunk[1:]: valid = self.map_reloc_to_num_words.has_key(h['type']) if valid: num_words = self.map_reloc_to_num_words[h['type']] reloc = h['reloc'] for hunk_num in reloc: offsets = reloc[hunk_num] for off in offsets: if off >= addr and off + num_words * 2 <= end_addr: word_offset = (off - addr) / 2 # in words # calc offset addr = 0 for i in xrange(num_words): addr = addr * 0x10000 + word[word_offset+i] reloc_type_name = h['type_name'].replace("HUNK_","").lower() return (word_offset, num_words, hunk_num, addr, reloc_type_name) return None map_ext_ref_to_num_words = { Hunk.EXT_ABSREF32 : 2, Hunk.EXT_RELREF16: 1, Hunk.EXT_DEXT16: 1 } # find_ext_ref # return # 0 - word offset to word begin (in words) # 1 - size of reloc (in words) # 2 - name of external symbol # 3 - type name of ext ref def find_ext_ref(self, hunk, addr, word): end_addr = addr + len(word) * 2 for h in hunk[1:]: if h['type'] == Hunk.HUNK_EXT: for ext in h['ext_ref']: refs = ext['refs'] valid = self.map_ext_ref_to_num_words.has_key(ext['type']) if valid: num_words = self.map_ext_ref_to_num_words[ext['type']] for ref in refs: if ref >= addr and ref < end_addr: word_offset = (ref - addr) / 2 type_name = ext['type_name'].replace("EXT_","").lower() return (word_offset, num_words, ext['name'], type_name) return None # search the HUNK_EXT for a defintion def find_ext_def(self, hunk, addr): for h in hunk[1:]: if h['type'] == Hunk.HUNK_EXT: for ext in h['ext_def']: if addr == ext['def']: return ext['name'] return None # search the index of a lib for a definition def find_index_def(self, hunk, addr): main = hunk[0] if main.has_key('index_hunk'): info = main['index_hunk'] if info.has_key('defs'): for d in info['defs']: if d['value'] == addr: return d['name'] return None def find_symbol_or_def(self, hunk, addr, always): symbol = self.find_symbol(hunk, addr, False) if symbol == None: symbol = self.find_ext_def(hunk, addr) if symbol == None: symbol = self.find_index_def(hunk, addr) if symbol == None and always: return "%08x" % addr return symbol # ----- show disassembly ----- def show_disassembly(self, hunk, seg_list, start): main = hunk[0] lines = self.disasm.disassemble(main['data'],start) # show line by line for l in lines: addr = l[0] word = l[1] code = l[2] # try to find a symbol for this addr symbol = self.find_symbol_or_def(hunk, addr, False) # create line info info = [] # find source line info line = self.find_src_line(hunk,addr) if line != None: (src_file, src_line) = line info.append( "src: %s:%d" % (src_file,src_line)) # find an extref ext_ref = self.find_ext_ref(hunk,addr,word) if ext_ref != None: ref_symbol = ext_ref[2] ref_type = ext_ref[3] info.append( "%s: %s" % (ref_type, ref_symbol) ) # find a relocation reloc = self.find_reloc(hunk,addr,word) if reloc != None: hunk_num = reloc[2] offset = reloc[3] reloc_type_name = reloc[4] # a self reference reloc_symbol = self.find_symbol_or_def(seg_list[hunk_num],offset,True) if hunk_num == main['hunk_no']: src = "self" else: src = "#%03d %s" % (hunk_num, seg_list[hunk_num][0]['type_name']) info.append( "%s: %s: %s" % (reloc_type_name, src, reloc_symbol) ) # build comment from all infos if len(info) > 0: comment = "; " + ", ".join(info) else: comment = "" # create final line if symbol != None: print "\t\t\t\t%s:" % symbol print "%08x\t%-20s\t%-30s %s" % (addr," ".join(map(lambda x: "%04x" %x, word)),code,comment)