上面的公式可延展功能去污染整个代码流程块,如果某一特定代码块被攻击者控制了(并非 由崩溃生成的输入值直接作为目的地址),那么我们就需要先解决实际的定值限制问题,不 过其追踪的复杂度也会呈指数型增长。研究人员是有创造力的,他们创建出了其它各种污点 分析方法,比如确定敏感数据在系统中的持续时间【6】,以及/或者正式定义一个安全信息 流【7】。 中间语言和污染源 为了追踪污染源和控制污点传播,那么就必须采取一种程序分析方法,以帮助理解目标 程序语言的语义。在高级语言中可用于污点分析的工具有用0++和Java写的一些工具【7】 【8】【9】,但本文主要注重于汇编级的代码分析。笔者也建议读者阅读一些关于符号化执行 (symbolic execution)【9】【10】和SAT Solvers【11】【12】【13】的文章,这些文章也 是与本文主题息息相关的。r^^) 理解程序指令最为经典的方法就是使用一种中间语言,它可提高代码质量和程序的可移 植性。在这方面有很多优秀文章可供参考,本人推荐【14】【15】【16】等文章,同时我还想 说,我是直接使用WinDBG api来分析的,它在考虑移植性方面并不是最好的方法,但它相 对代码而言却是最快的。 WinDBG插件是以DLL的形式被调试器使用LoadLibrary函数来加载的,并在调试器进 程上下文中运行。这些插件是被调试器所信任的。调试器尝试去处理访问违例,但插件本身 中的堆腐败会导致调试器崩溃。所有的调试器插件均会调用到Win32 API和调试器接口 (dbgeng. dll)。最有趣的是调试器API将会提取目标的类型/版本,这就意味着你可以编写 一个插件,让它可运行在处于活动状态的调试会话(live debugging session)或者dump 文件之中,这对于用户模式/内核模式下的目标进程均适用。对于WinDBG主要有两类扩展 參WdbgExts ->旧版调试器扩展接口存在一些符号和类型查找的限制问题。 參DbgEng _>新版调试接口,作为附加项目被添加进去的,为调试器的执行提供各类接 0匕层£叩扩展八?1来源于此86叩.311,通过调用接口来创建新的独立工具,以下是其具备的 一些功能: 參获取当前进程/线程信息 •读/写内存 參符号/类型查找 在调用扩展函数之前,首先还需要创建调试接口对象,然后调用这些对象所提供的接口。使 用DbgEng扩展函数必须先输出DebugExtensionInitialize入口点,然后再选择性地输出 DebugExtensionNotify* DebugExtensionUninitialize 入口点。如之前所述,调试器将使 用1(^礼11«^7()来加载扩展dll文件,然后使用&61?『00八3办688()去查找函数入口点。附 上代码: HRESULT CALLBACK DebugExtensionInitialize( OUT PULONG Version, OUT PULONG Flags ) 在加载扩展函数之前需要先调用这一强制性入口点。此函数通过以下代码来获得新的调试器 接口: if ((Hr = DebugCreate(—uuidof(lDebugClient)), (void **)&DebugClient)) != S_OK) if ((Hr = DebugClient->QueryInterface(—uuidof(lDebugControl), (void **)&DebugControl)) != S_OK) 可选函数: void DebugExtensionNotify( OUT ULONG Notify, OUT UL0NG64 Argument 调用上述函数后,即可连接或断开目标,也可不在代码中使用该函数。当插件被卸载后, 0613叫£1161^101^^1^11&1126会被调用,用于执行清除例程,代码如下: HRESULT CALLBACK vdt_trace(PDEBUG_CLIENT Client, PCSTR args) 它可作为调试器的一个插件来使用(直接在调试器中使用!^扣」!^^来调用),其中args 参数是传递给插件的命令行参数字符串。MAPI函数用在获取进程信息时很有用,本人强烈 建议读者去阅读下关于它的源码。 可观数据的爆增 有分析过污点传播的朋友可能知道里面一个最大的难点就是如何追踪各类数据的变化。 在此我们需要先具备以下知识: 參识别出所有的指令和操作数; 參找出污染源,污染的目标地址以及其它受影响的各个寄存器(某些情况下是不用追踪 受影响的寄存器的,比如£?1八&3中的比较标志【6】); 參标记所有污染数据; 參理解每一条指令的执行行为。 显而易见,追踪以上所有信息是很占用性能的,即性能密集型(performance-intensive), 它将影响到决策时间以及后续工作。关于指令的隐性和显性操作数,它们都需要支持所有的 环境,否则在追踪一些重要的污染数据时容易丢失。下面提供一个关于push %eax操作指 令的例子【5】: 參显性操作数:%6狀寄存器 參隐性操作数:%esp和ss |