基于代码搬移的PE文件信息隐藏
2010-08-06朱天明刘嘉勇
朱天明, 刘嘉勇
(四川大学 信息安全研究所,四川 成都 610064)
0 引言
随着计算机技术的飞速发展,以及互联网的广泛应用,计算机已经逐渐成为了人们日常生活不可或缺的一部分,人们所能接触到的信息也越来越多。信息的安全渐渐的成为了人们关注的主要问题,信息隐藏就是实现信息安全传输的一种解决方法。目前,信息隐藏技术主要局限于针对图像、声音、视频等多媒体载体[1]。对基于可执行(PE)文件信息隐藏技术的研究还很有限,它主要是利用 PE文件结构中的冗余空间和字段、静态分配的字符串存储空间等来进行信息隐藏[2-3]。这些方法都存在信息隐藏过于集中,信息与原始 PE文件内容结合不够紧密,容易被发现的缺点[4]。针对这些问题,在研究 PE格式以及机器指令格式的基础上,提出了一种基于代码搬移来将信息隐藏到 PE文件中的方案,并对方案进行了实现和分析。
1 基于代码搬移的PE信息隐藏方案
1.1 方案原理
一般在程序的编写过程中,程序员都会写出很多的子程序来实现各种功能,并在主程序中调用这些子程序,这就使得在一个完整的程序中会存在着很多大大小小的子程序。在PE文件代码节中,一个子程序就是相对完整的一块代码块,这块代码实现一个特定的功能。正是子程序的这个相对完整的特性给了将子程序进行搬移的可能。可以根据载体文件的冗余大小和隐藏文件的大小,选取若干个子程序并将其搬移到代码节末尾的冗余空间中,然后在原来子程序处隐藏信息,为了加强信息的机密性和抗攻击的性能,在信息隐藏时,可以对信息进行加密,以及用秘密共享技术将信息分割存储到不同的子程序中,这样当一部分的信息被破坏的时候,仍然可以恢复出隐藏信息。
在选取子程序时,选取的子程序的总大小要大于或等于经过秘密分割和加密处理之后的隐藏文件的大小,并且小于载体文件总的冗余大小,这样才可以实现信息的隐藏。在对子程序进行搬移时,由于搬移的是二进制的代码,所以需要解决以下三个方面的问题:
(1)判断子程序的位置
对于子程序的搬移,在搬移之前,首先需要准确的判断出子程序在代码中所处的位置。由于对子程序的调用都是通过主调程序的Call指令进行的,所以可以通过Call来查找子程序的位置。先将二进制的代码进行反汇编,通过 PE头OptionalHeader结构体中的字段AddressOfEntryPoint找到程序的入口点[5],从程序的入口点处依次查找Call指令,并且排除掉对动态链接库中的函数的调用就能得到子程序的地址。如汇编指令CALL 0x00431234,0x00431234处就是一个子程序的开始。
(2)判断子程序的大小
对于子程序的大小,可以通过子程序的结尾地址减去开始地址得到,开始的地址通过第一步找到的CALL指令的跳转地址可以得到,现在需要判断子程序的结尾地址。在汇编指令中,在一个程序结尾处都会出现一条retn指令来清理子程序使用的堆栈以及将程序返回到调用程序处[6]。所以,可以通过找到retn指令来判断子程序的结尾地址。然而,在有的子程序中,当进行条件判断的时候,可能会有多个retn指令,其中只有一个retn才是子程序真正的结尾,如图1。在这种情下,程序中间出现的retn指令前面会出现如JZ、JNZ等条件转移指令,如果条件满足程序就会跳转到这个retn指令后面去执行,那么这个retn指令就有可能不会执行,也就不是程序结尾的标志,如子程序中第一个 retn。所以判断子程序大小的方法为:依次查找retn指令,然后排除掉可能会被跳转指令跳过的retn,直到找到最终的retn指令,从而得到子程序的结尾地址。具有多个retn折子程序如下:
(3)修改子程序中的跳转指令
在搬移子程序的时候,由于跳转指令的特性,需要对跳转指令重新进行改写以使得其跳转到正确的地址,这样才能保证程序在隐藏了信息之后仍然可以正常运行。在子程序中,跳转指令有CALL和JMP两类,对应的机器码分别为E8 XXXXXXXX,E9 XXXXXXXX,其中偏移量(XXXXXXXX)=跳转的目的地址-跳转的起始地址-5h 。JMP指令不需要修改,需要修改的为CALL指令。在搬移过程中,CALL指令跳转的目的地址没有发生变化,而跳转的起始地址由于指令被搬移了而发生了变化,从而偏移量也会发生变化。这就需要将子程序中所有的这种 CALL的偏移量根据搬移到的位置进行重新计算并改写,使其在搬移后仍能调用正确的函数。
1.2 方案的实现
1.2.1 方案的实现流程
如图1所示。此为信息隐藏的实现流程,对于提取过程,仅仅是隐藏过程的逆过程。
图1 实现流程
1.2.2 实现步骤
(1)对载体文件以及隐藏信息文件的预分析
对载体PE文件C进行预分析,得到载体文件子程序的数量、大小以及 PE文件代码段的冗余大小,并根据调用的先后顺序将子程序排序并标上序号。对隐藏信息进行分析得到秘密分割后信息的大小。通过分析得到的数据,选取合适的子程序并用密钥K表示所选取的子程序的序号。如,选取第1,2个子程序,则密钥为0102.
(2)对信息进行预处理
首先,用密钥K对需要隐藏的信息进行加密得到M’。然后,用秘密分割算法将加密后的信息进行分割得到子信息,,…,。这里在实现中将隐藏信息分为3个子信息,门限为2即需要两个完整的子信息便可以恢复隐藏信息。
(3)对信息进行隐藏
通过密钥K的控制,找到需要隐藏信息的子程序,将子程序搬移到代码段末尾的冗余处,并且将其中的 CALL指令进行修改。然后,在原来子程序最开始处添加一句代码,JMP xxxxxxxx其中xxxxxxxx是子程序被搬移处的地址,添加这一句指令使程序能跳转到正确的子程序处执行,接着将子信息,,…,依次隐藏到子程序原来的位置处。隐藏完毕之后,再将子信息的大小数据保存在一个 PE文件固定位置处,以便在恢复隐藏信息时将子信息分离开来。这里在实现中将子信息大小数据保存在 PE头的冗余位置处。然后修改PE文件头的VirtualSize字段为修改后代码节的大小,最后得到隐藏了信息的PE文件。
(4)信息的提取
信息的提取过程仅仅是信息的隐藏过程的逆过程。首先,通过密钥找到隐藏了信息的原始子程序的位置,并根据保存的子信息的大小,分别提取隐藏的子信息。然后,用找到的足够份数的子信息通过密钥分割技术恢复原始的加密信息,并对加密信息进行解密,得到隐藏信息。
2 实验及分析
算法实现平台:Microsoft Windows XP sp2,1.5G RAM,Microsoft Visual C++ 6.0。 软件包括一个分析程序中子程序的大小的模块,并用序号将子程序标出。实验选取的隐藏载体文件为CPU-Z.EXE版本为1.5.2.2,其中代码节的冗余大小为 3 252 bytes。根据代码节冗余,选取的隐藏文件为CPU-Z的系统配置文件cpuz.ini大小为180 bytes。运行软件,可以在软件子程序分析的模块中得到子程序的序号和大小信息,以及经过秘密分割后隐藏文件的大小。根据处理后隐藏文件cpuz.ini的大小260 bytes,选取了第1、20两个子程序进行隐藏。输入密钥 0120点击预处理,等预处理完成之后,点击隐藏信息,然后便可以得到隐藏了信息的CPU-Z.EXE文件。执行隐藏了信息的载体程序,程序仍然能正常运行并且功能完整。点击提取信息得到提取出来的cpuz.ini,将其与原来的 cpuz.ini文件用文件对比软件WinMerge对比,两个文件完全一致。
本方案不是将信息简单地隐藏到节末尾的冗余处,而是将信息隐藏在正常的代码之中,提出的PE信息隐藏方式如下:
正常代码…
隐藏密文
正常代码…
而在其前面和后面的部分都是 PE文件正常的代码。传统的将信息隐藏到 PE文件节后冗余处的方法,隐藏信息后的PE文件如下:
正常代码…
密文…
00 00 00 00 00 00 00(PE段尾全为零)
隐藏的信息在代码段末尾,而在其下的部分为冗余段,全部为零。可以看到用本方案隐藏的信息处于 PE文件代码之中,而传统方案仅仅在节末尾隐藏了数据。可见本方案和传统方案相比隐藏的数据具有更高的隐蔽性,并且选取了多个子程序进行隐藏,因此隐藏的信息具有分散性,而一个载体文件可以有很多的子程序,攻击者在没有密钥的情况下,想找的正确的子程序,难度很大。
3 结语
随着因特网和计算机的普及,各种各样的软件层出不穷,目前,网络上就存在着大量的PE格式文件,基于PE文件的信息隐藏具有很广阔的应用前景,隐藏载体多样化,数量多、种类多,只要是PE格式的执行程序都可以成为隐藏的载体,隐藏后不易被察觉。现创造性的提出了将PE文件原有代码进行搬移,而将信息隐藏到正常的PE文件数据之中,将隐藏数据和PE文件原始数据紧密的结合在了一起,避免了隐蔽信息过于集中的问题,增强了隐藏信息的隐蔽性和安全性。
[1] 高凌燕,王趾成,易向军.基于BMP文件信息隐藏技术的探讨[J]. 通信技术,2008,41(08):54-56.
[1] 刘振华,尹萍.信息隐藏技术及其应用[M]. 北京:科学出版社,2002.
[2] 吴振强,冯绍东,马建峰.PE文件的信息隐藏方案与实现[J].计算机工程与应用,2005,41(27):148-150.
[3] 方旺盛,邵利平,张克俊.基于PE文件格式的信息隐藏技术研究[J].微计算机信息,2006,11(3):77-80.
[4] 端木庆峰,王衍波,张凯泽,等.基于 PE文件资源数据的信息隐藏方案[J].计算机工程,2009,35(13):128-133.
[5] 段钢.加密与解密[M].第3版.北京:电子工业出版社,2008:269.
[6] IRVINE K R. Assembly Language for Intel-Based Computers Fourth Edition[M].北京:电子工业出版社,2004.