def load_symbols(self, file_data, is_big_endian=True): symbol_list = [] if is_big_endian: unpack_format = '>I' else: unpack_format = '<I' symbol_count = struct.unpack(unpack_format, file_data[4:8])[0] print("symbol_count: %s" % symbol_count) symbol_offset = 8 string_table_offset = 8 + 8 * symbol_count print("string_table_offset: %s" % string_table_offset) # get symbols for i in range(symbol_count): offset = i * 8 symbol_data = file_data[symbol_offset + offset:symbol_offset + offset + 8] flag = ord(symbol_data[0]) string_offset = struct.unpack(unpack_format, '\x00' + symbol_data[1:4])[0] string_offset += string_table_offset print("string_offset: %s" % string_offset) symbol_name = "" while True: if file_data[string_offset] != '\x00': symbol_name += file_data[string_offset] string_offset += 1 else: break print("symbol_name: %s" % symbol_name) symbol_address = struct.unpack(unpack_format, symbol_data[-4:])[0] symbol_list.append([flag, symbol_name, symbol_address]) # Find TP-Link device loading address with symbols if "wrs_kernel_text_start" in symbol_name: load_address = symbol_address current_image_base = idaapi.get_imagebase() shift_address = load_address - current_image_base while shift_address >= 0x70000000: idaapi.rebase_program(0x70000000, 0x0008) shift_address -= 0x70000000 idaapi.rebase_program(shift_address, 0x0008) # load symbols for symbol_data in symbol_list: flag, symbol_name, symbol_address = symbol_data idc.MakeName(symbol_address, symbol_name) if flag == 0x54: if symbol_name: print("Start fix Function %s at %s" % (symbol_name, hex(symbol_address))) idc.MakeCode(symbol_address) # might not need idc.MakeFunction(symbol_address, idc.BADADDR)
def fix_vxworks_idb(load_address, vx_version, symbol_table_start, symbol_table_end): current_image_base = idaapi.get_imagebase() symbol_interval = 16 if vx_version == 6: symbol_interval = 20 symbol_table_start += load_address symbol_table_end += load_address ea = symbol_table_start shift_address = load_address - current_image_base while shift_address >= 0x70000000: idaapi.rebase_program(0x70000000, 0x0008) shift_address -= 0x70000000 idaapi.rebase_program(shift_address, 0x0008) while ea < symbol_table_end: # for VxWorks 6 unknown symbol format if idc.Byte(ea + symbol_table_end - 2) == 3: ea += symbol_interval continue offset = 4 if idaapi.IDA_SDK_VERSION >= 700: idc.create_strlit(idc.Dword(ea + offset), idc.BADADDR) else: idc.MakeStr(idc.Dword(ea + offset), idc.BADADDR) sName = idc.GetString(idc.Dword(ea + offset), -1, idc.ASCSTR_C) print("Found %s in symbol table" % sName) if sName: sName_dst = idc.Dword(ea + offset + 4) if vx_version == 6: sName_type = idc.Dword(ea + offset + 12) else: sName_type = idc.Dword(ea + offset + 8) idc.MakeName(sName_dst, sName) if sName_type in need_create_function: # flags = idc.GetFlags(ea) print("Start fix Function %s at %s" % (sName, hex(sName_dst))) idc.MakeCode(sName_dst) # might not need idc.MakeFunction(sName_dst, idc.BADADDR) ea += symbol_interval print("Fix function by symbol table finish.") print( "Start IDA auto analysis, depending on the size of the firmware this might take a few minutes." ) idaapi.autoWait()
def rsp(self, buffer, **kargs): idc.Message("Handling a rebase command from the rsp!\n") result = True #try: addr = buffer.read_string() #idc.Message("In rebase call: " +str(addr)) rebase_to_addr = IdabridgeUtils.convert_str_to_numval(addr) current_ea = idc.ScreenEA() c_base_addr = idc.FirstSeg() r_base_diff = rebase_to_addr - c_base_addr idc.Message("instanceof(rebase_to_addr, str) == %s rebase_to_addr: %s Got: %s)"%(isinstance(rebase_to_addr, str), rebase_to_addr, addr)) idaapi.rebase_program(r_base_diff, idc.MSF_FIXONCE) idc.AnalyseArea(idc.MinEA(),idc.MaxEA()) new_ea = rebase_to_addr + ( current_ea - c_base_addr) idc.Jump(new_ea) result = True #except: # pass return self.return_data(result)
def process(fd, bitness): enable_auto(False) base_addr = 0x0 if bitness == 1: idaapi.set_processor_type('ARM:ARMv7-A', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_PC_FLAT elif bitness == 2: idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT fd.seek(0, idaapi.SEEK_END) size = fd.tell() segm = idaapi.segment_t() segm.bitness = bitness segm.start_ea = 0 segm.end_ea = size if base_addr != 0: print("[*] Rebasing to address 0x%x" % (base_addr)) idaapi.rebase_program(base_addr, MSF_NOFIX) idaapi.autoWait() idaapi.add_segm_ex(segm, "SecureROM", "CODE", idaapi.ADDSEG_OR_DIE) fd.seek(0) fd.file2base(0, 0, size, False) print("[*] Pass One") print("[*] Defining functions") #locate_functions(segm) print("[*] Defining early initialation instructions") build_jump_table(segm) print("[*] Attempting to force string definitons") global string_start, string_end string_start, string_end = process_strings(segm) print("[*] Pass Two") print("[*] Hunting for and defining symbols") symbolicate(segm)
from sets import Set import json import idaapi import idc print('My Script is now running...') print('Waiting for idapro...') idaapi.autoWait() print('start persisting...') idaapi.rebase_program(-1*idaapi.get_imagebase(), 0) ss = idaapi.get_input_file_path() pn = os.path.splitext(ss)[0] callees = dict() funcmap = dict() data = dict() data['name'] = pn for seg_ea in Segments(): for function_ea in Functions(SegStart(seg_ea), SegEnd(seg_ea)): #fill call graph # For each of the incoming references for ref_ea in CodeRefsTo(function_ea, 0): # Get the name of the referring function caller_name = GetFunctionName(ref_ea) # Add the current function to the list of functions called by the referring function callees[caller_name] = callees.get(caller_name, Set()) callees[caller_name].add(function_ea) data['functions'] = list()
def load_file(fd, neflags, format): global prologues global br_flag size = 0 base_addr = 0 ea = 0 nfunc = 0 idaapi.set_processor_type("arm", ida_idp.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT if (neflags & idaapi.NEF_RELOAD) != 0: return 1 fd.seek(0, idaapi.SEEK_END) size = fd.tell() segm = idaapi.segment_t() segm.bitness = 2 # 64-bit segm.start_ea = 0 segm.end_ea = size if br_flag == false: idaapi.add_segm_ex(segm, "iBoot", "CODE", idaapi.ADDSEG_OR_DIE) else: idaapi.add_segm_ex(segm, "SecureROM", "CODE", idaapi.ADDSEG_OR_DIE) fd.seek(0) fd.file2base(0, 0, size, false) idaapi.add_entry(0, 0, "start", 1) ida_funcs.add_func(ea) print("[+] Marked as code") # heuristic while (true): mnemonic = idc.print_insn_mnem(ea) if "LDR" in mnemonic: base_str = idc.print_operand(ea, 1) base_addr = int(base_str.split("=")[1], 16) break ea += 4 print("[+] Rebasing to address 0x%x" % (base_addr)) idaapi.rebase_program(base_addr, idc.MSF_NOFIX) segment_start = base_addr segment_end = idc.get_segm_attr(segment_start, idc.SEGATTR_END) ea = segment_start print("[+] Searching and defining functions") for prologue in prologues: while ea != ida_idaapi.BADADDR: ea = ida_search.find_binary(ea, segment_end, prologue, 16, ida_search.SEARCH_DOWN) if ea != ida_idaapi.BADADDR: if len(prologue) < 8: ea = ea - 2 if (ea % 4) == 0 and ida_bytes.get_full_flags(ea) < 0x200: # print("[+] Defining a function at 0x%x" % (ea)) ida_funcs.add_func(ea) nfunc = nfunc + 1 ea = ea + 4 idc.plan_and_wait(segment_start, segment_end) print("[+] Identified %d new functions" % (nfunc)) print("[+] Looking for interesting functions") find_interesting(segment_start, segment_end) return 1
def load_file(fd, neflags, format): size = 0 base_addr = 0 ea = 0 idaapi.set_processor_type("arm", idaapi.SETPROC_ALL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT if (neflags & idaapi.NEF_RELOAD) != 0: return 1 fd.seek(0, idaapi.SEEK_END) size = fd.tell() segm = idaapi.segment_t() segm.bitness = 2 # 64-bit segm.start_ea = 0 segm.end_ea = size idaapi.add_segm_ex(segm, "iBoot", "CODE", idaapi.ADDSEG_OR_DIE) fd.seek(0) fd.file2base(0, 0, size, false) idaapi.add_entry(0, 0, "start", 1) idc.MakeFunction(ea) print("[+] Marked as code") # heuristic while (true): mnemonic = idc.GetMnem(ea) if "LDR" in mnemonic: base_str = idc.GetOpnd(ea, 1) base_addr = int(base_str.split("=")[1], 16) break ea += 4 print("[+] Rebasing to address 0x%x" % (base_addr)) idaapi.rebase_program(base_addr, idc.MSF_NOFIX) idaapi.autoWait() segment_start = base_addr segment_end = idc.GetSegmentAttr(segment_start, idc.SEGATTR_END) ea = segment_start print("[+] Searching and defining functions") while ea != idc.BADADDR: ea = idc.FindBinary(ea, idc.SEARCH_DOWN, "BF A9", 16) if ea != idc.BADADDR: ea = ea - 2 if (ea % 4) == 0 and idc.GetFlags(ea) < 0x200: # print("[+] Defining a function at 0x%x" % (ea)) idc.MakeFunction(ea) ea = ea + 4 idc.AnalyzeArea(segment_start, segment_end) idaapi.autoWait() return 1 # EOF
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # * See the License for the specific language governing permissions and # * limitations under the License. # *******************************************************************************/ from sets import Set import json import idaapi import idc print('My Script is now running...') print('Waiting for idapro...') idaapi.autoWait() print('start persisting...') idaapi.rebase_program(-1 * idaapi.get_imagebase(), 0) ss = idaapi.get_input_file_path() pn = os.path.splitext(ss)[0] callees = dict() funcmap = dict() data = dict() data['name'] = pn for seg_ea in Segments(): for function_ea in Functions(SegStart(seg_ea), SegEnd(seg_ea)): #fill call graph # For each of the incoming references for ref_ea in CodeRefsTo(function_ea, 0): # Get the name of the referring function caller_name = GetFunctionName(ref_ea)
def load_file(fd, flags, format): ea = 0 size = 0 fd.seek(0x200) search = fd.read(0x10) print("[sephelper]: starting...") if segbit == 1: print("[sephelper]: detected a 32bit SEPROM !") idaapi.set_processor_type("arm:armv7-m", idaapi.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_PC_FLAT else: print("[sephelper]: detected a 64bit SEPROM !") idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT if (flags & idaapi.NEF_RELOAD) != 0: return 1 fd.seek(0x0, idaapi.SEEK_END) size = fd.tell() segm = idaapi.segment_t() segm.bitness = segbit segm.start_ea = 0x0 segm.end_ea = size idaapi.add_segm_ex(segm, "SEPROM", "CODE", idaapi.ADDSEG_OR_DIE) fd.seek(0x0) fd.file2base(0x0, 0x0, size, False) print("[sephelper]: adding entry point...") idaapi.add_entry(0x0, 0x0, "_start", 1) ida_funcs.add_func(ea) print("[sephelper]: base_addr = 0x%x" % base_addr) idaapi.rebase_program(base_addr, idc.MSF_NOFIX) print("[sephelper]: analyzing...") ea = base_addr segment_end = idc.get_segm_attr(base_addr, idc.SEGATTR_END) hexcode = ["BF A9", "BD A9"] # there is not PAC on SEPROM if segbit == 1: hexcode = ["03 AF", "02 AF", "01 AF"] for prologue in hexcode: while ea != idc.BADADDR: ea = ida_search.find_binary(ea, segment_end, prologue, 0x10, ida_search.SEARCH_DOWN) if ea != idc.BADADDR: ea = ea - 0x2 if (ea % 0x4) == 0 and ida_bytes.get_full_flags(ea) < 0x200: # print("[sephelper]: function added = 0x%x" % ea) ida_funcs.add_func(ea) ea = ea + 0x4 idc.plan_and_wait(base_addr, segment_end) print('[sephelper]: finding some functions...') find_function(segm.start_ea, segment_end) print('[sephelper]: done !') return 1