def main(): for segstart, segend, segname in enum_segments(): if segname not in ('.text', '.data'): continue for src, dst in find_pointers(segstart, segend): if is_code(src): # ignore instructions like: # # call ds:__vbaGenerateBoundsError #print('code pointer: 0x%x -> 0x%x' % (src, dst)) continue # TODO: fix this: just look at the few previous bytes and ensure they are ASCII/Unicode if is_in_string(src): # for example, the following contains 0x444974 (a common valid offset): # # text:004245B0 aRequestid db 'requestID', # # enable or disable this behavior as you wish print('string pointer: 0x%x -> 0x%x' % (src, dst)) pass #continue print('pointer from 0x%x to 0x%x' % (src, dst)) if is_unknown(dst): print('destination unknown, making byte: 0x%x' % (dst)) idc.MakeByte(dst) elif is_head(dst): # things are good pass else: # need to undefine head, and make byte head_va = get_head(dst) print('destination overlaps with head: 0x%x' % (head_va)) idc.MakeUnkn(head_va, dst - head_va) idc.MakeByte(head_va) idc.MakeByte(dst) idc.MakeUnkn(src, 4) idc.MakeDword(src) # this doesn't seem to always work :-( # ref: https://reverseengineering.stackexchange.com/questions/17798/how-can-i-mark-a-global-variable-as-an-offset-using-idapython #idc.OpOffset(src, 0) ida_offset.op_offset(src, 0, idc.REF_OFF32)
def make_array(ea, size): if ea != idc.BADADDR and ea != 0: flags = idc.GetFlags(ea) if not idc.isByte(flags) or idc.ItemSize(ea) != 1: idc.MakeUnknown(ea, 1, idc.DOUNK_SIMPLE) idc.MakeByte(ea) idc.MakeArray(ea, size)
def make_array(ea, size): if ea != idc.BADADDR and ea != 0: flags = idc.get_full_flags(ea) if not idc.isByte(flags) or idc.get_item_size(ea) != 1: idc.del_items(ea, idc.DOUNK_SIMPLE, 1) idc.MakeByte(ea) idc.MakeArray(ea, size)
def main(): for segstart, segend, segname in enum_segments(): if segname not in ('.text', '.data'): continue for src, dst in find_pointers(segstart, segend): if is_code(src): # ignore instructions like: # # call ds:__vbaGenerateBoundsError #print('code pointer: 0x%x -> 0x%x' % (src, dst)) continue if is_in_string(src): # for example, the following contains 0x444974 (a common valid offset): # # text:004245B0 aRequestid db 'requestID', # # enable or disable this behavior as you wish print('string pointer: 0x%x -> 0x%x' % (src, dst)) pass #continue print('pointer from 0x%x to 0x%x' % (src, dst)) if is_unknown(dst): print('destination unknown, making byte: 0x%x' % (dst)) idc.MakeByte(dst) elif is_head(dst): # things are good pass else: # need to undefine head, and make byte head_va = get_head(dst) print('destination overlaps with head: 0x%x' % (head_va)) idc.MakeUnkn(head_va, dst - head_va) idc.MakeByte(head_va) idc.MakeByte(dst) idc.MakeUnkn(src, 4) idc.MakeDword(src) # this doesn't seem to always work :-( idc.OpOffset(src, 0)
def MakeReg(name, offset, size, count=0): idc.MakeNameEx(offset, name, idc.SN_NOCHECK | idc.SN_NOWARN) if (size == 1): idc.MakeByte(offset) elif size == 2: idc.MakeWord(offset) elif size == 4: idc.MakeDword(offset) else: raise NotImplementedError("Register size invalid! Name: " + name) if (count != 0): idc.make_array(offset, count)
def rngmkd(start_ea, end_ea): """ Turns the data in the range to words. If not aligned with words, turns into bytes instead :param start_ea: start of the range :param end_ea: end of the range """ ea = start_ea while ea % 4 != 0: print('%07X: -> byte' % ea) idc.MakeByte(ea) ea += 1 while ea < end_ea: print('%07X: -> word' % ea) idc.MakeDword(ea) ea += 4
def MakeN(addr, size): ''' Make a integer with the given size at the given address. Args: addr (int): effective address. size (int): the size of the integer, one of 1, 2, 4, or 8. ''' if size == 1: idc.MakeByte(addr) elif size == 2: idc.MakeWord(addr) elif size == 4: idc.MakeDword(addr) elif size == 8: idc.MakeQword(addr)
def changeASCII(start_ea, ): """ finds all ascii named data and changes it to bytes and removes its name """ found = False for ea, name in idautils.Names(): d = Data.Data(ea) if idc.isASCII(d._getFlags()): found = True print("%07X: Make ASCII -> Byte" % ea) idc.MakeByte(ea) idc.MakeName(ea, '') if found: print("changed all ASCII data to byte data!") else: print("no ASCII data was found!")
def MakeAndGetByte(ea, comment=None): """ Creates a byte at the specified address and returns the byte value. :param ea: address to make byte at :param comment: optional comment to place at the specified address :return: the value of the byte at the specified address """ # Make the byte value. idc.MakeByte(ea) # Check if the comment is valid and if so place it at the address. if comment is not None: idc.MakeComm(ea, comment) # Get the byte value. return idc.Byte(ea)
def removeText(start_ea, end_ea): """ removes all ASCII text within range :param start_ea: start of the range to remove :param end_ea: end of the range to remove """ found = False ea = start_ea while ea < end_ea: d = Data.Data(ea) if idc.isASCII(d.getFlags()): found = True print("%07X: Make text -> Byte" % ea) idc.MakeByte(ea) ea += d.getSize() if found: print("changed all ASCII data to byte data!") else: print("no ASCII data was found!")
def changeASCII(start_ea, end_ea): """ finds all ascii data which is not user named and changes it to bytes and removes its name """ found = False ea = start_ea while ea < end_ea: d = Data.Data(ea) if idc.isASCII(d.getFlags()): found = True print("%07X: Make ASCII -> Byte" % ea) idc.MakeByte(ea) idc.MakeName(ea, 'ASCII_%07X' % ea) ea += d.getSize() if found: print("changed all ASCII data to byte data!") else: print("no ASCII data was found!")
def main(): print("[*] loading crypto constants") for const in non_sparse_consts: const["byte_array"] = convert_to_byte_array(const) for start in idautils.Segments(): print("[*] searching for crypto constants in %s" % idc.SegName(start)) ea = start while ea < idc.SegEnd(start): bbbb = list( struct.unpack("BBBB", idc.GetManyBytes(ea, 4) or "AAAA")) for const in non_sparse_consts: if bbbb != const["byte_array"][:4]: continue if map( lambda x: ord(x), idc.GetManyBytes(ea, len(const["byte_array"])) or list()) == const["byte_array"]: print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"])) idc.MakeName(ea, const["name"]) if const["size"] == "B": idc.MakeByte(ea) elif const["size"] == "L": idc.MakeDword(ea) elif const["size"] == "Q": idc.MakeQword(ea) MakeArray(ea, len(const["array"])) ea += len(const["byte_array"]) - 4 break ea += 4 #print "ea: 0x%x " % ea ea = start if idc.GetSegmentAttr(ea, SEGATTR_TYPE) == 2: while ea < idc.SegEnd(start): d = idc.Dword(ea) for const in sparse_consts: if d != const["array"][0]: continue tmp = ea + 4 for val in const["array"][1:]: for i in range(8): if idc.Dword(tmp + i) == val: tmp = tmp + i + 4 break else: break else: print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"])) cmt = idc.GetCommentEx(idc.prev_head(ea), 0) if cmt: idc.CommentEx(idc.prev_head(ea), cmt + ' ' + const["name"], 0) else: idc.CommentEx(idc.prev_head(ea), const["name"], 0) ea = tmp break ea += 1 print("[*] finished")
if (xr2.type == 19) and (xr2.to == next_next): db = head + idaapi.get_item_size(head) if idc.Byte(head) == 0x0F: idaapi.patch_byte(head, 0x90) idaapi.patch_byte(head + 1, 0xE9) else: idaapi.patch_byte(head, 0xEB) idc.MakeUnknown(db, xr.to - db + 0x10, idaapi.DOUNK_SIMPLE) idc.MakeCode(xr.to) i = db while i < xr.to: if (i + 4) < xr.to: idc.MakeDword(i) i += 4 else: idc.MakeByte(i) i += 1 idaapi.analyze_area(head - 0x40, head + 0x40) idaapi.analyze_area(xr.to - 0x40, xr.to + 0x40) for head in idautils.Heads(): if idc.Byte(head) == 0xE8: for xr in idautils.XrefsFrom(head, 0): # Find direct call targets if not (xr.type == 21): idc.MakeFunction(xr.to)