吾愛破解 - LCG - LSG |安卓破解|病毒分析|huihengkj.com

 找回密碼
 注冊[Register]

QQ登錄

只需一步,快速開始

搜索
查看: 6086|回復: 115

[調試逆向] [原創]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




至于為什么這么改,外網有篇文章(http://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的段寄存器如下。


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

可以看到0x23和0x33唯一的區別就是Flags和limits位。
在0x23的32位系統中,Limits位需要設為0xFFFFF來達到最大尋址空間4GB,而在x64 win10中,已經完全放棄了使用段寄存器進行尋址的方式,全部采用分頁機制。因此GDT的limit和base全部設為0進行“平坦模式”。
Flags位的結構如下:

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)


看雪那篇也是我自己

免費評分

參與人數 29威望 +2 吾愛幣 +126 熱心值 +24 收起 理由
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
我最近也在研究http://dynamorio.org/docs/
推薦
matrixsky 發表于 2020-8-1 10:16
風掃春殘雪 發表于 2020-7-30 21:24
那個是我大號……當年入坑過于中二,名字太羞恥了,于是重新回來注冊了個小號……但是看雪賬號扔了有點可 ...

哈哈哈哈哈  你饒頭的問題解決了沒有
沙發
風雨3137 發表于 2020-7-28 16:34
3#
adsllikk 發表于 2020-7-28 16:44
圖片掛了
4#
 樓主| 風掃春殘雪 發表于 2020-7-28 16:53 |樓主

謝謝!已重新上傳
5#
pansophy 發表于 2020-7-28 17:02
厲害了,學習中
6#
nobodycca 發表于 2020-7-28 17:06
這個還可以這樣玩的嗎,確實是奇技淫巧
7#
shanghaoxiaogei 發表于 2020-7-28 17:32
厲害了,學習下
8#
一只甘蔗的故事 發表于 2020-7-28 17:47
大佬牛x,學習了!
9#
zhangyang580 發表于 2020-7-28 17:58
感謝大佬分析  學習
10#
wscb 發表于 2020-7-28 17:58
學習一下,感謝分享
您需要登錄后才可以回帖 登錄 | 注冊[Register]

本版積分規則 警告:本版塊禁止灌水或回復與主題無關內容,違者重罰!

快速回復 收藏帖子 返回列表 搜索

RSS訂閱|小黑屋|聯系我們|吾愛破解 - LCG - LSG ( )

GMT+8, 2020-8-4 06:11

Powered by Discuz!

500彩票邀请码Copyright © 2001-2020, Tencent Cloud.

快速回復 返回頂部 返回列表

500彩票邀請碼-彩經網