def decode_register(self, reg): R = None name = reg if type(reg) == str: for r in self.registers: if reg in r.aliases: R = r break if R is None: raise KeyError("DR: Unknown register: %s"%reg) else: name = "$%d"%name for r in self.registers: if "$%d"%reg in r.aliases: R = r break if not R: raise KeyError("DR: Unknown register: $%d"%reg) return ir.register_operand(name, R)
def DR(self, index, mode=32): """Decode register based on register number and mode""" regdecode = {0: ['ah', 'al', 'ax', 'eax', 'rax'], 1: ['ch', 'cl', 'cx', 'ecx', 'rcx'], 2: ['dh', 'dl', 'dx', 'edx', 'rdx'], 3: ['bh', 'bl', 'bx', 'ebx', 'rbx'], 4: ['sp', 'sp', 'sp', 'esp', 'rsp'], 5: ['bp', 'bp', 'bp', 'ebp', 'rbp'], 6: ['si', 'si', 'si', 'esi', 'rsi'], 7: ['di', 'di', 'di', 'edi', 'rdi'], 8: ['', 'r8b', 'r8w', 'r8d', 'r8'], 9: ['', 'r9b', 'r9w', 'r9d', 'r9'], 10: ['', 'r10b', 'r10w', 'r10d', 'r10'], 11: ['', 'r11b', 'r11w', 'r11d', 'r11'], 12: ['', 'r12b', 'r12w', 'r12d', 'r12'], 13: ['', 'r13b', 'r13w', 'r13d', 'r13'], 14: ['', 'r14b', 'r14w', 'r14d', 'r14'], 15: ['', 'r15b', 'r15w', 'r15d', 'r15'], } #TODO: segmentation registers #TODO in 64-bit esi/edi/ebp/esp gain low byte access w/ REX if type(index) == int: regmodes = {16: 2, 32: 3, 64: 4} regname = regdecode[index][regmodes[mode]] elif type(index) == str: regname = index.lower() else: raise InvalidInstruction("UNKNOWN DR index: %s"%repr(index)) register = None for reg in self.registers: if regname in reg: register = reg break if not register: raise InvalidInstruction("Failed to decode register: %s"%regname) return ir.register_operand(regname, register)
TRACK = {'eax': SYMa, 'ebx': SYMb, 'ecx': SYMc} def dump(): global TRACK for name in TRACK: print name,'=',TRACK[name].get_values(), TRACK[name].get_states() print '---' #dump() #10: eax = 0 SYMa.update([0], 10, 0) #dump() #20: ebx = ecx + 5 new_state = ssa.translate_ops(TRACK, [ir.register_operand('ecx', ECX),'+', ir.constant_operand(5)], 20) SYMb.update([new_state], 20, 0) #dump() ### retroactive update is a funny way of putting it ### but thats what this assignment does since code ### addr 15 < 20. #15: ebx = 4 SYMc.update([4], 15, 0) #dump() #verify everything worked works = True if SYMc.get_values()[0] != 4: works = False print "FAILED, ecx should be 4"