请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

梦织未来

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 822|回复: 17

[原创]用户层x86切换x64原理(WOW64子系统原理)

[复制链接]

升级   100%

216

主题

64

精华

1432

积分
发表于 2016-10-5 20:02:00 | 显示全部楼层 |阅读模式
梦织未来(www.mengwuji.net)

作者:mengwuji

小伙伴们国庆玩的好吗?我是糟糕透啦!下面的内容奉献给论坛的默默支持者们。

大家都知道32位程序可以运行在64位系统上,处理器是支持64位模式中兼容运行32位指令的。在32位系统中,用户层api调用切换进内核的时候,一般是通过syscall指令进入的。那么64位系统呢,好像有点儿问题,我们下面举个例子介绍下。
1,假如我现在写了一个64位的程序,调用了ntdll中的ZwCreateFile函数创建一个文件。这个流程会和32位系统中流程一样,也是直接通过(注意我说的直接是表示没做多余的事情)syscall指令进入内核做一些具体操作。
2,假如我现在写了一个32位的程序,调用了ntdll中的ZwCreateFile函数创建一个文件。这个流程就不能简单的直接进入内核去做相关的操作了,因为会遇到一个坑爹的问题(实际会有好几个坑爹的问题),这个问题需要我们来看看ZwCreateFile函数的参数。

  1. NTSTATUS
  2. NTAPI
  3. ZwCreateFile (
  4.     __out PHANDLE FileHandle,
  5.     __in ACCESS_MASK DesiredAccess,
  6.     __in POBJECT_ATTRIBUTES ObjectAttributes,
  7.     __out PIO_STATUS_BLOCK IoStatusBlock,
  8.     __in_opt PLARGE_INTEGER AllocationSize,
  9.     __in ULONG FileAttributes,
  10.     __in ULONG ShareAccess,
  11.     __in ULONG CreateDisposition,
  12.     __in ULONG CreateOptions,
  13.     __in_bcount_opt(EaLength) PVOID EaBuffer,
  14.     __in ULONG EaLength
  15.     );

复制代码

这是我们调用的ZwCreateFile函数,我们注意下ObjectAttributes参数,ObjectAttributes参数是OBJECT_ATTRIBUTES结构指针,这个结构在32位程序里大小是0x18。当我们调用进入内核后,内核中同样有个NtCreateFile函数和用户层的ZwCreateFile对应,参数也是一模一样的。那么我们进行双机调试查看内核NtCreateFile的处理的时候,发现64位系统内核中ObjectAttributes参数指向的数据块大小(也就是OBJECT_ATTRIBUTES结构尺寸大小)是0x30了,指针所指向的结构体尺寸变大了,为什么呢?
我们来看看32位模式下OBJECT_ATTRIBUTES结构的定义:

  1.           typedef struct _OBJECT_ATTRIBUTES          // 6 elements, 0x18 bytes (sizeof)
  2.           {                                                                             
  3. /*0x000*/     ULONG32      Length;                                                      
  4. /*0x004*/     VOID*        RootDirectory;                                               
  5. /*0x008*/     struct _UNICODE_STRING* ObjectName;                                       
  6. /*0x00C*/     ULONG32      Attributes;                                                  
  7. /*0x010*/     VOID*        SecurityDescriptor;                                          
  8. /*0x014*/     VOID*        SecurityQualityOfService;                                    
  9.           }OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

复制代码

下面是64位模式下OBJECT_ATTRIBUTES的定义:

  1.           typedef struct _OBJECT_ATTRIBUTES          // 6 elements, 0x30 bytes (sizeof)
  2.           {                                                                             
  3. /*0x000*/     ULONG32      Length;                                                      
  4. /*0x004*/     UINT8        _PADDING0_[0x4];                                             
  5. /*0x008*/     VOID*        RootDirectory;                                               
  6. /*0x010*/     struct _UNICODE_STRING* ObjectName;                                       
  7. /*0x018*/     ULONG32      Attributes;                                                  
  8. /*0x01C*/     UINT8        _PADDING1_[0x4];                                             
  9. /*0x020*/     VOID*        SecurityDescriptor;                                          
  10. /*0x028*/     VOID*        SecurityQualityOfService;                                    
  11.           }OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;                                      

复制代码


在上面可以看出结构中的指针类型成员在32位定义中是4字节,而在64位定义中是8字节了,可以说这种结构成员扩展就是导致32位参数和64位参数大小不一致的原因。
那么如果我们直接把32位下的ObjectAttributes参数传递到内核中,内核在处理该参数的时候实际处理的是一个畸形参数,不符合64位OBJECT_ATTRIBUTES结构的定义,就会产生问题了。怎么解决这个问题呢?
微软要保证32位程序能顺利在64位系统中运行,应对诸如上面这类问题,开发了一个WOW64子系统作为中间的转换层,把32位程序提供的参数变成内核中需要的模样,同时把内核返回的数据变成32位程序想看到的模样。

