首页
社区
课程
招聘
[原创]3环到0环系统调用分析报告
发表于: 2011-12-25 22:08 13900

[原创]3环到0环系统调用分析报告

2011-12-25 22:08
13900

//科锐十班:        网名米汤
//于武汉桂子花园     2011.12.21 13:47

首先VC 写个用户代码:

#include "stdafx.h"
#include <windows.h>
int main(int argc, char* argv[])
{
        HANDLE hFile;
               
        while (1)
        {
                printf("Read Going.... 4 !!!\n");
                Sleep(4000);       

                hFile = CreateFile("MYFILE.TXT",           // open MYFILE.TXT  25号系统调用服务
                        GENERIC_READ,              // open for reading
                        FILE_SHARE_READ,           // share for reading
                        NULL,                      // no security
                        OPEN_EXISTING,             // existing file only
                        FILE_ATTRIBUTE_NORMAL,     // normal file
                        NULL);                     // no attr. template
               
                if (hFile == INVALID_HANDLE_VALUE)
                {
                        puts("Could not open file.");   // process error
                }

                CloseHandle(hFile);
        }

        return 0;
}
//为什么用循环呢,因为我们在系统服务下断点的来的频率太快了,太短了...一下条件断点就无法手标操作虚似机.
//通过od 分析如图: 


那么在windbg 中下个条件断点
bp KiFastCallEntry".if @edx== 0x0012FE50{} .else{gc}"    用符号不知道为什么容易 假死机
bp 8053e550 ".if @edx== 0x0012FE50{} .else{gc}"    这样就可以断下来,why!!! Why!!!

这样就在快速系统调用总入口下了一个条件断点,很大的机率上 "确定" 是我们r3程序触发的

nt!KiFastCallEntry:
0008:8053e550 b923000000      mov     ecx,23h                                                     ecx --> GDT_R3_DATA       
0008:8053e555 6a30            push    30h                               
0008:8053e557 0fa1            pop     fs                                                        //fs  -->KPCR ffdff000
0008:8053e559 8ed9            mov     ds,cx
0008:8053e55b 8ec1            mov     es,cx                                                //ds,es --> GDT_R3_DATA       
0008:8053e55d 8b0d40f0dfff    mov     ecx,dword ptr ds:[0FFDFF040h]  //ecx --> TSS
0008:8053e563 8b6104          mov     esp,dword ptr [ecx+4]                                esp 临时堆栈过渡到自己的内核堆栈
0008:8053e566 6a23            push    23h                                                                //开始保护R3现场 TRAP_FRAME   
0008:8053e568 52              push    edx                                                                //r3 SS:ESP
0008:8053e569 9c              pushfd                                                                        //r3 状态标志寄存器
0008:8053e56a 6a02            push    2                                                                       
0008:8053e56c 83c208          add     edx,8                                                //edx --> r3栈中参数块
0008:8053e56f 9d              popfd                                                                        //r0 状态标志寄存器 置0,关中断
0008:8053e570 804c240102      or      byte ptr [esp+1],2                                        //置r3 状态标志寄存器 开中断
0008:8053e575 6a1b            push    1Bh                                                                //0001 1011 r3 cs  GDT_R3_CODE
0008:8053e577 ff350403dfff    push    dword ptr ds:[0FFDF0304h]                        //r3 KTRAP_FRAME.eip= iFastSystemCallRet
0008:8053e57d 6a00            push    0                                                                //为了框架统一.压入0,对本次系统调用无意义
0008:8053e57f 55              push    ebp
0008:8053e580 53              push    ebx                                                                //无限r3现场保护
0008:8053e581 56              push    esi
0008:8053e582 57              push    edi                                                                //....
0008:8053e583 8b1d1cf0dfff    mov     ebx,dword ptr ds:[0FFDFF01Ch]        //ebx --> +0x01c SelfPcr : Ptr32 _KPCR
0008:8053e589 6a3b            push    3Bh                                                                //0011 1011 r3 fs  KGDT_R3_TEB
0008:8053e58b 8bb324010000    mov     esi,dword ptr [ebx+124h]                        //esi --> CurrentThread
0008:8053e591 ff33            push    dword ptr [ebx]                                        //保存线程原先异常表
0008:8053e593 c703ffffffff    mov     dword ptr [ebx],0FFFFFFFFh                        //目前seh置空
0008:8053e599 8b6e18          mov     ebp,dword ptr [esi+18h]                        //ebp --> 当前线程的最高栈顶.
0008:8053e59c 6a01            push    1                                                                //保存先前模式 用户模式
0008:8053e59e 83ec48          sub     esp,48h                                                        //TRAP_FRAME 预留其它 空间
0008:8053e5a1 81ed9c020000    sub     ebp,29Ch                                        //ebp--> 当前KTRAP_FRAME  
0008:8053e5a7 c6864001000001  mov     byte ptr [esi+140h],1                                //设置 当前 先前模式
0008:8053e5ae 3bec            cmp     ebp,esp                                               
0008:8053e5b0 759a            jne     nt!KiFastCallEntry2+0x47 (8053e54c)
0008:8053e5b2 83652c00        and     dword ptr [ebp+2Ch],0                                //KTRAP_FRAME.dr7 = 0
0008:8053e5b6 f6462cff        test    byte ptr [esi+2Ch],0FFh                                //当前线程是否在调试状态
0008:8053e5ba 89ae34010000    mov     dword ptr [esi+134h],ebp                        //设置当前线程的当前框架地址
0008:8053e5c0 0f854afeffff    jne     nt!Dr_FastCallDrSave (8053e410)                //如果调试状态跳走
0008:8053e5c6 8b5d60          mov     ebx,dword ptr [ebp+60h]                        //调试相关
0008:8053e5c9 8b7d68          mov     edi,dword ptr [ebp+68h]                        //调试相关
0008:8053e5cc 89550c          mov     dword ptr [ebp+0Ch],edx                        //调试相关
0008:8053e5cf c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h        //调试相关
0008:8053e5d6 895d00          mov     dword ptr [ebp],ebx                                //调试相关
0008:8053e5d9 897d04          mov     dword ptr [ebp+4],edi                                /调试相关

