class ROMDisassembler(object): def __init__(self, image): self.memory = ReadWriteMemory(StringIO(image)) self.getByte = self.memory.createGetter(1, self.memory.BIG_ENDIAN) self.getWord = self.memory.createGetter(2, self.memory.BIG_ENDIAN)
class Disassembler(object): def __init__(self, opcodes, imageFileName, symbols, indirectAddresses, directAddresses = ()): self.opcodes = opcodes self.memory = ReadWriteMemory(file(imageFileName, "rb")) self.memoryExplorer = MemoryExplorer(size = len(self.memory), offset = 0x0000) self.getByte = self.memory.createGetter(1, self.memory.BIG_ENDIAN) self.getWord = self.memory.createGetter(2, self.memory.BIG_ENDIAN) self.symbols = symbols Operation.symbols = self.symbols self.pc = 0x0000 self.callTargets = set(tuple([self.getWord(e) for e in indirectAddresses])).union(set(directAddresses)) self.jumpTargets = set() self.processed = set() #print "Call-Targets: ", [hex(x) for x in self.callTargets] #print sorted([hex(x) for x in self.jumpTargets]) def disassemble(self): lines = set() while self.callTargets: target = self.callTargets.pop() result = self.disassembleTillReturn(target) #lines.extend(result) lines = lines.union(result) #return sorted(set(lines), key = lambda o: o.address) return dict((e.address, e) for e in lines) def disassembleTillReturn(self, address): lines = set() origAddress = address if address == 0xaf4: print "" while True: try: line = self.disassembleLine(address) except IndexError as e: print "Index-Error while disassembling line: %s" % e break except IllegalOpcode as e: print "Illegal Opcode while disassembling line: %s" % e break address += line.size #if not self.memoryExplorer.isExplored(origAddress): # and line not in lines: if origAddress not in self.processed: lines.add(line) #lines.append(line) if line.opcode in RETURNS: break self.processed.add(origAddress) while self.jumpTargets: target = self.jumpTargets.pop() if not self.memoryExplorer.isExplored(target): lines = lines.union(self.disassembleTillReturn(target))#lines.extend(self.disassembleTillReturn(target)) return lines def disassembleLine(self, address): op = self.getByte(address) opcode = self.opcodes[op] opcodeName = opcode.name addressingMode = opcode.addressingMode opcodeSize = opcode.size operandData = self.getWord(address + 1) if opcodeSize == 3 else self.getByte(address + 1) if opcodeSize == 2 else None operand = "" if op in ILLEGAL_OPCODES: raise IllegalOpcode("0x%02x [Address: 0x%04x]" % (op, address, )) else: if address in Operation.symbols: #print "0x%04x ==> %s" % (address, Operation.symbols[address]) label = Operation.symbols[address] else: label = '' operation = Operation(address, opcodeSize, label, op, opcodeName, operand, operandData, addressingMode, '') #print "$%04x %02x %s" % (address, op, operation.formatOperandData()), #print opcodeName, displayString, destination = operation.processes() #print displayString self.memoryExplorer.setExplored(address, opcodeSize) newAddress = address + opcodeSize ## ## Code above is almost identical with simulator. ## ## START SPECIAL. ## END SPECIAL. ## ## Code below is almost identical with simulator. ## if op in JUMPS: if destination and not self.memoryExplorer.isExplored(destination): # in self.processed: self.jumpTargets.add(destination) elif op in CALLS: if destination and not self.memoryExplorer.isExplored(destination): #destination in self.processed: if destination < len(self.memory): ### CHECK!!! self.callTargets.add(destination) else: print "Uups!?" return operation
class Disassembler(object): def __init__(self, opcodes, imageFileName, symbols, indirectAddresses, directAddresses=()): self.opcodes = opcodes self.memory = ReadWriteMemory(file(imageFileName, "rb")) self.memoryExplorer = MemoryExplorer(size=len(self.memory), offset=0x0000) self.getByte = self.memory.createGetter(1, self.memory.BIG_ENDIAN) self.getWord = self.memory.createGetter(2, self.memory.BIG_ENDIAN) self.symbols = symbols Operation.symbols = self.symbols self.pc = 0x0000 self.callTargets = set( tuple([self.getWord(e) for e in indirectAddresses])).union(set(directAddresses)) self.jumpTargets = set() self.processed = set() #print "Call-Targets: ", [hex(x) for x in self.callTargets] #print sorted([hex(x) for x in self.jumpTargets]) def disassemble(self): lines = set() while self.callTargets: target = self.callTargets.pop() result = self.disassembleTillReturn(target) #lines.extend(result) lines = lines.union(result) #return sorted(set(lines), key = lambda o: o.address) return dict((e.address, e) for e in lines) def disassembleTillReturn(self, address): lines = set() origAddress = address if address == 0xaf4: print "" while True: try: line = self.disassembleLine(address) except IndexError as e: print "Index-Error while disassembling line: {0!s}".format(e) break except IllegalOpcode as e: print "Illegal Opcode while disassembling line: {0!s}".format( e) break address += line.size #if not self.memoryExplorer.isExplored(origAddress): # and line not in lines: if origAddress not in self.processed: lines.add(line) #lines.append(line) if line.opcode in RETURNS: break self.processed.add(origAddress) while self.jumpTargets: target = self.jumpTargets.pop() if not self.memoryExplorer.isExplored(target): lines = lines.union(self.disassembleTillReturn( target)) #lines.extend(self.disassembleTillReturn(target)) return lines def disassembleLine(self, address): op = self.getByte(address) opcode = self.opcodes[op] opcodeName = opcode.name addressingMode = opcode.addressingMode opcodeSize = opcode.size operandData = self.getWord(address + 1) if opcodeSize == 3 else self.getByte( address + 1) if opcodeSize == 2 else None operand = "" if op in ILLEGAL_OPCODES: raise IllegalOpcode("0x{0:02x} [Address: 0x{1:04x}]".format( op, address)) else: if address in Operation.symbols: #print "0x%04x ==> %s" % (address, Operation.symbols[address]) label = Operation.symbols[address] else: label = '' operation = Operation(address, opcodeSize, label, op, opcodeName, operand, operandData, addressingMode, '') #print "$%04x %02x %s" % (address, op, operation.formatOperandData()), #print opcodeName, displayString, destination = operation.processes() #print displayString self.memoryExplorer.setExplored(address, opcodeSize) newAddress = address + opcodeSize ## ## Code above is almost identical with simulator. ## ## START SPECIAL. ## END SPECIAL. ## ## Code below is almost identical with simulator. ## if op in JUMPS: if destination and not self.memoryExplorer.isExplored( destination): # in self.processed: self.jumpTargets.add(destination) elif op in CALLS: if destination and not self.memoryExplorer.isExplored( destination): #destination in self.processed: if destination < len(self.memory): ### CHECK!!! self.callTargets.add(destination) else: print "Uups!?" return operation