WOW64子系统是在用户层实现的,我们现在利用windbg看看ZwCreateFile怎么进入内核的,就知道WOW64子系统的大致实现原理了。下面看看32位模式ZwCreateFile的汇编代码:

  1. ntdll_77dd0000!NtCreateFile:
  2. 77df00c4 b852000000      mov     eax,52h
  3. 77df00c9 33c9            xor     ecx,ecx
  4. 77df00cb 8d542404        lea     edx,[esp+4]
  5. 77df00cf 64ff15c0000000  call    dword ptr fs:[0C0h]
  6. 77df00d6 83c404          add     esp,4
  7. 77df00d9 c22c00          ret     2Ch

复制代码


其中是eax是功能号,edx指向了第一个参数地址。这里call fs:[0C0h]就是准备切换到WOW64子系统中了。fs指向的是当前线程的teb,+0xc0处保存了一个函数地址,这个函数的汇编代码如下:

  1. 0:000:x86> u poi(fs:[0xc0])
  2. wow64cpu!CpuSuspendLocalThread+0x8a8:
  3. 75652320 ea1e2765753300  jmp     0033:7565271E
  4. 75652327 0000            add     byte ptr [eax],al
  5. 75652329 cc              int     3
  6. 7565232a cc              int     3

复制代码


这个函数在符号表里是没有的,不知道是不是微软故意隐藏了,不过没关系,我们不用知道它的名字。我们可以看到它内部就是个跨段跳转指令,我们当前的段cs=0x23,经过了这个跨段跳转指令后,我们会进入64位模式下,所以小伙伴们准备好擦亮眼睛吧!

