def get_instruction_info(self, data, addr): (instrTxt, instrLen) = skwrapper.disasm(data, addr) if instrLen == 0: return None result = InstructionInfo() result.length = instrLen return result
def get_instruction_info(self, data, addr): (instrTxt, instrLen) = skwrapper.disasm(data, addr) if instrLen == 0: return None result = InstructionInfo() result.length = instrLen rccs = r'(?:C|NC|Z|NZ|M|P|PE|PO)' regexes = [ \ r'^(?:JP|JR) '+rccs+r',\$(.*)$', # 0: conditional jump eg: JP PE,#DEAD r'^(?:JP|JR) \$(.*)$', # 1: unconditional jump eg: JP #DEAD r'^(?:JP|JR) \((?:HL|IX|IY)\)$', # 2: unconditional indirect eg: JP (IX) r'^DJNZ \$(.*)$', # 3: dec, jump if not zero eg: DJNZ #DEAD r'^CALL '+rccs+r',\$(.*)$', # 4: conditional call eg: CALL PE,#DEAD r'^CALL \$(.*)$', # 5: unconditional call eg: CALL #DEAD r'^RET '+rccs+'$', # 6: conditional return r'^(?:RET|RETN|RETI)$', # 7: return, return (nmi), return (interrupt) ] m = None for (i,regex) in enumerate(regexes): m = re.match(regex, instrTxt) if not m: continue if i==0 or i==3: dest = int(m.group(1), 16) result.add_branch(BranchType.TrueBranch, dest) result.add_branch(BranchType.FalseBranch, addr + instrLen) pass elif i==1: dest = int(m.group(1), 16) result.add_branch(BranchType.UnconditionalBranch, dest) pass elif i==2: result.add_branch(BranchType.IndirectBranch) pass elif i==4 or i==5: dest = int(m.group(1), 16) result.add_branch(BranchType.CallDestination, dest) pass elif i==6: pass # conditional returns don't end block elif i==7: result.add_branch(BranchType.FunctionReturn) break return result
def get_instruction_text(self, data, addr): (instrTxt, instrLen) = skwrapper.disasm(data, addr) if instrLen == 0: return None result = [] atoms = [t for t in re.split(r'([, ()\+])', instrTxt) if t] # delimeters kept if in capture group result.append(InstructionTextToken(InstructionTextTokenType.InstructionToken, atoms[0])) if atoms[1:]: result.append(InstructionTextToken(InstructionTextTokenType.TextToken, ' ')) # for atom in atoms[1:]: if not atom or atom == ' ': continue # PROBLEM: cond 'C' conflicts with register C # eg: "RET C" is it "RET <reg>" or "REG <cc>" ? # eg: "CALL C" is it "CALL <reg>" or "CALL C,$0000" ? elif atom == 'C' and atoms[0] in ['CALL','RET']: # flag, condition code result.append(InstructionTextToken(InstructionTextTokenType.TextToken, atom)) elif atom in self.reg16_strs or atom in self.reg8_strs: result.append(InstructionTextToken(InstructionTextTokenType.RegisterToken, atom)) elif atom in self.cond_strs: result.append(InstructionTextToken(InstructionTextTokenType.TextToken, atom)) elif atom[0] == '#': result.append(InstructionTextToken(InstructionTextTokenType.IntegerToken, atom, int(atom[1:],16))) elif atom[0] == '$': if len(atom)==5: result.append(InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, atom, int(atom[1:],16))) else: result.append(InstructionTextToken(InstructionTextTokenType.IntegerToken, atom, int(atom[1:],16))) elif atom.isdigit(): result.append(InstructionTextToken(InstructionTextTokenType.IntegerToken, atom, int(atom))) elif atom == '(': result.append(InstructionTextToken(InstructionTextTokenType.BeginMemoryOperandToken, atom)) elif atom == ')': result.append(InstructionTextToken(InstructionTextTokenType.EndMemoryOperandToken, atom)) elif atom == '+': result.append(InstructionTextToken(InstructionTextTokenType.TextToken, atom)) elif atom == ',': result.append(InstructionTextToken(InstructionTextTokenType.OperandSeparatorToken, atom)) else: raise Exception('unfamiliar token: %s from instruction %s' % (tok, instrTxt)) return result, instrLen
def get_instruction_text(self, data, addr): (instrTxt, instrLen) = skwrapper.disasm(data, addr) tokens = [InstructionTextToken(InstructionTextTokenType.TextToken, instrTxt)] return tokens, instrLen