Windows内核情景分析学习笔记(六)

64位下 3环Wow64进程进行系统调用分析

以下将以ReadProcessMemory为例进行分析

首先进入SysWow64下的kernel32.dll

7577CFCC          8B FF    mov  edi,edi                                                        
7577CFCE          55       push  ebp                                                           
7577CFCF          8B EC    mov  ebp,esp                                                        
7577CFD1          5D       pop  ebp                                                            
7577CFD2          E9 E6 40 jmp  757610BD

757610BD          FF 25 00 jmp  dword ptr ds:[<&API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemory

上述跳转将会到达SysWow64下的kernelBase.dll

76F4DFC8          8B FF    mov  edi,edi                                                        
76F4DFCA          55       push  ebp                                                           
76F4DFCB          8B EC    mov  ebp,esp                                                        
76F4DFCD          8D 45 14 lea  eax,dword ptr ss:[ebp+0x14]                                    
76F4DFD0          50       push  eax           ; 将存放读取长度的地址作为需要返回实际读取长度的地址                                           
76F4DFD1          FF 75 14 push  dword ptr ss:[ebp+0x14] ;以下是依次压入前四个参数                                   
76F4DFD4          FF 75 10 push  dword ptr ss:[ebp+0x10]                                       
76F4DFD7          FF 75 0C push  dword ptr ss:[ebp+0x0C]                                       
76F4DFDA          FF 75 08 push  dword ptr ss:[ebp+0x08]                                       
76F4DFDD          FF 15 C4 call  dword ptr ds:[<&ntdll.NtReadVirtualMemory>]                   
76F4DFE3          8B 4D 18 mov  ecx,dword ptr ss:[ebp+0x18] ;取出真正要存实际读入长度的地址                                   
76F4DFE6          85 C9    test  ecx,ecx                                                       
76F4DFE8          74 05    je  KernelBase.76F4DFEF                                             
76F4DFEA          8B 55 14 mov  edx,dword ptr ss:[ebp+0x14]                                    
76F4DFED          89 11    mov  dword ptr ds:[ecx],edx      ;如果所给地址不为空 便将实际读取的长度写入                                   
76F4DFEF          85 C0    test  eax,eax                                                       
76F4DFF1          7D 0A    jnl  KernelBase.76F4DFFD                                            
76F4DFF3          50       push  eax                                                           
76F4DFF4          E8 69 86 call  KernelBase.76F76662  ;如果返回值为负数 代表调用出错  将调用这个函数设置Error                                         
76F4DFF9          33 C0    xor  eax,eax                                                        
76F4DFFB          EB 03    jmp  KernelBase.76F4E000                                            
76F4DFFD          33 C0    xor  eax,eax                                                        
76F4DFFF          40       inc  eax                                                            
76F4E000          5D       pop  ebp                                                            
76F4E001          C2 14 00 retn  0x0014                                                        

接下来进入SysWow64中的ntdll.dll

77BAFE80  		  B8 3C 00 mov  eax,0x0000003C             ;eax 代表此API在SSDT表中的索引值                                    
77BAFE85          33 C9    xor  ecx,ecx                                                        
77BAFE87          8D 54 24 lea  edx,dword ptr ss:[esp+0x04] ;edx指向存放参数的地址                                   
77BAFE8B          64 FF 15 call  dword ptr fs:[0x000000C0]  ;fs[0xC0]中存放的是755F2320        
77BAFE92          83 C4 04 add  esp,0x04                                                       
77BAFE95          C2 14 00 retn  0x0014                                                        

接下来便进入Wow64Cpu.dll

755F2320          EA 1E 27 jmp far  0x0033 : 0x755F271E   ;该指令将Cs修改为64位的代码段,接下来的代码将全部以64位进行解析 并跳转到0x755F271E00000000749C271E CpupReturnFromSimulatedCode:            ; DATA XREF: CpuProcessInit+B1↑o
00000000749C271E                                         ; CpuResetToConsistentState+B7↑o ...
00000000749C271E                 mov     r8d, [esp]      ; r8d = 返回地址
00000000749C2723                 mov     [r13+_MyContext._Eip], r8d ; 将Eip Esp保存在类型于Context的结构中
00000000749C272A                 mov     [r13+_MyContext._Esp], esp
00000000749C2731                 mov     rsp, [r12+_TEB.TlsSlots];进行换栈操作
00000000749C2739                 and     [r12+_TEB.TlsSlots], 0
00000000749C2742          		 mov     r11d, edx       ; r11d = 参数位置         
00000000749C2745                 jmp     qword ptr [r15+rcx*8];rcx从前面可知为0 所以将跳转到[r15]位置 [r15] = 0x00000000749C2749
00000000749C2749                 mov     [r13+_MyContext._Esi], esi;以下将保存一些寄存器到MyContext中
00000000749C2750                 mov     [r13+_MyContext._Edi], edi
00000000749C2757                 mov     [r13+_MyContext._Ebx], ebx
00000000749C275E                 mov     [r13+_MyContext._Ebp], ebp
00000000749C2765                 pushfq
00000000749C2766                 pop     rbx
00000000749C2767                 mov     [r13+_MyContext._Eflags], ebx
00000000749C276E                 mov     ecx, eax        ; eax = Index
00000000749C2770                 call    cs:__imp_Wow64SystemServiceEx
00000000749C2776                 mov     [r13+_MyContext._Eax], eax
00000000749C277D                 jmp     loc_749C2611 ;           

接下来将进入到Wow64.dll中

Wow64SystemServiceEx:
00000000749CCEB0                 mov     r11, rsp
00000000749CCEB3                 mov     [r11+18h], rbx
00000000749CCEB7                 push    rsi
00000000749CCEB8                 push    rdi
00000000749CCEB9                 push    r12
00000000749CCEBB                 sub     rsp, 8A0h
00000000749CCEC2                 mov     rax, cs:__security_cookie
00000000749CCEC9                 xor     rax, rsp
00000000749CCECC                 mov     [rsp+8B8h+var_28], rax
00000000749CCED4                 mov     rbx, rdx        ; rbx  参数位置
00000000749CCED7                 mov     r8d, ecx        ; r8d = ecx = Index
00000000749CCEDA                 mov     edx, ecx        ; edx = ecx = Index
00000000749CCEDC                 shr     edx, 0Ch        
00000000749CCEDF                 and     edx, 3			 ;rdx 索引中的12-13位代表选取哪张表
00000000749CCEE2                 and     r8d, 0FFFh      ; r8d = 真正表中的索引号
00000000749CCEE9                 lea     r9, [rdx+rdx*2]
00000000749CCEED                 add     r9, r9         
00000000749CCEF0                 lea     r10, ServiceTables
00000000749CCEF7                 cmp     r8d, [r10+r9*8+10h];r9 = rdx * 0x30 表示的是对应表在ServiceTables中的偏移量 再加上0x10位置存放的是这个表中最大索引号
00000000749CCEFC                 ja      loc_749CD041    ; 检验索引是否在最大索引内
00000000749CCF02                 mov     rsi, gs:_TEB.NtTib.Self;以下没看出来具体的用处
00000000749CCF0B                 mov     [rsp+8B8h+TEB], rsi
00000000749CCF10                 mov     rdi, gs:_TEB.NtTib.Self
00000000749CCF19                 add     rdi, 2000h
00000000749CCF20                 mov     [rsp+8B8h+var_888], rdi
00000000749CCF25                 mov     rax, [rsi+(_TEB.TlsSlots+18h)]
00000000749CCF2C                 mov     [rsp+8B8h+var_848], rax
00000000749CCF31                 lea     rax, [rsp+8B8h+var_840]
00000000749CCF36                 mov     [r11-838h], rax
00000000749CCF3D                 lea     rax, [rsp+8B8h+var_840]
00000000749CCF42                 mov     [rsp+8B8h+var_840], rax
00000000749CCF47                 lea     rax, [r11-28h]
00000000749CCF4B                 mov     [r11-830h], rax
00000000749CCF52                 lea     rax, [rsp+8B8h+var_848]
00000000749CCF57                 mov     [rsi+1498h], rax
00000000749CCF5E                 mov     rax, [r10+r9*8] ; rax = 真正的函数表地址
00000000749CCF62                 mov     r12, [rax+r8*8] ; r12 = 索引对于的函数地址
00000000749CCF66                 mov     [rsp+8B8h+Table], edx
00000000749CCF6A                 mov     [rsp+8B8h+Index], r8d
00000000749CCF6F
00000000749CCF6F loc_749CCF6F:                           ; DATA XREF: .text:00000000749F3F60↓o
00000000749CCF6F                                         ; .text:00000000749F3F70↓o
00000000749CCF6F                 mov     eax, [rdi+34h]
00000000749CCF72                 mov     [rsi+_TEB.LastErrorValue], eax
00000000749CCF75                 mov     rax, cs:pfnWow64LogSystemService
00000000749CCF7C                 test    rax, rax
00000000749CCF7F                 jnz     short loc_749CCF8F
00000000749CCF81                 mov     rcx, rbx
00000000749CCF84                 call    r12			;将调用到表中对应的函数 在本次中这个函数为whNtReadVirtualMemory也位于Wow64.dll中
00000000749CCF87                 mov     ebx, eax
00000000749CCF89                 mov     [rsp+8B8h+Result], eax
00000000749CCF8D                 jmp     short loc_749CCFC0
whNtReadVirtualMemory:
00000000749DAC78                 mov     [rsp+arg_10], rbx
00000000749DAC7D                 push    rsi
00000000749DAC7E                 push    rdi
00000000749DAC7F                 push    r12
00000000749DAC81                 push    r13
00000000749DAC83                 push    r14
00000000749DAC85                 sub     rsp, 30h
00000000749DAC89
00000000749DAC89 loc_749DAC89:                           ; DATA XREF: .text:00000000749F0DC8↓o
00000000749DAC89                 movsxd  r12, dword ptr [rcx] ; rcx = 参数地址,依次取出参数 放入寄存器中
00000000749DAC8C                 mov     esi, [rcx+4]		  
00000000749DAC8F                 mov     edi, [rcx+8]
00000000749DAC92                 mov     ebx, [rcx+0Ch]
00000000749DAC95                 mov     r13d, [rcx+10h]
00000000749DAC99                 mov     rdx, r13
00000000749DAC9C                 lea     rcx, [rsp+58h+arg_8]
00000000749DACA1                 call    Wow64ShallowThunkSIZE_T32TO64 ; 如果所给lpNumberOfBytesRead不为空则 选用栈上的一个地址 暂时代替这个地址
00000000749DACA6                 mov     r14, rax
00000000749DACA9                 mov     [rsp+58h+var_38], rax ;将第五个参数即rsp+58h+arg_8 压栈
00000000749DACAE                 mov     r9, rbx				;将前四个参数放入寄存器中
00000000749DACB1                 mov     r8, rdi
00000000749DACB4                 mov     rdx, rsi
00000000749DACB7                 mov     rcx, r12
00000000749DACBA                 call    cs:__imp_NtReadVirtualMemory ;接下如就是进入ntdll 调用该函数
00000000749DACC0                 mov     r11d, eax
00000000749DACC3                 test    r14, r14
00000000749DACC6                 jnz     short loc_749DACCF
00000000749DACC8                 and     [rsp+58h+arg_0], r14
00000000749DACCD                 jmp     short loc_749DACE4
00000000749DACCF ; ---------------------------------------------------------------------------
00000000749DACCF
00000000749DACCF loc_749DACCF:                           ; CODE XREF: whNtReadVirtualMemory+4E↑j
00000000749DACCF                 mov     eax, 0FFFFFFFFh
00000000749DACD4                 cmp     [r14], rax	;如果返回的读取地址长度部位-1 则将暂存在rsp+58h+var_38中的数据 写入到真正的所给地址中
00000000749DACD7                 cmovb   rax, [r14]
00000000749DACDB                 mov     [r13+0], eax
00000000749DACDF                 mov     [rsp+58h+arg_0], r13
00000000749DACE4
00000000749DACE4 loc_749DACE4:                           ; CODE XREF: whNtReadVirtualMemory+55↑j
00000000749DACE4                                         ; DATA XREF: .text:00000000749F0DC8↓o
00000000749DACE4                 mov     eax, r11d
00000000749DACE7                 mov     rbx, [rsp+58h+arg_10]
00000000749DACEC                 add     rsp, 30h
00000000749DACF0                 pop     r14
00000000749DACF2                 pop     r13
00000000749DACF4                 pop     r12
00000000749DACF6                 pop     rdi
00000000749DACF7                 pop     rsi
00000000749DACF8                 retn

接下来就进入ntdll中的对应函数

0000000077A01700  4C 8B D1 mov  r10,rcx                                                        
0000000077A01703  B8 3C 00 mov  eax,0x0000003C                                                 
0000000077A01708  0F 05    syscall                                                             
0000000077A0170A  C3       retn                                                                

接下去就是要进入0环调用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值