//不开中断 (临时用置为90 这样别的系统调用再也进不来了,就可以安心调试本次调用)  eb 8053e5dc 90
0008:8053e5dc fb              "sti" 不让她执行        本句代码
                                                                       
0008:8053e5dd 8bf8            mov     edi,eax                                                        //edi = 系统调用服务号
0008:8053e5df c1ef08          shr     edi,8                                               
0008:8053e5e2 83e730          and     edi,30h                                                       
0008:8053e5e5 8bcf            mov     ecx,edi                                                        //ecx = edi bit11,bit12   00 /10
0008:8053e5e7 03bee0000000    add     edi,dword ptr [esi+0E0h]                        //edi-->ServiceTable       
0008:8053e5ed 8bd8            mov     ebx,eax                                                        //ebx = 系统调用服务号
0008:8053e5ef 25ff0f0000      and     eax,0FFFh                                                       
0008:8053e5f4 3b4708          cmp     eax,dword ptr [edi+8]                                //检查统调用服务号 的合法性
0008:8053e5f7 0f8345fdffff    jae     nt!KiBBTUnexpectedRange (8053e342)
0008:8053e5fd 83f910          cmp     ecx,10h                                                        //是否扩展系统调用
0008:8053e600 751a            jne     nt!KiFastCallEntry+0xcc (8053e61c)         //否则跳走
.......
0008:8053e61c ff0538f6dfff            inc     dword ptr ds:[0FFDFF638h]                       
0008:8053e622 8bf2            mov     esi,edx                                                //esi-->r3参数块
0008:8053e624 8b5f0c          mov     ebx,dword ptr [edi+0Ch]                        //ebx-->参数大小数组       
0008:8053e627 33c9            xor     ecx,ecx
0008:8053e629 8a0c18          mov     cl,byte ptr [eax+ebx]                                //ecx = 参数块大小
0008:8053e62c 8b3f            mov     edi,dword ptr [edi]                                //edi-->系统服务函数指针数组       
0008:8053e62e 8b1c87          mov     ebx,dword ptr [edi+eax*4]                         //ebx = 服务函数地址
0008:8053e631 e9f2cb0e01      jmp     8162b228                                               
......
0008:8162b228 e915f4276f      jmp     hookport+0xa642 (f08aa642)                 
//...我的机器被谁hook 了?????我不看了.我估计跟360有关,所以还原系统,因为现在只是学习基础!不找没趣吧
.....
//回到正常机器,接着被hook地方(8053e631 ),当然这次是系统正常代码

