吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 27070|回复: 165
收起左侧

[调试逆向] [原创]SysWOW64的奇技淫巧

    [复制链接]
风扫春残雪 发表于 2020-7-28 16:33
本帖最后由 风扫春残雪 于 2020-7-28 16:53 编辑

我感觉这玩意儿应该有人写过,但中文互联网怎么搜都搜不到,顺便看了看英文资料。发一个自己的实现好了
这玩意儿用处:
(1)反调试
(2)能让win10 32位程序运行64位代码(其他操作系统的wow64据说实现底层不太一样,不保证同代码能完全运行)


最近在试着转二进制漏洞方向,部署的时候出现了各种版本问题和反复崩溃,看到dynamoRIO下已经有成千的issue,想让开发者来debug肯定是不可能,于是只好自己上了。
在调试的过程中,发现dynamoRIO有一段ASM特别有意思
他是用来在32位程序中执行64位function的一段loader,摘抄见附录
关键的代码只有这么几行
[Asm] 纯文本查看 复制代码
       RAW(ea)    
       DD offset sml_transfer_to_64    
       DB CS64_SELECTOR    
       RAW(00)

[Asm] 纯文本查看 复制代码
       /* far jmp to next instr w/ 32-bit switch: jmp 0023:<sml_return_to_32> */    
       push     offset sml_return_to_32  /* 8-byte push */    
       mov      dword ptr [esp + 4], CS32_SELECTOR /* top 4 bytes of prev push */    
       jmp      fword ptr [esp]

我试了试摘出来写成汇编,效果非常好。
在OD里不仅分析不出64位的汇编,而且单步会直接跟飞。在windbg里只有单步才能分析出x64的代码
自己写的汇编如下
[Asm] 纯文本查看 复制代码
.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include Test.inc

.data
strTitle db 'Helloworld!',0
.code

start:
    invoke MessageBox,0,addr strTitle,addr strTitle,0
    xor eax,eax
    mov edi,0FFFFFFFFH
    db 0eah
    dd offset sys64_start
    db 033h
    db 0
sys64_start:

    db 049h, 08bh, 0d7h ;mov rdx,r15
     
    push 0
    push offset sys32_start
    mov dword ptr[esp + 4],023h
    jmp fword ptr[esp]
     
sys32_start:
    mov eax,0
    mov ebx,0
    pop eax
    pop eax
    pop eax
    pop eax
    invoke MessageBox,0,addr strTitle,addr strTitle,0
    retn
end start




