混淆程序是恶意代码编写者用于隐藏其执行过程的代码。加壳程序是混淆程序中的一类,加壳之后的程序会被压缩,使得含义分析。
判断程序是否加壳的一个模糊的判别规则是,正常程序中的字符串往往会很多,而被加壳或混淆后的程序能够获取到的,能直接打印出的字符串却很少。
注意 加壳和混淆代码通常至少会带有LoadLibrary和GetProcAddress函数,主要是用于加载和使用其他函数的功能。
在加壳程序运行前,首先会运行一小段脱壳程序,来解压加壳的文件,然后再运行脱壳之后的文件。
通常,用于检测加壳软件的加壳类型,或是编译器类型是使用PEiD工具。但许多PEiD插件会执行恶意代码文件。
PE文件格式
可移植执行(PE)文件是Windows可执行文件、对象代码和DLL所使用的标准格式。其文件格式本质为一种数据结构,包含Windows操作系统加载器管理可执行代码所必要的信息。
PE文件以一个文件头开始,其中包括代码信息、应用程序类型、所需的库函数、空间要求。
链接库与函数
导入函数是一个程序所使用的但存储在另一个程序中的那些函数。
程序员可以将一些函数链接到他们的程序中,这样,就不必再多个程序中重复实现特定的功能。代码库可以被静态链接、运行时链接或者动态链接。
静态链接是Windows平台最不常用的方法。当一个库北静态链接到可执行程序的时候,该库中所有代码都会被复制到可执行程序之中(所以可执行程序会大很多)
运行时动态链接在合法程序中并不流行,但是在恶意代码中经常使用,特别是恶意代码被加壳或者是混淆的时候。使用运行时链接的可执行程序,只有当需要使用函数的时候才链接到库,而不像动态链接模式在程序启动的时候就会链接。
一些Windows API允许程序员导入一些没有在程序头重声明列出的链接函数。 其中最常见的是LoadLibrary和GetProcAddress。上述两个函数允许一个程序访问系统上任何库中的任何函数。
在所有链接方法中,动态链接是最常见的。当代码库被动态链接时,宿主操作系统会在程序被装载的时候搜索所需要的代码库,如果程序调用了被链接的库函数,这个函数就会在代码库中执行。PE头存储了每个被装在的库文件,以及每个会被程序使用的函数信息。
PE文件头与分节
.text : 包含了CPU执行指令。所有其他节存储数据和支持性的信息。一般来说,这是唯一可执行的节,也是唯一包含代码的节。
.rdata: 包含导入与导出函数信息,还可以存储程序所使用的其他只读数据(有些文件中还包含.edata 和 .idata 分别用户表述导出函数信息与导入函数信息)
.data: 包含程序的全局数据,即可以在程序的任何位置访问到。
.rsrc: 包含由可执行文件所使用的资源,而这些内容并不是可执行的。
PE文件头信息包含如下几个方面
- 导入函数
- 导出函数
- 时间戳(程序是在什么时间被编译的)
- 分节(文件分节名称以及在磁盘与内存中的大小)
- 子系统(指示程序是命令行还是图形化界面程序)
- 资源