Mixing x86 with x64 code (混合编写x86和x64代码)

摘要: 几个月前我小小的研究了在WOW64下的32位进程中运行native x64代码。第二个设想是在64位进程下运行x86代码。它们都是可以的,如我google的一样,已经有人在使用这两种方法了:●http://vx.netlux.org/lib/vrg02.html ...

Mixing x86 with x64 code (混合编写x86和x64代码)_第1张图片

几个月前我小小的研究了在WOW64下的32位进程中运行native x64代码。
第二个设想是在64位进程下运行x86代码。它们都是可以的,如我google的一样,已经有人在使用这两种方法了:
●http://vx.netlux.org/lib/vrg02.html
●http://www.corsix.org/content/dll-injection-and-wow64
●http://int0h.wordpress.com/2009/12/24/the-power-of-wow64/
●http://int0h.wordpress.com/2011/02/22/anti-anti-debugging-via-wow64/
当我研究的时候还没有看上面搜索到的结果,所以下面仅仅代表我自己的见解;
x86 <-> x64 Transition(x86和x64之间的转换)
最早来检查x86到x64转换的方法,是观察windows中32位版本和64位版本的ntdll.dll中的任意syscall:

Mixing x86 with x64 code (混合编写x86和x64代码)_第2张图片

正如你所见,在64位系统上新的call fs:[0xC0](wow64cpu!X86SwitchTo64BitMode) 代替了标准call ntdll.KiFastSystemCall.               
wow64cpu!X86SwitchTo64BitMode 执行了一个简单的远跳转到64位的段中了:
wow64cpu!X86SwitchTo64BitMode:
748c2320 jmp     0033:748C271E   ;wow64cpu!CpupReturnFromSimulatedCode
这就是64位Windows系统上转换x64和x86后面的魔术。
此外它也能在非WoW64进程中运行(标准的native 64位应用程序),所以32位代码也能运行在64位应用程序中。
总结一下,运行在64位Windows中的每个进程(x86和x64),都分配了两个代码段:
●cs = 0×23 -> x86 mode
●cs = 0×33 -> x64 mode
Running x64 code inside 32-bits process(在32位进程中运行x64代码)
首先,我准备了一些宏,将用它来标记64位代码的开始和结尾:

Mixing x86 with x64 code (混合编写x86和x64代码)_第3张图片

执行完X64_Start()宏后,CPU直接转换到x64模式,执行完X64_End()宏后立即回到x86模式。
由于远返回的opcode,以上宏都是位置独立的。
能够调用x64版本的APIs是非常有用的。我尝试加载过x64版本的kernel32.dll,它不是一个微不足道的任务,并且我失败了,所以我需要坚持使用Native API。x64版本的kernel32.dll的主要问题是在已经加载x86版本的kernel32.dll的情况下,x64 kernel32.dll有一些额外的检查来阻止正常的加载。我相信通过一些猥琐的hook来拦截kernel32!BaseDllInitialize能达到目的,但是这是非常复杂的任务。当我开始研究的时候,我是在WIndowsVista上,并且我能加载(用一些hacks)64位版本的kernel32和user32库,但是他们没有完整的功能,同时我又转换到Windows7,使用在Vista上的方法不能够正常工作了。
让我们回到主题上,为了使用Native APIs,我需要定位内存中你给的x64版本的ntdll.dll。为了完成这个任务,我需要解析_PEB_LDR_DATA结构中的InLoadOrderModuleLi
-st。64位的_PEB被64位的_TEB包含,并且64位_TEB类似于x86平台的(在x64上我们需要使用gs段代替fs):
mov   eax, gs:[0x30]
它甚至可以更简单,因为 wow64cpu!CpuSimulate(负责转换CPU到x86模式的函数)将gs:[0x30]的值移动到r12寄存器中,所以我们的getTEB64()版本看起来像这样

Mixing x86 with x64 code (混合编写x86和x64代码)_第4张图片

WOW64名字空间定义在“os_structs.h”文件中,随后将会和其他示例代码添加到文章尾部。
负责定位64位ntdll.dll函数定义如下:

Mixing x86 with x64 code (混合编写x86和x64代码)_第5张图片

为了完整支持x64 Native API调用,我们还需要等价于GetProcAddress的函数,通过ntdll!LdrGetProcedureAddress更容易的交流。下面代码负责获取LdrGetProcedureAddress的地址:
为了锦上添花,我将介绍有用的函数,能让我在x86的C/C++代码中直接的调用x64 Native APIs:

Mixing x86 with x64 code (混合编写x86和x64代码)_第6张图片

Mixing x86 with x64 code (混合编写x86和x64代码)_第7张图片

你可能感兴趣的:(Mixing x86 with x64 code (混合编写x86和x64代码))