下面以ntdll32!ZwQueryInformationProcess API为例分析 x86代码与x64代码之间的切换过程,

32bit的test程序:

step1:

ntdll32!ZwQueryInformationProcess:
775bfb18 b816000000      mov     eax,16h
775bfb1d 33c9            xor     ecx,ecx
775bfb1f 8d542404        lea     edx,[esp+4]
775bfb23 64ff15c0000000  call    dword ptr fs:[0C0h]  fs:0053:000000c0=00000000
775bfb2a 83c404          add     esp,4
775bfb2d c21400          ret     14h

在win32系统中 teb保存的是fs:[0]地址,

0:000:x86> dt _teb @$teb

+0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : (null)
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : (null)
   +0x02c ThreadLocalStoragePointer : (null)
   +0x030 ProcessEnvironmentBlock : 0x7efdb000 _PEB
   +0x034 LastErrorValue   : 0
   +0x038 CountOfOwnedCriticalSections : 0
   +0x03c CsrClientThread  : (null)
   +0x040 Win32ThreadInfo  : 0x00001a04 Void
   +0x044 User32Reserved   : [26] 0
   +0x0ac UserReserved     : [5] 0
  +0x0c0 WOW32Reserved    : (null)
   +0x0c4 CurrentLocale    : 0
   +other field

step into 775bfb23:

wow64cpu!X86SwitchTo64BitMode:
74b82320 ea1e27b8743300  jmp     0033:74B8271E

0:000:x86> dd esp
0015f368  775bfb2a 775e7177 ffffffff 00000024
0015f378  0015f384 00000004 00000000 00000000
0015f388  00000000 0015f3a8 775da902 776a2038
0015f398  00000000 00000000 00000000 776a4224
0015f3a8  0015f3c8 775e4e51 776a2038 775e715f
0015f3b8  00000000 00000000 00000000 776a4224
0015f3c8  0015f410 775e4e15 776a4224 00000000
0015f3d8  7efde000 7efde000 775e774d 0015f3c0

栈地址0015f368 保存的是返回地址,该地址是 775bfb23 的 call dword ptr fs:[0C0h] 指令自动压入栈的。

step2:

step into 74b82320 指令:

wow64cpu!CpupReturnFromSimulatedCode:  
00000000`74b8271e 67448b0424      mov     r8d,dword ptr [esp] ds:00000000`0015f368=775bfb2a ;//已切换成64bit mode, 保存x86的返回地址到r8d中。
00000000`74b82723 458985bc000000  mov     dword ptr [r13+0BCh],r8d ; //保存x86的返回地址到内存 [r13+0BCh]中,
00000000`74b8272a 4189a5c8000000  mov     dword ptr [r13+0C8h],esp   //保存x86的esp到内存 [r13+0C8h]中,
00000000`74b82731 498ba42480140000 mov     rsp,qword ptr [r12+1480h]
00000000`74b82739 4983a4248014000000 and   qword ptr [r12+1480h],0
00000000`74b82742 448bda          mov     r11d,edx

wow64cpu!TurboDispatchJumpAddressStart:

00000000`74b82745 41ff24cf        jmp     qword ptr [r15+rcx*8] ds:00000000`74b82450={wow64cpu!TurboDispatchJumpAddressEnd                         00000000`74b82749)}

