diff --git a/interface_extract.py b/interface_extract.py new file mode 100644 index 0000000..5b62ba0 --- /dev/null +++ b/interface_extract.py @@ -0,0 +1,105 @@ +import os +import json +from datetime import datetime + +from ida_typeinf import * +from idaapi import * +from idautils import * +from idc import * + +def mylog(func_name,msg): + with open("my.log","a+") as f:#报错日志写入 + current_time = datetime.now() + fmttime = current_time.strftime("%Y-%m-%d %H:%M:%S") + f.write(f"[{fmttime}]: {func_name} -> {msg}\n") +def export_func_asm(file_name,func_addr): + try: + with open(file_name,"w+") as f: + func_ea=get_func(func_addr)#获取有效函数地址对象 + func_name=get_func_name(func_addr)#获取函数名称 + f.write(f"Assembly for function {func_name} start:0x{func_ea.start_ea:x} end:0x{func_ea.end_ea:x}\n") + for ea in Heads(func_ea.start_ea,func_ea.end_ea):#遍历 + asm_line=generate_disasm_line(ea,GENDSM_REMOVE_TAGS)#提取汇编,去除标签 + f.write(f"0x{ea:x}: {asm_line}\n") + except Exception as msg: + mylog("export_func_asm",msg) + +def export_func(extractfile): + if(extractfile is None):exit(-1) + func_file=extractfile+"_extract.c" + try: + with open(func_file,"w") as file: + for func_addr in Functions():#迭代器编译所有函数 + func_name=get_func_name(func_addr)#获取函数名称 + if(func_name in BLACK_LIST):continue#黑名单处理 + func_seg=getseg(func_addr)#获取函数段 + if(func_seg.name!=7 or func_seg.perm !=5):continue #去除其他段函数 + #tmp_filename=extractfile+"_"+func_name+".asm" + #export_func_asm(tmp_filename,func_addr) #提取函数汇编 + code=decompile(func_addr) #反编译,提取c + if code : + file.write(f"//Function: {func_name} ->0x{func_addr} {func_seg.name} perm->{func_seg.perm}\n") + file.write(str(code)+"\n\n") #写入文件 + except Exception as msg: + mylog("export_func",msg) + +def export_local_types_for_struct(): + try: + #print(f"Number of local types: {num_types}") + type_list=[] + i=0 + while True: + i+=1 + type_name = get_numbered_type_name(i) # 获取类型名称 + if(type_name is None):return type_list + type_data=get_numbered_type(None,i) #获取类型 + mylog("export_local_types_for_struct",type_name) + if not type_data or type_data[1] is None :continue #[1]判断是否为普通类型,普通类型[1]为None + tinfo = tinfo_t() + # 调用 deserialize序列化 + success = tinfo.deserialize(None, type_data[0], type_data[1],None) + if(success and tinfo.is_struct()): + if( type_name in STRUCT_BACKLIST):continue #struct黑名单处理 + struct_info={ + "name":type_name, + "size":f"0x{tinfo.get_size():x}", + "info":tinfo.__str__(),#属性返回字符串 + } + type_list.append(struct_info) # 结果字典形式返回 + + except Exception as msg: + mylog("export_local_types_for_struct",msg) + +def export_local_types(save_file): + save_file=save_file+"_Estruct.json" + struct_list=export_local_types_for_struct()#返回字典列表 + if(struct_list is None):return + # 将结构体信息转换为 JSON 格式 + json_output = json.dumps(struct_list, indent=4) + #print(json_output) + with open(save_file,"w") as f: + f.write(json_output) +#函数黑名单 +BLACK_LIST={ +"_start","_dl_relocate_static_pie", +"deregister_tm_clones","register_tm_clones", +"__do_global_dtors_aux","frame_dummy", +} +#结构体黑名单 +STRUCT_BACKLIST={ + "Elf64_Sym","Elf64_Rela","Elf64_Dyn","Elf64_Verneed","Elf64_Vernaux" +} +def main(): + save_dir="result" + extractfile="extract.c" + filepath="tmp.txt" + if (os.path.exists(filepath) and os.path.isfile(filepath) ): + with open(filepath,"r") as f: + extractfile=f.read() + extractfile=os.path.join(save_dir,extractfile) + export_func(extractfile) + export_local_types(extractfile) + +if __name__ == "__main__": + main() + idaapi.qexit(0) \ No newline at end of file diff --git a/test.py b/test.py index b06b1d5..90c500b 100644 --- a/test.py +++ b/test.py @@ -9,7 +9,7 @@ BLUE = '\033[94m' RESET = '\033[0m' def Extract_Functions(idat64_path,file): #提取伪代码 - cmd=f'''{idat64_path} -A -B -S"extract_c.py" {file} + cmd=f'''{idat64_path} -A -B -S"interface_extract.py" {file} ''' save_dir="result" #cmd执行命令