8053e631 2be1            sub     esp,ecx                                                                //预留栈空间,准备复制用户参数了
8053e633 c1e902          shr     ecx,2                                                                        //ecx = 参数个数
8053e636 8bfc            mov     edi,esp                                                        //edi-->当前esp       
8053e638 3b35549a5580    cmp     esi,dword ptr [nt!MmUserProbeAddress (80559a54)]
8053e63e 0f83a8010000    jae     nt!KiSystemCallExit2+0x9f (8053e7ec)                //if(esi >7fff0000 )(跳走) 检查esi是否r3地址
8053e644 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]                        //复制r3参数
8053e646 ffd3            call    ebx                                                                        //调用系统服务函数
8053e648 8be5            mov     esp,ebp                                                               
8053e64a 8b0d24f1dfff    mov     ecx,dword ptr ds:[0FFDFF124h]                //ecx-->CurrentThread
8053e650 8b553c          mov     edx,dword ptr [ebp+3Ch]                                //edx=trap_frame.edx 0xffffffff
8053e653 899134010000    mov     dword ptr [ecx+134h],edx                                //Kthread.Trapframe = 0xfffffffff
nt!KiServiceExit:
8053e659 fa              cli                                               

8053e65a f7457000000200  test    dword ptr [ebp+70h],20000h                                //trap_frame.eflag测试划是否虚拟8086模式       
8053e661 7506            jne     nt!KiServiceExit+0x10 (8053e669)                //是则跳走
8053e663 f6456c01        test    byte ptr [ebp+6Ch],1                                                //trap_frame.SegCs 是否为r3 选择子
8053e667 7457            je      nt!KiServiceExit+0x67 (8053e6c0)                //不是则跳走
8053e669 8b1d24f1dfff    mov     ebx,dword ptr ds:[0FFDFF124h]                //ebx-->CurrentThread
8053e66f c6432e00        mov     byte ptr [ebx+2Eh],0                                        //kthread.afterd= 0 清除"警觉" apc 相关
8053e673 807b4a00        cmp     byte ptr [ebx+4Ah],0                                        //kthread.KAPC_STATE.UserApcPending
8053e677 7447            je      nt!KiServiceExit+0x67 (8053e6c0)                //没有apc挂起
..............
8053e6c0 8b54244c        mov     edx,dword ptr [esp+4Ch]                                 //edx = ktrap_frame.seh链       
8053e6c4 648b1d50000000  mov     ebx,dword ptr fs:[50h]                                        //ebx = kpcr.DebugActive 0
8053e6cb 64891500000000  mov     dword ptr fs:[0],edx                                        //kpcr.tib.ExceptionList = edx 还原线程seh
8053e6d2 8b4c2448        mov     ecx,dword ptr [esp+48h]                                //ecx = ktrap_frame.PreviousPreviousMode
8053e6d6 648b3524010000  mov     esi,dword ptr fs:[124h]                                //esi-->CurrentThread
8053e6dd 888e40010000    mov     byte ptr [esi+140h],cl                                        //kthread.PreviousMode = ecx 还原先前模式
8053e6e3 f7c3ff000000    test    ebx,0FFh                                                                //当前线程是否在调试
8053e6e9 7579            jne     nt!KiSystemCallExit2+0x17 (8053e764)        //是,则跳走
8053e6eb f744247000000200 test    dword ptr [esp+70h],20000h                                //trap_frame.eflag测试划是否虚拟8086模式       
8053e6f3 0f85eb080000    jne     nt!KiExceptionExit+0x12c (8053efe4)                //是,则跳走
8053e6f9 66f744246cf8ff  test    word ptr [esp+6Ch],0FFF8h                                        //trap_frame.cs 高13位
8053e700 0f84b4000000    je      nt!KiSystemCallExit2+0x6d (8053e7ba)         //为0 则跳走
8053e706 66837c246c1b    cmp     word ptr [esp+6Ch],1Bh                               
8053e70c 660fba64246c00  bt      word ptr [esp+6Ch],0
8053e713 f5              cmc
8053e714 0f878e000000    ja      nt!KiSystemCallExit2+0x5b (8053e7a8)
8053e71a 66837d6c08      cmp     word ptr [ebp+6Ch],8
8053e71f 7405            je      nt!KiServiceExit+0xcd (8053e726)
8053e721 8d6550          lea     esp,[ebp+50h]                                                       
8053e724 0fa1            pop     fs                                                                        //还原r3 ss
8053e726 8d6554          lea     esp,[ebp+54h]                                                        //一路还原.....
8053e729 5f              pop     edi
8053e72a 5e              pop     esi
8053e72b 5b              pop     ebx
8053e72c 5d              pop     ebp                                                                       
8053e72d 66817c24088000  cmp     word ptr [esp+8],80h                                        //检查trap_frame.cs 选择子的合法性
8053e734 0f87c6080000    ja      nt!KiExceptionExit+0x148 (8053f000)
8053e73a 83c404          add     esp,4                                                                //跳过trap_errcode
8053e73d f744240401000000 test    dword ptr [esp+4],1                                                // ss:0010:f959fdd0=0000001b 还是检查
nt!KiSystemCallExitBranch:
8053e745 7506            jne     nt!KiSystemCallExit2 (8053e74d)                        //trap_frame.cs是r3 选择子则跳走
......

