欢迎光临
我们一直在努力

IDA Pro IDC 与 IDAPython 脚本实战:自动化识别危险函数调用点

IDA Pro IDC 与 IDAPython 脚本实战:自动化识别危险函数调用点

静态二进制代码审计的自动化刚需

在针对闭源固件、大型二进制应用或恶意代码进行安全审计时,手动在 IDA Pro 的函数列表和反汇编窗口中逐个查找调用点效率极低。C/C++ 历史遗留代码中广泛存在不安全的字符串操作与系统调用函数——如 strcpy、strcat、sprintf、gets、system 等。这些函数若未对输入长度进行严格校验,极易诱发栈缓冲区溢出(Stack Overflow)与命令注入(Command Injection)漏洞。

为了在大体量的二进制程序中迅速缩小审计靶面,安全研究员通常利用脚本语言驱动 IDA 的分析引擎。IDA 提供了两种主流脚本接口:早期的 IDC 脚本与现代的 IDAPython。熟练运用 IDAPython 自动化提取交叉引用、分析调用点栈帧结构并高亮潜在风险点,是二进制安全审计的核心基本功。

IDC 与 IDAPython 的技术架构对比

维度IDC (IDA C-like Script)IDAPython (Python SDK 绑定)
语法风格 类似早期 ANSI C 与 C++,需显式声明变量 标准 Python 3,支持面向对象与高级容器
API 覆盖度 覆盖基础的反汇编导航、打断点与数据读取 完整封装 IDA C++ SDK,支持微码(Microcode)与反编译器 AST
第三方生态 封闭,无法引入外部库 可无缝集成 networkx、z3-solver、capstone 等分析库
维护与发展 处于维护状态,新特性支持有限 社区绝对主流,持续跟随 IDA 7.x/8.x/9.x 架构演进

在工程化审计脚本开发中,强烈推荐优先采用 IDAPython;而 IDC 仅在需要编写极轻量、免依赖的快速单行宏时使用。

危险函数调用点自动化识别 IDAPython 脚本实现

以下 IDAPython 脚本专为自动化静态审计设计,能够自动遍历导入表(Imports),定位所有高危 C 标准库函数,追溯其所有交叉引用(Code XRefs),分析调用处的栈帧偏移,并在反汇编界面自动为高危调用点着色与添加审计注释:

# ———————————————————————-
# Description : 自动化识别并审计二进制中的危险函数调用点与潜在栈溢出
# Target : IDA Pro 7.x / 8.x / 9.x (IDAPython 3)
# Author : HanShuo (SiliconVagrant)
# ———————————————————————-

import idautils
import idc
import ida_funcs
import ida_nalt
import ida_xref
import ida_bytes
import ida_lines

# 定义常见高危函数清单及其审计关注点
DANGEROUS_FUNCTIONS = {
"strcpy": "高危栈溢出风险: 缺少长度检查的目标拷贝",
"strcat": "高危栈溢出风险: 字符串拼接无边界限制",
"sprintf": "格式化字符串与栈溢出风险",
"vsprintf": "格式化字符串与栈溢出风险",
"gets": "严重漏洞: 绝对禁止使用的危险输入函数",
"scanf": "格式化溢出风险: 需检查格式符是否包含 %s 无限制读取",
"system": "高危命令注入风险: 需审计命令字符串来源",
"popen": "高危命令执行风险"
}

def analyze_call_site(call_ea, func_name):
"""分析危险函数调用点所在的上下文与栈帧结构"""
parent_func = ida_funcs.get_func(call_ea)
if not parent_func:
return

parent_name = ida_funcs.get_func_name(call_ea)
frame_size = parent_func.size() # 函数体大小

# 输出高危告警日志
print("[!] [AUDIT ALERT] 发现高危函数调用: {:<10} 位于: 0x{:08X} (所属函数: {})".format(
func_name, call_ea, parent_name
))

# 1. 在调用点反汇编行添加显眼的行尾注释
audit_msg = "[SECURITY RISK] " + DANGEROUS_FUNCTIONS.get(func_name, "危险调用")
idc.set_cmt(call_ea, audit_msg, 0)

# 2. 将高危指令所在行背景高亮标记为黄色 (0x80FFFF)
idc.set_color(call_ea, idc.CIC_ITEM, 0x80FFFF)

def scan_dangerous_api_calls():
print("\\n" + "=" * 70)
print("[*] 开始执行危险函数调用点全自动静态代码审计…")
print("=" * 70)

matched_import_count = 0
total_xrefs = 0

# 1. 遍历二进制导入表
import_count = ida_nalt.get_import_module_qty()

for i in range(import_count):
def import_callback(ea, name, ord):
nonlocal matched_import_count, total_xrefs
if not name:
return True

clean_name = name.lstrip("_") # 兼容 _strcpy / __strcpy 等前缀

if clean_name in DANGEROUS_FUNCTIONS:
matched_import_count += 1
print("\\n[+] 命中高危导入符号: {:<12} (导入地址: 0x{:08X})".format(name, ea))

# 2. 遍历该符号的所有代码交叉引用 (XRefs)
for xref in idautils.XrefsTo(ea):
if xref.iscode: # 仅关注代码段调用
total_xrefs += 1
analyze_call_site(xref.frm, clean_name)
return True

ida_nalt.enum_import_names(i, import_callback)

print("\\n" + "=" * 70)
print("[*] 静态审计完成! 共匹配到 {} 个高危符号,标记了 {} 处可疑调用点。".format(
matched_import_count, total_xrefs
))
print("=" * 70 + "\\n")

if __name__ == "__main__":
scan_dangerous_api_calls()

进阶审计:微码(Microcode)与参数回溯

单纯依靠交叉引用只能定位调用点,在实际工程中往往会产生大量误报(例如开发者使用了 strcpy(dst, "fixed_const") 拷贝已知短字符串)。为了提高审计精度,可结合 Hex-Rays 反编译微码 API 进行进阶分析:

1. Hex-Rays AST 污点参数回溯

利用 ida_hexrays.decompile 获取反编译生成的抽象语法树(AST):

  • 分析危险函数的第一个参数(目标缓冲区 dst)是否为栈上数组;
  • 分析第二个参数(源缓冲区 src)是否来自于外部输入(如网络 recv、命令行参数 argv 或文件读取 fread);
  • 若源数据来自外部不可信来源且目标为固定大小栈缓冲区,则将告警级别提升为 CRITICAL (可直接利用栈溢出)。

2. 批量无头模式(Headless Analysis)集成

在大型安全团队中,可利用 IDA 的无头运行模式(idat64 -A -S"script.py" target_binary),将该 IDAPython 审计脚本嵌入到企业 DevSecOps 固件漏洞扫描流水线中,实现全天候自动化漏洞挖掘。

赞(0)
未经允许不得转载:171主机测评 » IDA Pro IDC 与 IDAPython 脚本实战:自动化识别危险函数调用点
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址