Detour(上)

发表于:2007-07-01来源:作者:点击数: 标签:
Detours: Binary Interception of Win32 Functions Detours: 在二进制代码上截获Win32函数调用 Galen Hunt and Doug Brubacher Microsoft Research One Microsoft Way Redmond, WA 98052 注:这篇论文首次发表是授权给USENIX。作者保留著作权。本文允许出于

Detours: Binary Interception of Win32 Functions

Detours: 在二进制代码上截获Win32函数调用

Galen Hunt and Doug Brubacher

Microsoft Research

One Microsoft Way

Redmond, WA  98052

注:这篇论文首次发表是授权给USENIX。作者保留著作权。本文允许出于非商业性目的拷贝,例如教育和研究目的。第一次发表在Proceedings of the 3rd USENIX Windows NT Symposium. Seattle, WA, July 1999。

 

摘录

具有创意的系统级检测研究的关键,在于使得截获函数调用变得更简单以及用来扩展已经存在的操作系统和应用程序的功能。通过得到源代码,我们可以轻而易举的通过重建(Rebuilding)操作系统或者应用程序的方法在它们中间插入新的功能或者做功能扩展。然而,在今天这个商业化的开发世界里,以及在只有二进制代码发布的系统中,研究人员几乎没有可能可以得到程序的源代码。

我们开发的Detours 是一个在x86平台上截获任意Win32函数调用的工具库。Detours通过重写目标函数的映像来达到插入到Win32 函数中执行的目的。Detours开发包中同样保留了描述如何附着到任意的Win32二进制文件的DLLs和data节表(被称为一种有效负荷,“payloads”)的文档。

虽然以前的开发人员曾经使用重写二进制代码的方法将调试和性能测试的代码加入到应用程序中,但是据我们所知,Detours是第一个在任意平台(译注:指Windows平台)都提供了可以将目标函数做为一个截获函数的子过程来调用的开发包。我们独特的trampoline设计是扩展已存在的二进制软件的关键。

我们将介绍我们使用Detours来生成一个自动化的分布式系统的经验,这个系统被用来分析DCOM协议栈,并且被用来为基于COM的OS API生成一个thunking层。它从一个微观的基准上证明了Detours库的有效性。

1 介绍

具有创意的系统级检测研究的关键,在于使截获函数更简单可行以及扩展已经存在的操作系统和应用程序的功能,不论这个函数存在于一个应用程序,一个库,或者一个系统的动态链接库中。我们截获函数执行最直接的原因就是为函数增添功能,修改返回值,或者为调试以及性能测试加入附加的代码。通过访问源代码,我们可以轻而易举的使用重建(Rebuilding)操作系统或者应用程序的方法在它们中间插入新的功能或者做功能扩展。然而,在今天这个商业化的开发世界里,以及在只有二进制代码发布的系统中,研究人员几乎没有机会可以得到源代码。

Detours是一个在x86平台上截获任意Win32函数调用的工具库。中断代码可以在运行时动态加载。Detours使用一个无条件转移指令来替换目标函数的最初几条指令,将控制流转移到一个用户提供的截获函数。而目标函数中的一些指令被保存在一个被称为“trampoline” (译注:英文意为蹦床,杂技)的函数中,这些指令包括目标函数中被替换的代码以及一个转移到目标函数的无条件分支。而截获函数可以替换目标函数,或者通过执行“trampoline”的时候将目标函数作为子程序来调用的办法来扩展功能。

Detours是执行时被插入的。内存中的目标函数的代码不是在硬盘上被修改的,因而可以在一个很好的粒度上使得截获二进制函数的执行变得更容易。例如,一个应用程序执行时加载的DLL中的函数过程可以被插入一段截获代码(detoured),与此同时,这个DLL还可以被其他应用程序按正常情况执行(译注:也就是按照不被截获的方式执行,因为DLL二进制文件没有被修改,所以发生截获时不会影响其他进程空间加载这个DLL)。不同于DLL的重新链接或者静态重定向,Detours库中使用的这种中断技术确保不会影响到应用程序中的方法或者系统代码对目标函数的定位。

如果其他人为了调试或者在内部使用其他系统检测手段而试图修改二进制代码,Detours将是一个可以普遍使用的开发包。据我们所知,Detours是第一个可以在任意平台上将未修改的目标代码作为一个可以通过“trampoline”调用的子程序来保留的开发包。而以前的系统在逻辑上预先将截获代码放到目标代码中,而不是将原始的目标代码做为一个普通的子程序来调用。我们独特的“trampoline”设计对于扩展现有的软件的二进制代码是至关重要的。

出于使用基本的函数截获功能的目的,Detours同样提供了编辑任何DLL导入表的功能,达到向存在的二进制代码中添加任意数据节表的目的,向一个新进程或者一个已经运行着的进程中注入一个DLL。一旦向一个进程注入了DLL,这个动态库就可以截获任何Win32函数,不论它是在应用程序中或者在系统库中。

在下一节里我们将讲述Detours是如何工作的。第3节概述了如何使用Detours库,第4节描述了截获函数使用的一般技术以及如何通过一个微观标准来衡量Detours。第5节详细描述了如果使用Detours从本地应用程序产生分布式应用程序,用来量化DCOM的花费,为一个新的基于COM的Win32API建立一个thunking层,并且实现捕获第一次机会异常。我们会在第6节将Detours和其他人的相关工作做一个比较并且在第7节作出总结。

截获

Detours提供了三种很重要的功能:在x86机器上任意中断Win32二进制函数的执行的能力,编辑二进制文件导入表的能力,以及向二进制文件中附着任意数据节表的能力。

我们会描述每一种截获功能。

2.1 截获二进制函数

Detours库使得截获函数调用更容易,截获代码是运行时动态加载的。Detours使用一个无条件转移指令来替换目标函数的最初几条指令,将控制流转移到一个用户提供的截获函数。而目标函数中的一些指令被保存在一个被称为“trampoline”的函数中,这些指令包括目标函数中被替换的代码以及一个转移到目标函数的无条件分支。

当程序执行到达目标函数的时候,会直接跳转到一个用户支持的截获函数。截获函数来执行适当的预处理。截获函数可以直接返回到原来的函数,或者它可以调用“trampoline”函数,后者可以按照截获以前的方式来调用目标函数。当目标函数执行完以后,它将控制返回到截获函数。而截获函数将执行恰当的收尾工作并将控制返回到源函数调用处。Figure 1显示了被截获和未被截获的调用在逻辑上的控制流。

原文转自:http://www.ltesting.net