wow64cpu!TurboDispatchJumpAddressEnd:
00000000`74b82749 4189b5a4000000  mov     dword ptr [r13+0A4h],esi ds:00000000`001cfdc4=776a4224
00000000`74b82750 4189bda0000000  mov     dword ptr [r13+0A0h],edi
00000000`74b82757 41899da8000000  mov     dword ptr [r13+0A8h],ebx
00000000`74b8275e 4189adb8000000  mov     dword ptr [r13+0B8h],ebp
00000000`74b82765 9c              pushfq
00000000`74b82766 5b              pop     rbx
00000000`74b82767 41899dc4000000  mov     dword ptr [r13+0C4h],ebx
00000000`74b8276e 8bc8            mov     ecx,eax
00000000`74b82770 ff150ae9ffff    call    qword ptr [wow64cpu!_imp_Wow64SystemServiceEx (00000000`74b81080)] //调用系统调用
00000000`74b82776 418985b4000000  mov     dword ptr [r13+0B4h],eax
00000000`74b8277d e98ffeffff      jmp     wow64cpu!CpuSimulate+0x61 (00000000`74b82611)

step3:

wow64cpu!CpuSimulate

00000000`74b82611 4183a5d002000001 and     dword ptr [r13+2D0h],1 ds:00000000`001cfff0=00000000
00000000`74b82619 0f84af000000    je      wow64cpu!CpuSimulate+0x11e (00000000`74b826ce)
00000000`74b8261f 410f288570010000 movaps  xmm0,xmmword ptr [r13+170h]
00000000`74b82627 410f288d80010000 movaps  xmm1,xmmword ptr [r13+180h]
00000000`74b8262f 410f289590010000 movaps  xmm2,xmmword ptr [r13+190h]
00000000`74b82637 410f289da0010000 movaps  xmm3,xmmword ptr [r13+1A0h]
00000000`74b8263f 410f28a5b0010000 movaps  xmm4,xmmword ptr [r13+1B0h]
00000000`74b82647 410f28adc0010000 movaps  xmm5,xmmword ptr [r13+1C0h]
00000000`74b8264f 418b8db0000000  mov     ecx,dword ptr [r13+0B0h]
00000000`74b82656 418b95ac000000  mov     edx,dword ptr [r13+0ACh]
00000000`74b8265d 4183a5d0020000fe and     dword ptr [r13+2D0h],0FFFFFFFEh
00000000`74b82665 418bbda0000000  mov     edi,dword ptr [r13+0A0h]
00000000`74b8266c 418bb5a4000000  mov     esi,dword ptr [r13+0A4h]
00000000`74b82673 418b9da8000000  mov     ebx,dword ptr [r13+0A8h]
00000000`74b8267a 418badb8000000  mov     ebp,dword ptr [r13+0B8h]
00000000`74b82681 418b85b4000000  mov     eax,dword ptr [r13+0B4h]
00000000`74b82688 4989a42480140000 mov     qword ptr [r12+1480h],rsp
00000000`74b82690 66c74424082300  mov     word ptr [rsp+8],23h
00000000`74b82697 66c74424202b00  mov     word ptr [rsp+20h],2Bh
00000000`74b8269e 458b85c4000000  mov     r8d,dword ptr [r13+0C4h]
00000000`74b826a5 4181a5c4000000fffeffff and dword ptr [r13+0C4h],0FFFFFEFFh
00000000`74b826b0 4489442410      mov     dword ptr [rsp+10h],r8d
00000000`74b826b5 458b85c8000000  mov     r8d,dword ptr [r13+0C8h]

00000000`74b826bc 4c89442418      mov     qword ptr [rsp+18h],r8
00000000`74b826c1 458b85bc000000  mov     r8d,dword ptr [r13+0BCh]
00000000`74b826c8 4c890424        mov     qword ptr [rsp],r8
00000000`74b826cc 48cf            iretq
00000000`74b826ce 418bbda0000000  mov     edi,dword ptr [r13+0A0h]
00000000`74b826d5 418bb5a4000000  mov     esi,dword ptr [r13+0A4h]
00000000`74b826dc 418b9da8000000  mov     ebx,dword ptr [r13+0A8h]
00000000`74b826e3 418badb8000000  mov     ebp,dword ptr [r13+0B8h]
00000000`74b826ea 418b85b4000000  mov     eax,dword ptr [r13+0B4h]
00000000`74b826f1 4989a42480140000 mov     qword ptr [r12+1480h],rsp
000060000`74b826f9 41c7460423000000 mov     dword ptr [r14+4],23h
00000000`74b82701 41b82b000000    mov     r8d,2Bh
00000000`74b82707 418ed0          mov     ss,r8w
00000000`74b8270a 418ba5c8000000  mov     esp,dword ptr [r13+0C8h] //读取x86的esp
00000000`74b82711 458b8dbc000000  mov     r9d,dword ptr [r13+0BCh] //读取x86的返回地址
00000000`74b82718 45890e          mov     dword ptr [r14],r9d
00000000`74b8271b 41ff2e          jmp     fword ptr [r14] //跳转到x86的返回地址:775bfb2a

step4:

跳转到x86的返回地址,继续执行x86的代码:

ntdll32!ZwQueryInformationProcess:

775bfb2a 83c404          add     esp,4
775bfb2d c21400          ret     14h

