第36章 64位计算

本文最后更新于:2022年5月27日 下午

第36章64位计算

不知不觉间,64位0S得到快速普及,本章讲解代码逆向分析工程师必须学习的64位计算(64bit Computing )相关知识。

36.1 64位计算环境

80386是Intel于1985年推出的CPU芯片,它是一种32位微处理器。当时由于其价格高昂、支持的OS少,几乎没有得到普及。随着1995年微软发布32位OS Winows 95,计算机正式进人32位计算时代。Windows 95向下兼容支持16位程序,已有的DOS应用程序大部分也能够稳定运行。经过几年16位/32位混用的过渡期,OS进入Windows 2000/XP时代,32位应用程序开始成为主流,并延续至今。此过程中,CPU、OS制造厂商深刻认识到32位PC的局限(主物理内存最大为4GB ),纷纷开始开发64位版本,这就是64位CPU与64位OS共同构成的64位计算环境。

36.1.1 64位 CPU

在32位CPU时代,Intel主导着技术主流(x86 ),AMD生产x86兼容芯片,形成追击之势。但 64位CPU中出现了比较有意思的事情。Intel最初发布的64位CPU IA-64(产品名:Itanium )是一款64位的功能强大的芯片。有意思的是,全新IA-64采用了与原x86系列(IA-32 ) CPU完全不同的芯片。就像IBM的PowerPC系列一样,搭载的寄存器以及使用的指令都是完全不同的,无法与现有的IA-32直接兼容(使用模拟器可以实现间接兼容,但速度慢)。

其实,IA-64是Intel与HP合作的产物,设计的初衷可能是为了大幅提高计算机性能,霸占整个PC与服务器市场,从而抛弃了向下兼容的特性。但是想要市场(特别是PC市场)放弃向下兼容可不容易。此后AMD发布了AMD64,它是一款兼容IA-32的64位芯片。支持向下兼容的AMD64在PC市场上大受欢迎。为了应对这种情况,Intel从AMD购买使用许可,发布了与AMD64兼容的EM64T,后来改名为Intel64。最近Intel推岀的Core2 Duo、i7/i5/i3等CPU就是Intel64系列的。通常说的x64是AMD64与Intel64的合称,指的是与现有x86(IA-32 )兼容的64位CPU,主要用于普通PC和服务器。而IA-64是与x64具有完全不同形态的CPU,主要用在大型服务器与超级计算机中。

术语一览

讲解64位CPU时会遇到相当多的术语,这可能会给各位造成困惑。现将常用术语整理如下。

术语 说明
AMD64 AMD研制的64位CPU(直接向下兼容x86)
EM64T Intel研制的兼容AMD64的CPU
Intel64 EM64T的新名称
IA-64 Intel与HP合作研发的64位CPU(可通过模拟器间接兼容x86)
x86 Intel的IA-32、IA-16、IA-8系列的CPU
x64 AMD64 & Intel64

36.1.2 64位OS

PC中使用的Windows 64位操作系统有Windows XP/Vista/7的64位版本。微软认为能否向下兼容32位是决定64位OS成败的关键,支持32位也被看作是64位OS的核心功能。为此,微软提供了名为WOW64的机制,现有的32位应用程序能够在这种机制下正常运行,使现有32位源码可以很容易地移植到64位系统。

LLP64数据模型

64位Windows中使用LLP64数据模型实现向下兼容,它将现有32位Windows数据模型(ILP32 )

中的指针大小更改为64位。所以将现有的32位源代码移植到64位系统时,只要在指针类型变换上

下工夫就行了

数据类型 short int long longlong 指针 OS
ILP32 16 32 32 64 32 MS Windows 32位
LLP64 16 32 32 64 64 MS Windows 64位
LP64 16 32 64 64 64 UNIX 64位

还有一点需要注意的是,HANDLE类型大小在64位Windows中已经变为64位。

另外,64位UNIX系列使用LP64数据模型,它与LLP64的不同在于长整型类型的大小为64位。

ILP32: Integer、Long、Pointer-32位。

LLP64: LongLong、Pointer-64位。

LP64: Long、Pointer-64位

36.1.3 Win32 API

创建64位应用程序时,现有的Win32 API几乎可以照搬使用,而非另外提供一套Win64 API。开发人员不用再熟悉新增的API,没有这个负担也是非常吸引人的地方。通过诸如此类的各种考虑,轻松实现将现有32位源代码移植到64位系统。

微软为了向下兼容并未另外制作Win64,以后安装64位系统时也会一同提供Win64。

36.1.4 WOW64

现在正处于32位到64位的过渡期,在64位OS中正常运行现有的32位应用程序是重中之重。就像先前的Windows 95能够同时支持32位Windows应用程序与16位的DOS程序运行一样。WOW64(Windows On Windows 64 )是一种在64位OS中支持运行现有32位应用程序的机制。

64位Windows中,32位应用程序与64位应用程序都可以正常运行。64位应用程序会加载

kernel32.dll(64位)与ntdll.dll(64位)。而32位应用程序则会加载kernel32.dll(32位)与ntdll.dll(32位),WOW64会在中间将ntdll.dll(32位)的请求(API调用)重定向到ntdll.dll(64位)。