nt!KiSystemCallExit2:
8053e74d f644240901      test    byte ptr [esp+9],1                                                //trap_frame.tf 位是否为 1 单步状态
8053e752 75f8            jne     nt!KiSystemCallExit (8053e74c)                        //单步状态则跳走
8053e754 5a              pop     edx                                                                        //edx = tramp_frame.eip
8053e755 83c404          add     esp,4                                                               
8053e758 80642401fd      and     byte ptr [esp+1],0FDh                                        //1111 1101  清掉trap_frame.eflag 位2
8053e75d 9d              popfd                                                                                //还原eflag
8053e75e 59              pop     ecx                                                                        //ecx = tramp_frame.esp  r3 的栈顶
8053e75f fb              sti                                                                                        //开中断
8053e760 0f35            sysexit                                                                                //退出内模式
......

sysenter 所做操作:  箭头方向表示  源 赋值给 目标
1,SYSENTER_CS_MSR-->CS          174        (对应KGDT_R0_CODE)       
2,SYSENTER_CS_MSR+8-->SS                 (对应KGDT_R0_DATA)
3,SYSENTER_EIP_MSR-->EIP          176
4,SYSENTER_ESP_MSR-->ESP          175

sysexit 所做操作:
1,SYSENTER_CS_MSR+16-->CS  且 rpl位 自动置3(对应KGDT_R3_CODE)
2, edx --> eip
3, SYSENTER_CS_MSR+24-->SS 且rpl位置3 (对应KGDT_R3_DATA)
4, ecx-->esp

引起反思:
从这这两个指令操作,就可以想像为什么GDT中前几项表项的是那样的顺序!!


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
科锐明年俺也要去。
2011-12-25 22:19
0
雪    币: 143
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
   学习了~
2011-12-26 11:20
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
不错
科瑞出人才一点不假
2011-12-26 11:31
0
雪    币: 1737
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
呵呵~~ 偶的水平还差得很远啊~~
2011-12-26 16:45
0
雪    币: 415
活跃值: (34)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
不错,继续深入啊。
2011-12-27 08:48
0
雪    币: 122
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
以前应该也去科瑞学学的,可惜现在不在武汉了!
2011-12-27 22:46
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
科瑞现在不在武汉了!?
2011-12-28 08:25
0
雪    币: 116
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
应该是楼上那人不在武汉了?
2011-12-28 14:26
0
雪    币: 183
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
老吴????
2012-1-4 09:12
0
雪    币: 45
活跃值: (51)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
请正确用名字"科锐" -- "武汉科锐" 谢谢~~~
2012-4-28 22:33
0
雪    币: 45
活跃值: (51)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
那么在windbg 中下个条件断点
bp KiFastCallEntry".if @edx== 0x0012FE50{} .else{gc}"    用符号不知道为什么容易 假死机
bp 8053e550 ".if @edx== 0x0012FE50{} .else{gc}"    这样就可以断下来,why!!! Why!!!

       ↑↑↑↑

关于你这个问题.. 方老师,钱老师, 问了就能给你答案吧?
我猜想, 这个问题应该是你是在三环下使用 WinDbg, 而KiFastCallEntry是内核函数...

你可以试试,直接开WinDBG, 然后打开调试本机(或者使用livekd),应该是可以认出来的...
2012-4-28 22:36
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
前来学习,不错的文章
2012-4-28 22:43
0
雪    币: 2989
活跃值: (4911)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
最后于 2020-3-13 12:33 被舒默哦编辑 ,原因:
2020-3-2 13:59
0
游客
登录 | 注册 方可回帖
返回
//