逆向工程技术简析
2015-02-06刘键林
刘键林
(天津现代职业技术学院,天津 300350)
逆向工程技术简析
刘键林
(天津现代职业技术学院,天津 300350)
论述与分析一些在学习逆向工程的过程中经常遇到的专业术语,以及逆向分析软件工具的简单初步使用。这些术语以及工具软件的使用, 对于今后的逆向分析与学习是非常有帮助的。因此有必要对这些专业术语进行简要分析,以便加深记忆, 在今后的学习中方便使用。
API接口函数;断点中断;领空;文本编码;区段特征
API接口函数
API函数接口,就是目前我们使用的操作系统Windows。操作系统预留给任何软件开发者在Windows应用程序下运行使用而调用的函数接口,目前所有在Windows窗口下运行的各种应用程序与程序员,最终都要满足且必须通过底层来调用系统内部的诸多函数来实现软件本身其所要实现的各种功能。但是通常Windows系统自带函数内包括两种基本函数形式,Windows16位函数、和Windows32位函数。16位函数与32位函数它们之间存在的不同之处在哪里且如何辨识?在于Windows,API函数末尾最后的一个字母之区别。
针对函数举例说明:AbortPrinter、MessageBox等,是16位Windows系统下的函数。MessageBoxA,与MessageBoxW等,是32位Windows操作系统下的接口函数。而在这里我们必须弄清楚的是:MessageBoxA,函数是单字节。MessageBoxW即是函数将使用双字节完成调用。我们大家在反方向分析一些程序的过程中,经常使用到的是Windows32单字节函数,就是和MessageBoxA与之类似的函数,而其它的两种(Win16 单字节函数和Win32双字节函数)比较少见并且不会经常用。 因此Win32操作系统之下的这些 API函数,它们完全包含在动态的链接库之内,包含在那些例如comctl32、user32.dll等的...*.*dll库中。
断点与中断:断点即当前运行的程序被中断在某一个位置,所以断点方式很多。例如,内存断点、硬件断点、访问断点等。中断就是当程序运行过程中由于有某些特殊事件的发生,计算机暂时停止当前正在执行当中的任务,而去执行另外发生的(指令)紧急任务。当中断指令的紧急任务完成之后,马上返回到程序原先执行的任务中继续执行未完成的任务。这样的过程,即计算机完成的一个中断过程。据此,我们详细分析某些程序的过程,就是等到被分析程序去获取我们输入信息的关键时刻,并准备与之计算结果相比较的关键位置与语句,将其重要点中断下来,然后我们通过OllyDbg这个非常强大的分析软件,来对中断后的程序进行仔细分析,找到其中正在比对的编程语言,继而进行相关信息的分析与学习。
程序领空与系统领空
领空,是个重要的概念。大家非常明白Windows是为诸多程序运行而提供的窗口,我们这里所指程序的领空,就是需要在Windows窗口下而运行的程序自己占用的地方,也就是我们需要进行分析的程序所处的使用内存位置。如果我们是在程序起始运行的时候进行断点的设置,但中断之后却为何不停留在所运行程序自己的空间,而是停留在系统函数的空间?这是因为由Windows控制着系统所有函数,所有在Windows下运行的程序是没有权限直接调用中断的,Windows系统只提供给所运行的程序一个系统功能调用平台“函数”。此时程序再次调用“函数”的时候,才可以中断其正常运行。例如,在OllyDbg调试的程序中设置以下的“获取弹出文本对话框”断点:bp GetDlgItemText,当被我们要调试分析的程序即将读取任意输入的数据而调用GetDlgItemText的关键时刻,立即被OllyDbg拦截到且中断在此处,从而被我们分析的程序将停留在GetDlgItemText这个关键函数区域内,重要的是GetDlgItemText是属于Windows自己管理的函数,任何程序、任何时候都不能对系统函数进行调试,因为没有任何意义的调试都将发生严重的系统崩溃后果。所以此时分析工作要从系统内函数区域返回到被调试的程序所运行的领空,方可以对程序进行细致的分析与汇编。
文本编码
在这里,我们还要简述一下Windows程序当中使用的编码。在调试软件与分析软件的过程中,映入我们视线较多的编码文本有三种:ASCII、 ANSI 和Unicode,这里ASCII码分别与后两种在较多程序当中为常用的基础编码,弄清楚这三种编码之间的联系和区别之间的关系,对于今后对程序代码的调试与识别有着极其重要的帮助。
ASCII码:主要体现在文本对话编码,ASCII码是编码的基础。本身具有七位的编码标准,囊括了26个大写字母,26个小写字母、32个符号、10个数字、33个控制代码。有趣的是,另加了一个空格,共计代码有128个。但是由于计算机是以“字节”为单位存储和交换数据信息的,所以设计与生产厂家为了解决这一难题,再次对ASCII码进行了范围的扩充,在原有的128个代码的基础上再次增加了128个字符附加进128个代码之中,后面继而出现了Unicode、ANSI等字符集。
ANSI字符集编码主要是使计算机能够支持更多国家的语种,因而特此制定了GB2312, BIG5, JIS 等各自的分类编码标准。不同的地区和国家为了与之相符,相继制定了不同的标准。但编码对于中文来讲,则必须使用两个字节的编码来代表一个汉字,所以表示汉字编码的方式称为双字节。虽然双字节的编码得以解决,但是在中英文字符混合使用的情况下问题又出现了,所以对于不同字符编码系统而言,就要经过转换字符码,使用起来极为不方便,如中日、中英文字混合使用的情况。为了更好地解决这一转换字符码问题,很多生产设计厂家再次联合起来制订了一套可以适用于全世界所有国家的字符码,不管是西方文字还是东方文字,一律用两个字节来表示,因此就产生了中西方通用的Unicode编码。
综上所述,我们分析的这些逆向分析术语是在OllyDbg1.1环境之下实现的。这里需要我们对OllyDbg运行过程有一个简单的了解以便分析软件。
OllyDbg 运行:首选的方法是首先运行 OllyDbg,点击上面的菜单中的“File”按钮,之后再打开“Open”选项。选择需要我们调试分析的“EXE”,也可以是“DLL”文件载入,此时的OllyDbg调试器已经运行,且已经完成加载任务。如果OllyDbg1.1加载运行被调试软件之后需要命令及参数,底部的命令窗口可以输入参数或者选择历史调试被OllyDbg1.1记录过的任意参数或“API”函数,例如:
Bp MessageBox(A)
OllyDBG 中各个窗口的功能如上图
然后敲击回车键,此时OllyDbg程序会马上中断,再被调试程序调用这个对话框或函数。
反汇编窗口:这里显示被调试程序的反汇编代码及相关语句,窗口内是我们反汇编程序需要进行分析的汇编语言在这里显示出来,此处根据我们学习到的知识内容进行系统的详细的分析。标题栏上面的地址条包括很多选项,反汇编、HEX 数据、等等控制按钮。注释信息可以通过在反汇编窗口中右击鼠标键,弹出菜单里面的选项->隐藏或显示,来进行切换是否显示标题。利用用鼠标左键单击注释标签,会得到注释显示的方式。寄存器窗口内:此窗口随着调试进度与跟踪,显示出当前所调试线程的CPU 与寄存器内容。这个窗口同样单击标签寄存器,可以显示切换寄存器窗口的方式。信息窗口:此窗口呈报出反汇编窗口中高亮处选中行的命令参数,以及一些跳转目标地址、字符串,诸多等等重要信息。在数据窗口内:显示出内存的使用信息或文件领空所使用的内容。右键单击菜单可用于切换相关且不同数据内容。堆栈窗口内:显示当前调试线程的压、出栈信息。命令窗口内:键入被调试程序API函数以及断点命令,例如:bp MessageBox(A),敲击回车键之后被调试程序在创建对话框时将被中断。
另外,OllyDbg 还具有调试独立的DLL动态链接库函数。调试动态链接库时,OllyDbg 会创建并运行一个另外线程的应用程序来加载链接库,并根据需要调用输出函数。
如果我们需要重新运行OllyDbg上一次调试过的程序,只需要按一下 Ctrl+F2快捷键,也就是OllyDbg调试过程中被程序跑飞,这样 OllyDbg 会以同样跑飞前的参数运行这个程序。也可以用鼠标将EXE、DLL拖拽到OllyDbg的汇编窗口中启动。
OllyDbg最关键的是把运行的进程挂接到自己的程序当中,对其反汇编分析、窥视其领空。关闭 OllyDbg 的同时,这个进程也会被相继关闭。但是千万不要挂接系统的进程,否则非常可能会导致整个操作系统的崩溃(目前大多数操作系统对挂接敏感进程是禁止的)。
另外还有相关的多线程OllyDbg可以多线程调试任何程序,从这个线程切换到另外一个线程。具有非常重量级的功力是分析器:分析器是OllyDbg非常重要的一部分,它可以识别过程,分析嵌入代码中的常数和字符串等复杂的结构,以及API函数的调用情况,函数参数调用号,输入、输出段等等。精致地使用分析器使调试变得容易,对于减少错误中断和崩溃的可能性更有保障。
常见编程语言的入口OEP、及区段特征代码
我们从OEP开始分析。OEP是每个PE文件被加载时的起始的首地址,这个地址对于程序的运行至关重要。因为分析程序中的这个值,可以判断程序是否被加壳。我们分析的程序如果被加壳,脱壳时的必需步骤是找到OEP,也就是程序的入口地址。目前大多数本地运行的软件基本被隐藏了入口地址,也就是被加壳。软件加壳的目地就是隐藏OEP(或者使用花指令伪装OEP), 来迷惑分析人员对其程序进行细致的分析,但是程序的运行与本身的调用是不会受到任何影响的,只要我们找到程序真正的OEP地址,也就是程序调用的真正入口地址 PUSHAD (压栈)。就可以立刻对其进行脱壳分析处理,使其还原到程序真正的编程语言。那么什么是壳呢?本文只是从调试技术的角度做一个简单的解释。壳实际就是一段执行于原始程序前的代码。也可以这样理解,壳是在程序的外面再包裹上另外一段代码,保护里面的代码不被修改或反编译的程序。任何时候壳都将优先于程序运行权,掌握着程序的控制权,然后完成它所要保护程序不受任何编译的任务。
在实际的软件分析逆向过程当中,从不同编程语言在实际的程序入口处,即可发现它们的特征编码是各不相同的。对于特征码的辨识,也有利于我们第一时间观察到程序是否被加壳,如若程序被加壳,从程序的OEP入口地址处利用OllyDbg自带的脱壳工具进行脱壳。目前已经有很多现成的脱壳工具,使用OllyDbg手动脱壳且加以分析,收获颇丰。熟悉地掌握编程语言的特征,以及入口代码相关区段,是根据它们辨别应用程序使用何种编程语言、是否到达程序入口点的判断依据。
如果对编程语言的入口及区段特征有了基本的了解,了解了语言的入口及区段特征代码原理,就不难明白它的使用方法,以及脱壳之后识别程序员所使用的语言的种类,继而为进行深入的学习而打下基础。如果是恶意软件,则可以对其进行深层次的分析。其实,掌握任何的一种编程语言,都需要我们在学习过程中不断积累经验。
[1]谭文,邵坚磊,著.天书夜读:从汇编语言到Window内核编程[M].北京:罗云斌审校电子工业出版社,2008.
[2]宁树林,刘键林,著.软件逆向分析实用技术[M].北京:北京理工大学出版社,2010.
LIU Jian-lin
(TianjinModernVocationalTechnologyCollege,Tianjin, 300350)
Brief Analysis on the Reverse Engineering Technology
Discuss and analyze some terminologies that are often encountered during the learning process of the reverse engineering, and the initially simple utilization of reverse analysis about software and tools. The utilization of these terminologies as well as the tools and software can be quite helpful for the future reverse analysis and learning. Therefore, it is necessary to conduct brief analysis on these terminologies, so as to deepen the memory, and facilitate the utilization in the future leaning.
API interface function; Breakpoint interrupt; Territorial sky; Text code; Section features
2015-10-24
刘键林(1959-),男,天津市人,天津现代职业技术学院计算机实验室管理员,工程师,从事计算机加密与解密教学与研究工作。
TP391
A
1673-582X(2015)12-0093-04