也就是说,64位Windows提供了32位Windows的系统环境,用来运行32位应用程序。并在中途借助WOW64将其变换为64位环境,如图36-1所示。

WOW64仅运行在用户模式下,运行在内核模式中的驱动程序(Driver)文件必须 编译成64位。内核模式中发生内存引用错误时,就会引发BSOD(Blue Screen Of Death,蓝屏死机)问题,所以为了保证系统稳定性,WOW64被限制在用户模式下运行。

文件夹结构

64位Windows的文件夹结构中,开发人员与逆向分析人员都需要明确知道一点,那就是System32文件夹。系统文件夹在64位环境中的名称也为System32,并且为了向下兼容32位,单独 提供了SysWOW64文件夹,如图36-2所示。

System32文件夹中存放着64位的系统文件,而SysWOW64文件夹中则存放着32位的系统文件。向用户提供的重要的系统文件被分别编译成64位与32位(参考图39-3、图39-4 )。

有意思的是,64位应用程序中使用GetSystemDirectory() AW查找系统文件夹,正常返回System32文件夹。32位应用程序中调用GetSystemDirectory()返回的文件夹名称也为System32,但文件夹的实际内容与SysWOW64文件夹是一样的。这是WOW64在中间截获了API调用并进行操作后返回的结果,这使32位应用程序可以正常运行。

像 System32/SysWOW64—样,Program Files 与 Program Files(x86)文件夹并不是直接重定向的对象。32位应用程序中使用SHGetSpecialFolderPath() API获取Program Files文件夹路径时,WOW64会在中间对其截获,并返回Program Files(x86)路径。32位应用程序中,SysWOW64文件夹名称看似被修改成System32,但是Program Files(x86)文件夹会原样显示。

注册表

64位Windows中的注册表分为32位注册表项与64位注册表项,如图36-5所示。

32位进程请求访问HKLM\SOFTWARE下的键时,WOW64会将其重定向到32位的HKLM\SOFTWARE\Wow6432Node下的键。有关注册表重定向的更多内容请参考下面MSDN链接。与文件系统重定向相比,注册表通常显得更加复杂。需要做精确开发与逆向分析的人员,请务必认真阅读下面链接中的内容。

http://msdn.microsoft.com/en-us/library/aa384232(v=VS.85).aspx

与文件系统不同,注册表无法完全分离为32位与64位两部分,经常出现32/64位共用的情形。有时候向32位部分写入的值会自动写入64位部分。所以对运行在WOW64环境中的程序进行逆向分析时,必须准确知道访问的究竟是注册表的哪一部分(32位还是64位)。

36.1.5 练习:WOW64Test

下面准备了一个简单的示例,用来测试WOW64。WOW64Test_x86.exe被编译为32位文件, 在WOW64模式下运行。而WOW64Test_x64.exe被编译为64位文件,运行在64位Native模式下。两个文件的源文件(WOW64Test.cpp )都是一样的0

要正常运行/调试WOW64Test_x64.exe文件,需要Windows XP/Vista/7 64位系统环境支持。

图36-6是分别运行它们得到的结果

运行示例程序可以获取以下4种信息:

“system32” path

File size of “kernel32.dll”

“Program Files” path

Create Registry Key: ”HKLM\SOFTWARE\ReverseCore“

从运行结果画面可以看到,64位WOW64Test_x64.exe从准确位置(与源代码中的内容一样)获取值并生成了注册表键。但是以WOW64模式运行的32位WOW64Test_x86.exe行为略有不同。它虽然把System32文件夹目录识别为“C:\Windows\system32”,但其内容却指向SysWOW64文件夹(从kernel32.dll的文件尺寸即可得知)。还有Program Files目录被返回为“Program Files(x86)”。

创建注册表项时,实际创建的不是HKLM\SOFTWARE\ReverseCore,而是HKLM\SOFTWARE

Wow6432Node\ReverseCore。以WOW64模式运行的32位应用程序会像这样对文件(文件夹)与

注册表进行重定向,请各位一定要注意这点。

在64位Windows环境中逐一运行示例文件,然后利用文件浏览器与注册表编辑器

查看运行结果。

36.2 编译64位文件

本节将向各位介绍编译64位PE文件(PE+或PE32+)的方法。32位与64位Windows OS中都可 以分别交叉编译(Cross Compile ) 32位/64位PE文件。最简单的方法是安装Visual Studio 2012。

Visual Studio 2012 是默认提供64位编译环境的。

36.2.1设置 Visual Studio 2012 环境

  1. 选择“Build” – “Configuration Manager”菜单,打开配置管理器。点击新建解决方案平台。

2.
选择“x64”平台,点击确定按钮。

3.
这时候配置管理器中的平台已经改成刚才选择的x64了,这时候编译出来的就是64位程序了。可以在工具栏的平台下拉框中快速切换目标平台。


第36章 64位计算
https://m0ck1ng-b1rd.github.io/1999/03/06/逆向工程核心原理/第36章 64位计算/
作者
何语灵
发布于
1999年3月6日
许可协议