0x7565271E函数在wow64cpu.dll模块中,我们看看汇编代码:

  1. 00000000`7565271e 67448b0424      mov     r8d,dword ptr [esp]
  2. 00000000`75652723 458985bc000000  mov     dword ptr [r13+0BCh],r8d
  3. 00000000`7565272a 4189a5c8000000  mov     dword ptr [r13+0C8h],esp
  4. 00000000`75652731 498ba42480140000 mov     rsp,qword ptr [r12+1480h]
  5. 00000000`75652739 4983a4248014000000 and   qword ptr [r12+1480h],0
  6. 00000000`75652742 448bda          mov     r11d,edx
  7. wow64cpu!TurboDispatchJumpAddressStart:
  8. 00000000`75652745 41ff24cf        jmp     qword ptr [r15+rcx*8]

复制代码


转到x64模式下后,r13指向的是一个结构体,这个结构体大概如下:

  1. typedef struct _WOW64_CONTEXT{
  2. ULONG Unk1;          //+0x0
  3. CONTEXT context;       //+0x4
  4. ...
  5. }WOW64_CONTEXT,*PWOW64_CONTEXT;
复制代码

上面结构中CONTEXT的定义如下:

  1.           typedef struct _CONTEXT                   // 25 elements, 0x2CC bytes (sizeof)
  2.           {                                                                              
  3. /*0x000*/     ULONG32      ContextFlags;                                                
  4. /*0x004*/     ULONG32      Dr0;                                                         
  5. /*0x008*/     ULONG32      Dr1;                                                         
  6. /*0x00C*/     ULONG32      Dr2;                                                         
  7. /*0x010*/     ULONG32      Dr3;                                                         
  8. /*0x014*/     ULONG32      Dr6;                                                         
  9. /*0x018*/     ULONG32      Dr7;                                                         
  10. /*0x01C*/     struct _FLOATING_SAVE_AREA FloatSave; // 9 elements, 0x70 bytes (sizeof)   
  11. /*0x08C*/     ULONG32      SegGs;                                                        
  12. /*0x090*/     ULONG32      SegFs;                                                        
  13. /*0x094*/     ULONG32      SegEs;                                                        
  14. /*0x098*/     ULONG32      SegDs;                                                        
  15. /*0x09C*/     ULONG32      Edi;                                                         
  16. /*0x0A0*/     ULONG32      Esi;                                                         
  17. /*0x0A4*/     ULONG32      Ebx;                                                         
  18. /*0x0A8*/     ULONG32      Edx;                                                         
  19. /*0x0AC*/     ULONG32      Ecx;                                                         
  20. /*0x0B0*/     ULONG32      Eax;                                                         
  21. /*0x0B4*/     ULONG32      Ebp;                                                         
  22. /*0x0B8*/     ULONG32      Eip;                                                         
  23. /*0x0BC*/     ULONG32      SegCs;                                                        
  24. /*0x0C0*/     ULONG32      EFlags;                                                      
  25. /*0x0C4*/     ULONG32      Esp;                                                         
  26. /*0x0C8*/     ULONG32      SegSs;                                                        
  27. /*0x0CC*/     UINT8        ExtendedRegisters[512];                                       
  28.           }CONTEXT, *PCONTEXT;

复制代码


0x7565271E开头几条指令是保存eip和esp给r13->context.Eip和r13->context.Esp。
后面的r12是指向的当前线程64位的teb,可以看出进入wow64后,rsp是从64位teb的+0x1480处取值的,说明线程建立的时候,已经初始化了wow64模式下的堆栈,并且栈顶保存在了线程64位teb中,每次切换进wow64就从中取值然后赋值给rsp。那么一个32位程序的线程在运行的时候就涉及到三个栈了:
1,32位线程的用户栈。
2,32位线程在wow64子系统中的栈。
3,32位线程在内核中的内核栈。

我们接着往下看,jmp qword ptr [r15+rcx*8]指令会跳到TurboDispatchJumpAddressEnd函数,我下面在汇编中解释指令意义:

  1. wow64cpu!TurboDispatchJumpAddressEnd:
  2. 00000000`75652749 4189b5a4000000  mov     dword ptr [r13+0A4h],esi
  3. 00000000`75652750 4189bda0000000  mov     dword ptr [r13+0A0h],edi
  4. 00000000`75652757 41899da8000000  mov     dword ptr [r13+0A8h],ebx
  5. 00000000`7565275e 4189adb8000000  mov     dword ptr [r13+0B8h],ebp
  6. 00000000`75652765 9c              pushfq
  7. 00000000`75652766 5b              pop     rbx
  8. 00000000`75652767 41899dc4000000  mov     dword ptr [r13+0C4h],ebx  ;上面都是保存寄存器到r13->context结构中。
  9. 00000000`7565276e 8bc8            mov     ecx,eax          ;ZwCreateFile的功能号
  10. 00000000`75652770 ff150ae9ffff    call    qword ptr [wow64cpu+0x1080 (00000000`75651080)] ;调用的是wow64!Wow64SystemServiceEx函数,这个函数和KiSystemCall64很像,下面我们重点介绍。
  11. 00000000`75652776 418985b4000000  mov     dword ptr [r13+0B4h],eax   ;得到函数执行的返回值
  12. 00000000`7565277d e98ffeffff      jmp     wow64cpu!CpuSimulate+0x61 (00000000`75652611) ;准备退出吧

复制代码


上面保存了context后开始调用wow64!Wow64SystemServiceEx进行参数扩展等操作了,我们看汇编代码:

  1. 0:000> uf wow64!Wow64SystemServiceEx
  2. wow64!Wow64SystemServiceEx:
  3. 00000000`756cd0b8 4c8bdc          mov     r11,rsp
  4. 00000000`756cd0bb 49895b18        mov     qword ptr [r11+18h],rbx
  5. 00000000`756cd0bf 56              push    rsi
  6. 00000000`756cd0c0 57              push    rdi
  7. 00000000`756cd0c1 4154            push    r12
  8. 00000000`756cd0c3 4881eca0080000  sub     rsp,8A0h
  9. 00000000`756cd0ca 488b052fc00200  mov     rax,qword ptr [wow64!Wow64PrepareForException+0xac60 (00000000`756f9100)]
  10. 00000000`756cd0d1 4833c4          xor     rax,rsp
  11. 00000000`756cd0d4 4889842490080000 mov     qword ptr [rsp+890h],rax
  12. 00000000`756cd0dc 488bda          mov     rbx,rdx               ;参数表指针
  13. 00000000`756cd0df 448bc1          mov     r8d,ecx               ;函数功能号
  14. 00000000`756cd0e2 8bd1            mov     edx,ecx
  15. 00000000`756cd0e4 c1ea0c          shr     edx,0Ch
  16. 00000000`756cd0e7 83e203          and     edx,3                ;上面的操作就是确定需要在ssdt中查表还是shadow ssdt中查表,注意这里的不是内核的ssdt或者shadow ssdt,而是wow64子系统的ssdt和shadow ssdt ><
  17. 00000000`756cd0ea 4181e0ff0f0000  and     r8d,0FFFh
  18. 00000000`756cd0f1 4c8d0c52        lea     r9,[rdx+rdx*2]
  19. 00000000`756cd0f5 4d03c9          add     r9,r9
  20. 00000000`756cd0f8 4c8d1501d90200  lea     r10,[wow64!Wow64PrepareForException+0xc560 (00000000`756faa00)]
  21. 00000000`756cd0ff 473b44ca10      cmp     r8d,dword ptr [r10+r9*8+10h]  ;看功能号超出额定范围没,超过了就出问题啦,就退出啦~~
  22. 00000000`756cd104 0f873f010000    ja      wow64!Wow64SystemServiceEx+0x191 (00000000`756cd249)

  23. wow64!Wow64SystemServiceEx+0x52:
  24. 00000000`756cd10a 65488b342530000000 mov   rsi,qword ptr gs:[30h]        ;rsi = teb
  25. 00000000`756cd113 4889742438      mov     qword ptr [rsp+38h],rsi
  26. 00000000`756cd118 65488b3c2530000000 mov   rdi,qword ptr gs:[30h]        ;rdi = teb
  27. 00000000`756cd121 4881c700200000  add     rdi,2000h
  28. 00000000`756cd128 48897c2430      mov     qword ptr [rsp+30h],rdi
  29. 00000000`756cd12d 488b8698140000  mov     rax,qword ptr [rsi+1498h]
  30. 00000000`756cd134 4889442470      mov     qword ptr [rsp+70h],rax
  31. 00000000`756cd139 488d442478      lea     rax,[rsp+78h]
  32. 00000000`756cd13e 498983c8f7ffff  mov     qword ptr [r11-838h],rax
  33. 00000000`756cd145 488d442478      lea     rax,[rsp+78h]
  34. 00000000`756cd14a 4889442478      mov     qword ptr [rsp+78h],rax
  35. 00000000`756cd14f 498d43d8        lea     rax,[r11-28h]
  36. 00000000`756cd153 498983d0f7ffff  mov     qword ptr [r11-830h],rax
  37. 00000000`756cd15a 488d442470      lea     rax,[rsp+70h]
  38. 00000000`756cd15f 48898698140000  mov     qword ptr [rsi+1498h],rax
  39. 00000000`756cd166 4b8b04ca        mov     rax,qword ptr [r10+r9*8]    ;这里得到服务函数表(wow64的ssdt或者shadow ssdt)
  40. 00000000`756cd16a 4e8b24c0        mov     r12,qword ptr [rax+r8*8]    ;然后在服务表中得到功能号对应的函数地址
  41. 00000000`756cd16e 89542450        mov     dword ptr [rsp+50h],edx
  42. 00000000`756cd172 4489442454      mov     dword ptr [rsp+54h],r8d
  43. 00000000`756cd177 8b4734          mov     eax,dword ptr [rdi+34h]
  44. 00000000`756cd17a 894668          mov     dword ptr [rsi+68h],eax
  45. 00000000`756cd17d 488b0534de0200  mov     rax,qword ptr [wow64!Wow64PrepareForException+0xcb18 (00000000`756fafb8)]
  46. 00000000`756cd184 4885c0          test    rax,rax               ;上面得到的rax指向一个函数,可以为null,应该是做系统性能统计之类的.
  47. 00000000`756cd187 750e            jne     wow64!Wow64SystemServiceEx+0xdf (00000000`756cd197)

  48. wow64!Wow64SystemServiceEx+0xd1:
  49. 00000000`756cd189 488bcb          mov     rcx,rbx                ;rcx = 参数表指针
  50. 00000000`756cd18c 41ffd4          call    r12                  ;这里调用wow64服务表中的函数
  51. 00000000`756cd18f 8bd8            mov     ebx,eax
  52. 00000000`756cd191 89442420        mov     dword ptr [rsp+20h],eax     ;保存返回值
  53. 00000000`756cd195 eb31            jmp     wow64!Wow64SystemServiceEx+0x110 (00000000`756cd1c8)

  54. wow64!Wow64SystemServiceEx+0xdf:
  55. 00000000`756cd197 48895c2448      mov     qword ptr [rsp+48h],rbx
  56. 00000000`756cd19c c644245c00      mov     byte ptr [rsp+5Ch],0
  57. 00000000`756cd1a1 488d4c2440      lea     rcx,[rsp+40h]
  58. 00000000`756cd1a6 ffd0            call    rax
  59. 00000000`756cd1a8 488bcb          mov     rcx,rbx
  60. 00000000`756cd1ab 41ffd4          call    r12
  61. 00000000`756cd1ae 8bd8            mov     ebx,eax
  62. 00000000`756cd1b0 89442420        mov     dword ptr [rsp+20h],eax
  63. 00000000`756cd1b4 c644245c01      mov     byte ptr [rsp+5Ch],1
  64. 00000000`756cd1b9 89442458        mov     dword ptr [rsp+58h],eax
  65. 00000000`756cd1bd 488d4c2440      lea     rcx,[rsp+40h]
  66. 00000000`756cd1c2 ff15f0dd0200    call    qword ptr [wow64!Wow64PrepareForException+0xcb18 (00000000`756fafb8)]

  67. wow64!Wow64SystemServiceEx+0x110:
  68. 00000000`756cd1c8 eb1c            jmp     wow64!Wow64SystemServiceEx+0x12e (00000000`756cd1e6)

  69. wow64!Wow64SystemServiceEx+0x12e:
  70. 00000000`756cd1e6 8b4668          mov     eax,dword ptr [rsi+68h]
  71. 00000000`756cd1e9 894734          mov     dword ptr [rdi+34h],eax
  72. 00000000`756cd1ec 4c8ba698140000  mov     r12,qword ptr [rsi+1498h]
  73. 00000000`756cd1f3 498d7c2408      lea     rdi,[r12+8]
  74. 00000000`756cd1f8 488b17          mov     rdx,qword ptr [rdi]
  75. 00000000`756cd1fb 488b02          mov     rax,qword ptr [rdx]
  76. 00000000`756cd1fe 488907          mov     qword ptr [rdi],rax
  77. 00000000`756cd201 48897808        mov     qword ptr [rax+8],rdi
  78. 00000000`756cd205 483bd7          cmp     rdx,rdi
  79. 00000000`756cd208 7432            je      wow64!Wow64SystemServiceEx+0x184 (00000000`756cd23c)

  80. wow64!Wow64SystemServiceEx+0x152:
  81. 00000000`756cd20a 65488b042530000000 mov   rax,qword ptr gs:[30h]
  82. 00000000`756cd213 488b4860        mov     rcx,qword ptr [rax+60h]
  83. 00000000`756cd217 4c8bc2          mov     r8,rdx
  84. 00000000`756cd21a 33d2            xor     edx,edx
  85. 00000000`756cd21c 488b4930        mov     rcx,qword ptr [rcx+30h]
  86. 00000000`756cd220 ff15ca3effff    call    qword ptr [wow64+0x10f0 (00000000`756c10f0)]
  87. 00000000`756cd226 488b17          mov     rdx,qword ptr [rdi]
  88. 00000000`756cd229 488b02          mov     rax,qword ptr [rdx]
  89. 00000000`756cd22c 488907          mov     qword ptr [rdi],rax
  90. 00000000`756cd22f 48897808        mov     qword ptr [rax+8],rdi
  91. 00000000`756cd233 483bd7          cmp     rdx,rdi
  92. 00000000`756cd236 75d2            jne     wow64!Wow64SystemServiceEx+0x152 (00000000`756cd20a)

  93. wow64!Wow64SystemServiceEx+0x180:
  94. 00000000`756cd238 8b5c2420        mov     ebx,dword ptr [rsp+20h]

  95. wow64!Wow64SystemServiceEx+0x184:
  96. 00000000`756cd23c 498b0424        mov     rax,qword ptr [r12]
  97. 00000000`756cd240 48898698140000  mov     qword ptr [rsi+1498h],rax
  98. 00000000`756cd247 eb05            jmp     wow64!Wow64SystemServiceEx+0x196 (00000000`756cd24e)

  99. wow64!Wow64SystemServiceEx+0x191:
  100. 00000000`756cd249 bb1c0000c0      mov     ebx,0C000001Ch

  101. wow64!Wow64SystemServiceEx+0x196:
  102. 00000000`756cd24e 8bc3            mov     eax,ebx
  103. 00000000`756cd250 488b8c2490080000 mov     rcx,qword ptr [rsp+890h]
  104. 00000000`756cd258 4833cc          xor     rcx,rsp
  105. 00000000`756cd25b e8600e0200      call    wow64!Wow64EmulateAtlThunk+0x20558 (00000000`756ee0c0)
  106. 00000000`756cd260 488b9c24d0080000 mov     rbx,qword ptr [rsp+8D0h]
  107. 00000000`756cd268 4881c4a0080000  add     rsp,8A0h
  108. 00000000`756cd26f 415c            pop     r12
  109. 00000000`756cd271 5f              pop     rdi
  110. 00000000`756cd272 5e              pop     rsi
  111. 00000000`756cd273 c3              ret

