def find_string_at(ea, min=4): """ check if ASCII string exists at a given virtual address """ found = idaapi.get_strlit_contents(ea, -1, idaapi.STRTYPE_C) if found and len(found) > min: try: found = found.decode("ascii") # hacky check for IDA bug; get_strlit_contents also reads Unicode as # myy__uunniiccoodde when searching in ASCII mode so we check for that here # and return the fixed up value if len(found) >= 3 and found[1::2] == found[2::2]: found = found[0] + found[1::2] return found except UnicodeDecodeError: pass return ""
def znullptr(address, end, search, struct): magic = idaapi.find_binary(address, end, search, 0x10, idc.SEARCH_DOWN) pattern = '%02X %02X %02X %02X FF FF FF FF' % (magic & 0xFF, ((magic >> 0x8) & 0xFF), ((magic >> 0x10) & 0xFF), ((magic >> 0x18) & 0xFF)) sysvec = idaapi.find_binary(address, cvar.inf.maxEA, pattern, 0x10, idc.SEARCH_UP) - 0x60 idaapi.set_name(sysvec, 'sysentvec', SN_NOCHECK | SN_NOWARN | SN_FORCE) sysent = idaapi.get_qword(sysvec + 0x8) idaapi.set_name(sysent, 'sv_table', SN_NOCHECK | SN_NOWARN | SN_FORCE) sysnames = idaapi.get_qword(sysvec + 0xD0) idaapi.set_name(sysnames, 'sv_syscallnames', SN_NOCHECK | SN_NOWARN | SN_FORCE) # Get the list of syscalls offset = idaapi.find_binary(address, cvar.inf.maxEA, '73 79 73 63 61 6C 6C 00 65 78 69 74 00', 0x10, SEARCH_DOWN) numsyscalls = idaapi.get_qword(sysvec) for entry in xrange(numsyscalls): initial = sysnames + (entry * 0x8) idc.create_data(initial, FF_QWORD, 0x8, BADNODE) offset = idaapi.get_qword(initial) length = idaapi.get_max_strlit_length(offset, STRTYPE_C) name = idaapi.get_strlit_contents(offset, length, STRTYPE_C) sysentoffset = sysent + 0x8 + (entry * 0x30) idaapi.do_unknown_range(sysentoffset - 0x8, 0x30, 0) idaapi.create_struct(sysentoffset - 0x8, 0x30, struct) idc.set_cmt(sysentoffset - 0x8, '#%i' % entry, False) if '{' in name: continue # Rename the functions function = idaapi.get_qword(sysentoffset) idaapi.set_name(function, name.replace('#', 'sys_'), SN_NOCHECK | SN_NOWARN | SN_FORCE)
def __init__(self, ea): name = ea + get_member_by_name(get_struc(self.tid), "name").soff strlen = u.get_strlen(name) if strlen is None: # not a real vtable return self.size = self.size + strlen mangled = get_strlit_contents(name, strlen, 0) if mangled is None: # not a real function name return print("Mangled: " + mangled) demangled = demangle_name('??_R0' + mangled[1:], 0) if demangled: del_items(ea, self.size, DELIT_DELNAMES) if create_struct(ea, self.size, self.tid): print(" Made td at 0x%x: %s" % (ea, demangled)) self.class_name = demangled return print(" FAIL :(") return
#a binary search based on system call # if sc < 177: if sc < 89: if sc < 45: if sc < 23: if sc < 12: if sc < 6: if sc < 3: if sc == 0: #read pass elif sc == 1: #write pass else: #2, open msg("open(\"%s\", 0x%x, 0x%x)\n" % (idaapi.get_strlit_contents( cpu.rdi, -1, STRTYPE_C), cpu.rsi, cpu.rdx)) cpu.rax = 3 elif sc > 3: if sc == 4: #stat pass else: #5, fstat idaapi.patch_dword(cpu.rsi, 0x4000) idaapi.patch_qword(cpu.rsi + 0x20, 0x1000) else: #3, close pass elif sc > 6: if sc < 9: pass elif sc > 9: if sc == 10:
cpu.rax = 0 #rather than building a big dict of handlers, this is #a binary search based on system call # if sc < 177: if sc < 89: if sc < 45: if sc < 23: if sc < 12: if sc < 6: if sc < 3: if sc == 0: #read pass elif sc == 1: #write pass else: #2, open msg("open(\"%s\", 0x%x, 0x%x)\n" % (idaapi.get_strlit_contents(cpu.rdi, -1, STRTYPE_C), cpu.rsi, cpu.rdx)) cpu.rax = 3 elif sc > 3: if sc == 4: #stat pass else: #5, fstat idaapi.patch_dword(cpu.rsi, 0x4000) idaapi.patch_qword(cpu.rsi + 0x20, 0x1000) else: #3, close pass elif sc > 6: if sc < 9: pass elif sc > 9: if sc == 10: pass # 10, mprotect