Files
Extract_code/interface_extract.py
2024-10-18 17:42:24 +08:00

126 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,flags):
struct_list=export_local_types_for_struct()#返回字典列表
if(struct_list is None):return
if flags==0:
# # 将结构体信息转换为 JSON 格式
json_output = json.dumps(struct_list, indent=4)
#print(json_output)
filepath=save_file+"_Estruct.json"
with open(filepath,"w") as f:
f.write(json_output)
else :
# 字符串存储
filepath=save_file+"_Estruct.txt"
with open(filepath,"w") as f:
for i in struct_list:
f.write(f"[{i['name']}:struct_size {i['size']} -> {i['info']}]\n")
#函数黑名单
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="../input"
extractfile="extractelf"
filepath="tmp.txt"
try:
if(not os.path.exists(save_dir)):os.makedirs(save_dir)
if (os.path.exists(filepath) and os.path.isfile(filepath) ):
with open(filepath,"r") as f:
extractfile=f.read()
extractfile=extractfile.split("/")[-1]
extractfile=os.path.join(save_dir,extractfile)
export_func(extractfile)
export_local_types(extractfile,0)
except Exception as msg:
mylog("main",msg)
if __name__ == "__main__":
try :
auto_wait()
assert (init_hexrays_plugin()), "Hex-Rays Decompiler is not available!"
main()
except AssertionError as msg:
mylog("__main__",msg)
qexit(0)