【原】wow64 x86/x64 代码切换过程分析的更多相关文章

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

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

  2. 关于.NET编译的目标平台(AnyCPU,x86,x64) (转)

    关于.NET编译的目标平台(AnyCPU,x86,x64)(转) 今天有项目的代码收到客户的反馈,要求所有的EXE工程的目标平台全部指定成x86,而所有DLL工程的目标平台全部指定成AnyCPU . ...

  3. windows7内核分析之x86&x64第二章系统调用

    windows7内核分析之x86&x64第二章系统调用 2.1内核与系统调用 上节讲到进入内核五种方式 其中一种就是 系统调用 syscall/sysenter或者int 2e(在 64 位环 ...

  4. .net下com调用支持x86/x64

    起因 项目涉及u3d/wpf端的渲染图形合成,采用了开源项目spout,为了便捷,采用了spout的com版本作为c#端的调用 项目调整后,细节已经捋清楚了. 但是考虑桌面应用采用anypc,根据运行 ...

  5. 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别

    相信对于很多刚接触打包程序的同志来说,关于x86,x64,Any CPU这三个项目平台,以及解决方案配置Debug和Release有什么区别?这个问题一定有许多的困惑,甚至不乏一些已经工作了很久的老程 ...

  6. 『开源重编译』System.Data.SQLite.dll 自适应 x86 x64 AnyCPU 重编译

    背景: > System.Data.SQLite.dll 程序集 不能良好的支持 AngCPU 格式 System.Data.SQLite.dll 在 适应 x86 和 x64 有三个方案: & ...

  7. js原生带缩略图的图片切换效果

    js原生带缩略图的图片切换效果 本例中用到的 moveElement(elementID,final_x,final_y,interval)是来自<JavaScript DOM编程艺术(中文第二 ...

  8. The Boot Process at a Glance x86/x64系统启动过程解析

    哥又来干体力活了.人肉翻译一下: The Boot Process at a Glance This section explains the boot process in sufficient d ...

  9. KingbaseES V8R3集群运维案例之---主库系统down failover切换过程分析

    ​ 案例说明: KingbaseES V8R3集群failover时两个cluster都会触发,但只有一个cluster会调用脚本去执行真正的切换流程,另一个有对应的打印,但不会调用脚本,只是走相关的 ...

随机推荐

  1. 加拿大大学排名 by USNews

    https://www.usnews.com/education/best-global-universities/canada 2017综合排名: CS Subject:

  2. Windows下 训练Tesseract实现识别图片中的文字

    介绍 Tesseract是一个基于Apache2.0协议开源的跨平台ocr引擎,支持多种语言的识别,在Windows和Linux上都有良好的支持. 源代码在这: 源码地址 有一个编译打包好的Windo ...

  3. DateTimepicker中的星期问题

    开发机:win10 64+VS2013 客户机:win7 32bit 在项目中使用DateTimepicker,需要将时间获取到,然后转换为string,然后再转换为DateTime类型.开发机器上测 ...

  4. python数据类型总结

    按存值个数区分 标量/原子类型 数字,字符串 容器类型 列表,元组,字典 按可变不可变区分 可变 列表,字典 不可变 数字,字符串,元组 按访问顺序区分 直接访问 数字 顺序访问(序列类型) 字符串, ...

  5. 对KVM虚拟机进行cpu pinning配置的方法

    这篇文章主要介绍了对KVM虚拟机进行cpu pinning配置的方法,通过文中的各种virsh命令可进行操作,需要的朋友可以参考下 首先需求了解基本的信息 1 宿主机CPU特性查看 使用virsh n ...

  6. 匿名内部类中不能修改int变量时、final int i 不能改变i的值时、或 i++线程不安全。使用AtomicInteger;

    在匿名内部类或某某情况下中引入的变量必须是Final最终型的:这时还想要去修改这个变量就需要使用到AtomicInteger这个类了: AtomicInteger CarSize = new Atom ...

  7. Fragment与Radiogroup联动,经典的主界面布局。使用show和hide的方式实现;

    Fragment+RadioGroup经典的主界面布局,方便实用: 1.使用replace方式: 直接上代码,先是布局文件: <?xml version="1.0" enco ...

  8. c# Color 颜色设置

    #region 笔刷颜色 public SolidColorBrush col(byte a, byte r, byte g, byte b) { #region 颜色说明 //Color.FromA ...

  9. 5种分布式共享session的方法

    集群/分布式环境下5种session处理策略 转载 2016年03月16日 08:59:53 标签: session / nginx / 分布式 / 集群 11098 转载自:http://blog. ...

  10. python-多线程和线程池

    import threading # 点击查看它的用法 传统多线程方案会使用“即时创建, 即时销毁”的策略. from multiprocessing.dummy import Pool # 线程池 ...