Obfuscation/lua_scripts/analyze_analzgen.py

98 lines
3.8 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 xml.etree.ElementTree as ET
from collections import defaultdict
import argparse
import json
def analyze_analyze_xml(xml_dir: str):
print(f"开始分析................")
func_info = {}
reverse_calls = defaultdict(list)
for fname in os.listdir(xml_dir):
if not fname.endswith(".xml"):
continue
fpath = os.path.join(xml_dir, fname)
try:
tree = ET.parse(fpath)
root = tree.getroot()
except Exception as e:
print(f"[WARN] 无法解析 XML 文件: {fpath}, 错误: {e}")
continue
for memberdef in root.findall(".//memberdef[@kind='function']"):
name = memberdef.findtext('name')
if not name:
continue
location = memberdef.find('location')
decl_file = location.attrib.get('file', '') if location is not None else ''
decl_line = location.attrib.get('line', '') if location is not None else ''
body_file = location.attrib.get('bodyfile', '') if location is not None else ''
body_line = location.attrib.get('bodystart', '') if location is not None else ''
# 替换为映射后的路径(比如 /opt/output -> /files
adjusted_path = fpath.replace("/opt/output", "/files")
# 初始化函数信息
if name not in func_info:
func_info[name] = {
"function": name,
"declaration": f"{decl_file}:{decl_line}" if decl_file else "unknown",
"definition": f"{body_file}:{body_line}" if body_file else "unknown",
"calls": [],
"called_by": [],
"call_count": 0,
"called_count": 0,
"xml_file": adjusted_path
}
# 当前函数调用了哪些函数
for ref in memberdef.findall("references"):
callee = ref.text
if callee and callee != name:
func_info[name]["calls"].append(callee)
reverse_calls[callee].append(name)
# 当前函数被哪些函数调用
for ref_by in memberdef.findall("referencedby"):
caller = ref_by.text
if caller and caller != name:
func_info[name]["called_by"].append(caller)
reverse_calls[name].append(caller)
# 更新调用次数统计
for name, data in func_info.items():
data["call_count"] = len(set(data["calls"]))
data["called_count"] = len(set(data["called_by"] + reverse_calls.get(name, [])))
# 处理未定义但被调用的函数
for func, callers in reverse_calls.items():
if func not in func_info:
func_info[func] = {
"function": func,
"declaration": "unknown",
"definition": "unknown",
"calls": [],
"called_by": list(set(callers)),
"call_count": 0,
"called_count": len(set(callers)),
"xml_file": "unknown"
}
print(f"分析结束,正在生成结果................")
return list(func_info.values())
def export_json(results, path):
with open(path, "w", encoding="utf-8") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
print(f"✅ 已导出 JSON 文件:{path}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="分析 analyze XML输出 JSON 格式函数调用统计")
parser.add_argument("xml_dir", help="analyze 生成的 XML 文件夹路径")
parser.add_argument("--json", required=True, help="输出 JSON 文件路径")
args = parser.parse_args()
results = analyze_analyze_xml(args.xml_dir)
export_json(results, args.json)