def add_xrefs(addr, end=idc.BADADDR): """ https://github.com/xyzz/vita-ida-physdump/blob/master/vita_phys_dump.py Searches for MOV / MOVT pair, probably separated by few instructions, and adds xrefs to things that look like addresses """ while addr < end and addr != BADADDR: addr = idc.NextHead(addr) if idc.GetMnem(addr) in ["MOV", "MOVW"]: reg = idc.GetOpnd(addr, 0) if idc.GetOpnd(addr, 1)[0] != "#": continue val = idc.GetOperandValue(addr, 1) found = False next_addr = addr for x in range(16): next_addr = idc.NextHead(next_addr) if idc.GetMnem(next_addr) in ["B", "BX"]: break # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated # if there's a function call and our register is scratch, it will probably get corrupted, bail out if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [ "R0", "R1", "R2", "R3" ]: break # if we see a MOVT, do the match! if idc.GetMnem(next_addr) in ["MOVT", "MOVT.W"] and idc.GetOpnd( next_addr, 0) == reg: if idc.GetOpnd(next_addr, 1)[0] == "#": found = True val += idc.GetOperandValue(next_addr, 1) * (2**16) break # if we see something other than MOVT doing something to the register, bail out if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd( next_addr, 1) == reg: break if val & 0xFFFF0000 == 0: continue if found: # pair of MOV/MOVT try: idc.OpOffEx(addr, 1, idc.REF_LOW16, val, 0, 0) idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0) except: print "Failed xref @ %x next_addr %x val %x" % ( addr, next_addr, val) else: # a single MOV instruction try: idc.OpOff(addr, 1, 0) except: print "Failed xref at addr %x" % (addr)
def add_xrefs(): """ Searches for MOV / MOVT pair, probably separated by few instructions, and adds xrefs to things that look like addresses """ addr = 0 while addr != idc.BADADDR: addr = idc.NextHead(addr) if idc.GetMnem(addr) in ["MOV", "MOVW"]: reg = idc.GetOpnd(addr, 0) if idc.GetOpnd(addr, 1)[0] != "#": continue val = idc.GetOperandValue(addr, 1) found = False next_addr = addr for x in range(16): next_addr = idc.NextHead(next_addr) if idc.GetMnem(next_addr) in ["B", "BX"]: break # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated # if there's a function call and our register is scratch, it will probably get corrupted, bail out if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [ "R0", "R1", "R2", "R3" ]: break # if we see a MOVT, do the match! if idc.GetMnem(next_addr) in ["MOVT", "MOVT.W"] and idc.GetOpnd( next_addr, 0) == reg: if idc.GetOpnd(next_addr, 1)[0] == "#": found = True val += idc.GetOperandValue(next_addr, 1) * (2**16) break # if we see something other than MOVT doing something to the register, bail out if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd( next_addr, 1) == reg: break if val & 0xFFFF0000 == 0: continue if found: # pair of MOV/MOVT idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0) else: # a single MOV instruction idc.OpOff(addr, 1, 0)
def annotate_vector_table(self, vtoffset=0x0000000000): ''' Name the vector table entries according to docs: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIFJFG.html Vector tables can appear in mulitple places in device flash Functions are not renamed because multiple vectors might point to a single function Append the address of the VT entry to the name from self.annotations to keep unique names ''' for annotation_index in range(len(self.annotations)): entry_addr = vtoffset + 4 * annotation_index entry_name = "%s_%08x" % (self.annotations[annotation_index], entry_addr) idc.MakeDword(entry_addr) ida_name.set_name(entry_addr, entry_name, 0) # get the bytes of the vt entry dword = idc.Dword(entry_addr) if dword != 0: # print "ea %08x = 0x%08x" % (ea, dword) idc.MakeCode(dword - 1) idc.MakeFunction(dword - 1) # TODO fix the offsets created here # for thumb, they show to be off by a byte # one of the end args controls stuff about this idc.OpOffEx(entry_addr, 0, idaapi.REF_OFF32, -1, 0, 0) instruction = idc.Word(dword - 1) # functions like this are common if instruction == 0xe7fe: idc.SetFunctionCmt(dword - 1, 'Infinite Loop', 1)
def add_xrefs(): """ Searches for MOV / MOVT pair, probably separated by few instructions, and adds xrefs to addresses """ addr = 0 while addr != idc.BADADDR: addr = idc.NextHead(addr) if idc.GetMnem(addr) in ["MOV", "MOVW"]: reg = idc.GetOpnd(addr, 0) if idc.GetOpnd(addr, 1)[0] != "#": continue val = idc.GetOperandValue(addr, 1) found = False lower16_addr = addr upper16_addr = addr for x in range(16): upper16_addr = idc.NextHead(upper16_addr) if idc.GetMnem(upper16_addr) in ["B", "BX"]: break # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated # if there's a function call and our register is scratch, it will probably get corrupted, bail out if idc.GetMnem(upper16_addr) in ["BL", "BLX"] and reg in ["R0", "R1", "R2", "R3"]: break # if we see a MOVT, do the match! if idc.GetMnem(upper16_addr) in ["MOVT", "MOVT.W"] and idc.GetOpnd(upper16_addr, 0) == reg: if idc.GetOpnd(upper16_addr, 1)[0] == "#": found = True val += idc.GetOperandValue(upper16_addr, 1) << 16 break # if we see something other than MOVT doing something to the register, bail out if idc.GetOpnd(upper16_addr, 0) == reg or idc.GetOpnd(upper16_addr, 1) == reg: break # check if is valid address if idaapi.getseg(val) is not None: if found: # pair of MOV/MOVT idc.OpOffEx(lower16_addr, 1, idc.REF_LOW16, val, 0, 0) idc.OpOffEx(upper16_addr, 1, idc.REF_HIGH16, val, 0, 0) else: # a single MOV instruction idc.OpOff(addr, 1, 0) else: val_string = hex(val) if val != 0: val_string += " (" + str(val) float_repr = struct.unpack("<f", struct.pack("<I", val))[0] if float_repr > 0.00000001: val_string += ", " + str(float_repr) + ")" else: val_string += ")" if found: # pair of MOV/MOVT idc.MakeComm(lower16_addr, "lower16:" + val_string) idc.MakeComm(upper16_addr, "upper16:" + val_string) else: # a single MOV instruction if val != 0: idc.MakeComm(addr, val_string)