复制代码


Wow64SystemServiceEx函数主要是根据功能号进行查表,找到对应的wow64服务函数地址,然后调用,我们这里拿的是ZwCreateFile做例子,我们看看对应调用的函数是怎样的。

  1. 0:000> uf 00000000`756dc0f0
  2. wow64!Wow64EmulateAtlThunk+0xe588:
  3. 00000000`756dc0f0 4053            push    rbx
  4. 00000000`756dc0f2 56              push    rsi
  5. 00000000`756dc0f3 57              push    rdi
  6. 00000000`756dc0f4 4154            push    r12
  7. 00000000`756dc0f6 4155            push    r13
  8. 00000000`756dc0f8 4156            push    r14
  9. 00000000`756dc0fa 4157            push    r15
  10. 00000000`756dc0fc 4881ec90000000  sub     rsp,90h
  11. 00000000`756dc103 4889642478      mov     qword ptr [rsp+78h],rsp
  12. 00000000`756dc108 8b31            mov     esi,dword ptr [rcx]
  13. 00000000`756dc10a 448b6904        mov     r13d,dword ptr [rcx+4]
  14. 00000000`756dc10e 8b590c          mov     ebx,dword ptr [rcx+0Ch]
  15. 00000000`756dc111 448b7110        mov     r14d,dword ptr [rcx+10h]
  16. 00000000`756dc115 448b7914        mov     r15d,dword ptr [rcx+14h]
  17. 00000000`756dc119 8b4118          mov     eax,dword ptr [rcx+18h]
  18. 00000000`756dc11c 89442464        mov     dword ptr [rsp+64h],eax
  19. 00000000`756dc120 8b411c          mov     eax,dword ptr [rcx+1Ch]
  20. 00000000`756dc123 89442460        mov     dword ptr [rsp+60h],eax
  21. 00000000`756dc127 8b4120          mov     eax,dword ptr [rcx+20h]
  22. 00000000`756dc12a 898424e8000000  mov     dword ptr [rsp+0E8h],eax
  23. 00000000`756dc131 8b4124          mov     eax,dword ptr [rcx+24h]
  24. 00000000`756dc134 898424d8000000  mov     dword ptr [rsp+0D8h],eax
  25. 00000000`756dc13b 8b4128          mov     eax,dword ptr [rcx+28h]    ;上面的操作是从参数表中取出各个参数
  26. 00000000`756dc13e 898424e0000000  mov     dword ptr [rsp+0E0h],eax
  27. 00000000`756dc145 488364246800    and     qword ptr [rsp+68h],0
  28. 00000000`756dc14b 8bc6            mov     eax,esi
  29. 00000000`756dc14d f7d8            neg     eax
  30. 00000000`756dc14f 4d1be4          sbb     r12,r12
  31. 00000000`756dc152 488d442468      lea     rax,[rsp+68h]
  32. 00000000`756dc157 4c23e0          and     r12,rax
  33. 00000000`756dc15a 8b4908          mov     ecx,dword ptr [rcx+8]     ;取出ObjectAttributes参数
  34. 00000000`756dc15d 488d542470      lea     rdx,[rsp+70h]            ;返回扩展后64位的ObjectAttributes参数指针
  35. 00000000`756dc162 e86deffeff      call    wow64!Wow64ShallowThunkAllocObjectAttributes32TO64_FNC (00000000`756cb0d4)  ;进行扩展吧~~ 有兴趣的小伙伴可以自己看看这个函数是怎么扩展参数的
  36. 00000000`756dc167 898424d0000000  mov     dword ptr [rsp+0D0h],eax
  37. 00000000`756dc16e 85c0            test    eax,eax             ;判断出问题没,出问题的话就进入错误处理吧 然后返回了
  38. 00000000`756dc170 791d            jns     wow64!Wow64EmulateAtlThunk+0xe627 (00000000`756dc18f)

  39. wow64!Wow64EmulateAtlThunk+0xe60a:
  40. 00000000`756dc172 488d150a000000  lea     rdx,[wow64!Wow64EmulateAtlThunk+0xe61b (00000000`756dc183)]
  41. 00000000`756dc179 488bcc          mov     rcx,rsp
  42. 00000000`756dc17c e8e9220100      call    wow64!Wow64EmulateAtlThunk+0x20902 (00000000`756ee46a)
  43. 00000000`756dc181 90              nop
  44. 00000000`756dc182 90              nop
  45. 00000000`756dc183 8b8424d0000000  mov     eax,dword ptr [rsp+0D0h]
  46. 00000000`756dc18a e999000000      jmp     wow64!Wow64EmulateAtlThunk+0xe6c0 (00000000`756dc228)

  47. wow64!Wow64EmulateAtlThunk+0xe627:
  48. 00000000`756dc18f 48899c24d0000000 mov     qword ptr [rsp+0D0h],rbx
  49. 00000000`756dc197 4885db          test    rbx,rbx             ;看IoStatusBlock参数是否为null 因为这个参数是输出的,不为null的话我们就用wow64栈上的空间,在功能执行完成后重新复制到提供的IoStatusBlock中
  50. 00000000`756dc19a 7411            je      wow64!Wow64EmulateAtlThunk+0xe645 (00000000`756dc1ad)

  51. wow64!Wow64EmulateAtlThunk+0xe634:
  52. 00000000`756dc19c 488dbc2480000000 lea     rdi,[rsp+80h]
  53. 00000000`756dc1a4 899c2480000000  mov     dword ptr [rsp+80h],ebx
  54. 00000000`756dc1ab eb02            jmp     wow64!Wow64EmulateAtlThunk+0xe647 (00000000`756dc1af)

  55. wow64!Wow64EmulateAtlThunk+0xe645:
  56. 00000000`756dc1ad 33ff            xor     edi,edi

  57. wow64!Wow64EmulateAtlThunk+0xe647:
  58. 00000000`756dc1af 8b8424d8000000  mov     eax,dword ptr [rsp+0D8h]
  59. 00000000`756dc1b6 8b9424e0000000  mov     edx,dword ptr [rsp+0E0h]
  60. 00000000`756dc1bd 89542450        mov     dword ptr [rsp+50h],edx
  61. 00000000`756dc1c1 4889442448      mov     qword ptr [rsp+48h],rax
  62. 00000000`756dc1c6 8b8424e8000000  mov     eax,dword ptr [rsp+0E8h]
  63. 00000000`756dc1cd 89442440        mov     dword ptr [rsp+40h],eax
  64. 00000000`756dc1d1 8b442460        mov     eax,dword ptr [rsp+60h]
  65. 00000000`756dc1d5 89442438        mov     dword ptr [rsp+38h],eax
  66. 00000000`756dc1d9 8b442464        mov     eax,dword ptr [rsp+64h]
  67. 00000000`756dc1dd 89442430        mov     dword ptr [rsp+30h],eax
  68. 00000000`756dc1e1 44897c2428      mov     dword ptr [rsp+28h],r15d
  69. 00000000`756dc1e6 4c89742420      mov     qword ptr [rsp+20h],r14
  70. 00000000`756dc1eb 4c8bcf          mov     r9,rdi
  71. 00000000`756dc1ee 4c8b442470      mov     r8,qword ptr [rsp+70h]
  72. 00000000`756dc1f3 418bd5          mov     edx,r13d
  73. 00000000`756dc1f6 498bcc          mov     rcx,r12           ;上面是传递参数
  74. 00000000`756dc1f9 ff154958feff    call    qword ptr [wow64+0x1a48 (00000000`756c1a48)]    这里调用的是ntdll.ZwCreateFile ,这个ZwCreateFile内部就调用syscall进入内核了,代码很简单我不在下面列举了。
  75. 00000000`756dc1ff 448bd8          mov     r11d,eax
  76. 00000000`756dc202 85f6            test    esi,esi
  77. 00000000`756dc204 7406            je      wow64!Wow64EmulateAtlThunk+0xe6a4 (00000000`756dc20c)

  78. wow64!Wow64EmulateAtlThunk+0xe69e:
  79. 00000000`756dc206 418b0c24        mov     ecx,dword ptr [r12]
  80. 00000000`756dc20a 890e            mov     dword ptr [rsi],ecx

  81. wow64!Wow64EmulateAtlThunk+0xe6a4:
  82. 00000000`756dc20c 4885ff          test    rdi,rdi
  83. 00000000`756dc20f 740e            je      wow64!Wow64EmulateAtlThunk+0xe6b7 (00000000`756dc21f)

  84. wow64!Wow64EmulateAtlThunk+0xe6a9:
  85. 00000000`756dc211 8b0f            mov     ecx,dword ptr [rdi]
  86. 00000000`756dc213 3bcb            cmp     ecx,ebx
  87. 00000000`756dc215 7408            je      wow64!Wow64EmulateAtlThunk+0xe6b7 (00000000`756dc21f)

  88. wow64!Wow64EmulateAtlThunk+0xe6af:
  89. 00000000`756dc217 890b            mov     dword ptr [rbx],ecx
  90. 00000000`756dc219 8b4708          mov     eax,dword ptr [rdi+8]
  91. 00000000`756dc21c 894304          mov     dword ptr [rbx+4],eax

  92. wow64!Wow64EmulateAtlThunk+0xe6b7:
  93. 00000000`756dc21f 488364246800    and     qword ptr [rsp+68h],0
  94. 00000000`756dc225 418bc3          mov     eax,r11d

  95. wow64!Wow64EmulateAtlThunk+0xe6c0:
  96. 00000000`756dc228 4881c490000000  add     rsp,90h
  97. 00000000`756dc22f 415f            pop     r15
  98. 00000000`756dc231 415e            pop     r14
  99. 00000000`756dc233 415d            pop     r13
  100. 00000000`756dc235 415c            pop     r12
  101. 00000000`756dc237 5f              pop     rdi
  102. 00000000`756dc238 5e              pop     rsi
  103. 00000000`756dc239 5b              pop     rbx
  104. 00000000`756dc23a c3              ret

复制代码


上面756dc0f0函数操作都很简单,就是得到各个参数后,把一些参数做扩展后调用最终的ntdll.ZwCreateFile进入内核了。
通过这个流程我们基本看明白了wow64子系统是咋回事儿了,我们可以在这个层上面做一些手脚比如hook wow64的ssdt或者shadow ssdt会不会很有意思呢~

本来还有一些地方要说说的,但是我想吃饭啦,下次再分享吧亲爱的小伙伴们~~
回复

使用道具 举报

升级   100%

216

主题

64

精华

1432

积分
 楼主| 发表于 2016-10-5 20:04:08 | 显示全部楼层
自己顶下,我发现写到后面怎么越来越不想写呢!

哎呀真是懒吖,毁了哎~
回复 支持 反对

使用道具 举报

升级   4%

0

主题

0

精华

2

积分
发表于 2016-10-5 20:16:39 | 显示全部楼层
回复 支持 反对

使用道具 举报

升级   98%

1

主题

0

精华

49

积分
发表于 2016-10-5 20:16:52 | 显示全部楼层
支持梦大神,不想写可以说出来~~ ,以视频的形式讲出来
回复 支持 反对

使用道具 举报

升级   20%

1

主题

0

精华

10

积分
发表于 2016-10-5 20:24:34 | 显示全部楼层
頂一個
回复 支持 反对

使用道具 举报

升级   22%

0

主题

0

精华

11

积分
发表于 2016-10-5 20:40:31 | 显示全部楼层
感谢梦大分享,小生受益良多,有空自己也再windbg上跟
回复 支持 反对

使用道具 举报

升级   58%

52

主题

0

精华

137

积分
发表于 2016-10-5 21:06:38 | 显示全部楼层
谢谢梦大佬
回复 支持 反对

使用道具 举报

升级   96%

18

主题

0

精华

194

积分
发表于 2016-10-5 21:09:16 | 显示全部楼层
厉害了word梦
回复 支持 反对

使用道具 举报

升级   66%

9

主题

0

精华

33

积分
发表于 2016-10-5 21:43:27 | 显示全部楼层
支持!感谢!
回复 支持 反对

使用道具 举报

升级   18%

1

主题

0

精华

9

积分
发表于 2016-10-5 22:01:12 | 显示全部楼层
顶,为什么那个长跳转od跟踪不了。
回复 支持 反对

使用道具 举报

升级   52%

1

主题

0

精华

26

积分
发表于 2016-10-5 22:09:01 | 显示全部楼层
请问这是不是天书夜读的代码?
回复 支持 反对

使用道具 举报

升级   99.33%

1

主题

0

精华

199

积分
发表于 2016-10-6 02:00:38 | 显示全部楼层
然而已加入环境检测大家族
回复 支持 反对

使用道具 举报

升级   36%

0

主题

0

精华

18

积分
发表于 2016-10-6 07:23:45 | 显示全部楼层
梦大国庆没休息吗?
回复 支持 反对

使用道具 举报

升级   100%

216

主题

64

精华

1432

积分
 楼主| 发表于 2016-10-6 12:48:54 | 显示全部楼层
璀璨刀光 发表于 2016-10-5 20:16
支持梦大神,不想写可以说出来~~ ,以视频的形式讲出来

视频更累吖 而且还有备课麻烦的很呢
回复 支持 反对

使用道具 举报

升级   100%

216

主题

64

精华

1432

积分
 楼主| 发表于 2016-10-6 12:49:22 | 显示全部楼层
绿林科技 发表于 2016-10-5 22:09
请问这是不是天书夜读的代码?

怎么联系到天书夜读了...
回复 支持 反对

使用道具 举报

升级   100%

216

主题

64

精华

1432

积分
 楼主| 发表于 2016-10-6 12:50:10 | 显示全部楼层
killvxk 发表于 2016-10-6 02:00
然而已加入环境检测大家族

tx也向wow64做手脚了。
回复 支持 反对

使用道具 举报

升级   100%

216

主题

64

精华

1432

积分
 楼主| 发表于 2016-10-6 12:50:34 | 显示全部楼层
因素 发表于 2016-10-6 07:23
梦大国庆没休息吗?

休息了,妥妥的睡了几天。
回复 支持 反对

使用道具 举报

升级   56%

2

主题

0

精华

28

积分
发表于 2016-10-8 22:29:33 | 显示全部楼层
谢谢梦大,看到这么长的汇编,尝试着人脑跟着走,结果跟丢了。。。等这两天没事儿了我也去windbg调试一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|Archiver|mengwuji ( 粤ICP备13060035号-1 )  

GMT+8, 2017-3-26 01:56 , Processed in 0.493069 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表