至于为什么这么改,外网有篇文章(https://www.malwaretech.com/2014/02/the-0x33-segment-selector-heavens-gate.html)写得特别好,我就不画蛇添足了,大概把大意翻译过来

首先,长跳转的机制是修改段寄存器CS来进行寻址和改变权限。段寄存器的结构分为selector、TL和RPL,selector代表段寄存器在GDT中对应的index,TL代表应该查局部表还是全局表(LDT/GDT),RPL是权限位。0x23和0x33的段寄存器如下。
Segment-Selectors.png

我们知道段寄存器TL=0时还是要去查GDT得到完整的段描述,在GDT中,0x23和0x33的信息如下

GDTD-46.png 可以看到0x23和0x33唯一的区别就是Flags和limits位。
在0x23的32位系统中,Limits位需要设为0xFFFFF来达到最大寻址空间4GB,而在x64 win10中,已经完全放弃了使用段寄存器进行寻址的方式,全部采用分页机制。因此GDT的limit和base全部设为0进行“平坦模式”。
Flags位的结构如下:
Flags-x86-x64.png
Gr(granularity)代表限长单位,在32位系统中一般都设为1代表Limits单位是4K(因此4K*0xFFFFF=4G),如果是0则Limits单位是byte,这个值在64位系统中无意义
L代表64位模式。这一位很多比较远古的书上是保留位
D/B则是32位下的操作数位数,这个和代码段、堆栈段有关系,但是在64位下也没有意义。

综上,通过切换CS段选择器可以在syswow64中左右横跳。


附录:
[Asm] 纯文本查看 复制代码
/* Routines to switch to 64-bit mode from 32-bit WOW64, make a 64-bit    
* call, and then return to 32-bit mode.    
*/    
/*    
* int switch_modes_and_load(void *ntdll64_LdrLoadDll,    
*                           UNICODE_STRING_64 *lib,    
*                           HANDLE *result)    
* XXX i#1633: this routine does not yet support ntdll64 > 4GB    
*/    
# define FUNCNAME switch_modes_and_load    
       DECLARE_FUNC(FUNCNAME)    
GLOBAL_LABEL(FUNCNAME:)    
       /* get args before we change esp */    
       mov      eax, ARG1    
       mov      ecx, ARG2    
       mov      edx, ARG3    
       /* save callee-saved registers */    
       push     ebx    
       /* far jmp to next instr w/ 64-bit switch: jmp 0033:<sml_transfer_to_64> */    
       RAW(ea)    
       DD offset sml_transfer_to_64    
       DB CS64_SELECTOR    
       RAW(00)    
sml_transfer_to_64:    
   /* Below here is executed in 64-bit mode, but with guarantees that    
    * no address is above 4GB, as this is a WOW64 process.    
    */    
      /* Call LdrLoadDll to load 64-bit lib:    
       *   LdrLoadDll(IN PWSTR DllPath OPTIONAL,    
       *              IN PULONG DllCharacteristics OPTIONAL,    
       *              IN PUNICODE_STRING DllName,    
       *              OUT PVOID *DllHandle));    
       */    
       RAW(4c) RAW(8b) RAW(ca)  /* mov r9, rdx : 4th arg: result */    
       RAW(4c) RAW(8b) RAW(c1)  /* mov r8, rcx : 3rd arg: lib */    
       push     0               /* slot for &DllCharacteristics */    
       lea      edx, dword ptr [esp] /* 2nd arg: &DllCharacteristics */    
       xor      ecx, ecx        /* 1st arg: DllPath = NULL */    
       /* save WOW64 state */    
       RAW(41) push     esp /* push r12 */    
       RAW(41) push     ebp /* push r13 */    
       RAW(41) push     esi /* push r14 */    
       RAW(41) push     edi /* push r15 */    
       /* align the stack pointer */    
       mov      ebx, esp        /* save esp in callee-preserved reg */    
       sub      esp, 32         /* call conv */    
       and      esp, HEX(fffffff0) /* align to 16-byte boundary */    
       call     eax    
       mov      esp, ebx        /* restore esp */    
       /* restore WOW64 state */    
       RAW(41) pop      edi /* pop r15 */    
       RAW(41) pop      esi /* pop r14 */    
       RAW(41) pop      ebp /* pop r13 */    
       RAW(41) pop      esp /* pop r12 */    
       /* far jmp to next instr w/ 32-bit switch: jmp 0023:<sml_return_to_32> */    
       push     offset sml_return_to_32  /* 8-byte push */    
       mov      dword ptr [esp + 4], CS32_SELECTOR /* top 4 bytes of prev push */    
       jmp      fword ptr [esp]    
sml_return_to_32:    
       add      esp, 16         /* clean up far jmp target and &DllCharacteristics */    
       pop      ebx             /* restore callee-saved reg */    
       ret                      /* return value already in eax */    
       END_FUNC(FUNCNAME)


看雪那篇也是我自己

免费评分

参与人数 67威望 +2 吾爱币 +155 热心值 +56 收起 理由
gogobn + 1 + 1 谢谢@Thanks!
懒得想名song + 1 我很赞同!
ZjyCjy + 1 + 1 谢谢@Thanks!
wh2510 + 1 谢谢@Thanks!
15278066219 + 1 + 1 用心讨论,共获提升!
do4family + 1 热心回复!
ml2077 + 1 热心回复!
离心秋 + 1 已经处理,感谢您对吾爱破解论坛的支持!
zhongxiaolong + 1 谢谢@Thanks!
FJFJ + 1 + 1 谢谢@Thanks!
pangxie1991 + 1 我很赞同!
CWJYBB + 1 + 1 我很赞同!
kqqt6236 + 1 我很赞同!
猛男z + 1 + 1 &amp;lt;font style=&amp;quot;vertical-align: inherit;&amp;quot;&amp;gt;&amp;lt;font style=
5omggx + 1 + 1 用心讨论,共获提升!
liu!!! + 1 + 1 谢谢@Thanks!
BaiTuGe + 1 + 1 用心讨论,共获提升!
louchen1994 + 1 + 1 我很赞同!
cloud210 + 1 + 1 用心讨论,共获提升!
Gumping + 1 + 1 我很赞同!
叶一苇 + 1 谢谢@Thanks!
loinlee123 + 1 这是啥意思啊
清雾迷晨 + 1 用心讨论,共获提升!
青霄 + 1 + 1 大佬写代码注释都用英文吗
zhaocz + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kwan8888 + 1 + 1 用心讨论,共获提升!
AmyLee97 + 1 鼓励转贴优秀软件安全工具和文档!
xbxbxbxb + 1 + 1 我很赞同!
onething + 1 + 1 热心回复!
Leslie339 + 1 + 1 我很赞同!
Jet_Chou + 1 不明觉厉,支持
班长的男人 + 1 + 1 谢谢@Thanks!
zsq + 1 + 1 谢谢@Thanks!
空凡星 + 1 热心回复!
ycuvuuui1L + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
GoodDoctor + 1 + 1 用心讨论,共获提升!
zswseu + 1 + 1 我很赞同!
rover_fighter + 1 热心回复!
Chl16347 + 1 + 1 热心回复!
893277970li + 1 + 1 &amp;lt;font style=&amp;quot;vertical-align: inherit;&amp;quot;&amp;gt;&amp;lt;font style=
lingjing + 1 + 1 我很赞同!
Damitte + 1 + 1 谢谢 @Thanks!
liujing1 + 1 + 1 我很赞同!
lsywy520 + 1 我很赞同!
思有邪 + 1 + 1 我很赞同!
czw52pj + 1 + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
fengbolee + 1 + 1 用心讨论,共获提升!
怀今 + 1 谢谢@Thanks!
月六点年一倍 + 1 谢谢@Thanks!
jiaodian + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Woshiluo + 1 谢谢@Thanks!
迷途的懒虫 + 1 + 1 我很赞同!
菠萝Pine + 1 + 1 热心回复!
d0cklng + 1 + 1 希望不要用来制毒
xdd233 + 1 我很赞同!
Perry370 + 1 + 1 用心讨论,共获提升!
gaosld + 1 + 1 热心回复!
willJ + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
boshao007 + 1 我很赞同!
JuncoJet + 3 + 1 有意思
sunnylds7 + 1 + 1 热心回复!
kuletco + 1 谢谢@Thanks!
st790211 + 1 + 1 谢谢@Thanks!
joeyFdo + 1 + 1 谢谢@Thanks!
tyzamer + 1 我很赞同!
315215 + 1 + 1 这个易语言论坛早就有人说过并且做出来了,精易论坛更进一步,有人做出调用.

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

cbwang505 发表于 2020-7-28 18:11
我最近也在研究https://dynamorio.org/docs/
matrixsky 发表于 2020-8-1 10:16
风扫春残雪 发表于 2020-7-30 21:24
那个是我大号……当年入坑过于中二,名字太羞耻了,于是重新回来注册了个小号……但是看雪账号扔了有点可 ...

哈哈哈哈哈  你饶头的问题解决了没有
风雨3137 发表于 2020-7-28 16:34
adsllikk 发表于 2020-7-28 16:44
图片挂了
 楼主| 风扫春残雪 发表于 2020-7-28 16:53

谢谢!已重新上传
pansophy 发表于 2020-7-28 17:02
厉害了,学习中
nobodycca 发表于 2020-7-28 17:06
这个还可以这样玩的吗,确实是奇技淫巧
一只甘蔗的故事 发表于 2020-7-28 17:47
大佬牛x,学习了!
zhangyang580 发表于 2020-7-28 17:58
感谢大佬分析  学习
wscb 发表于 2020-7-28 17:58
学习一下,感谢分享
tyzamer 发表于 2020-7-28 18:06
学习一下,感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 00:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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