首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第53期->安全文摘
期刊号: 类型: 关键词:
线程调度的监视

作者:pjf(jfpan20000@sina.com)
出处:http://www.blogcn.com/user17/pjf/blog/4331410.html
日期:2004-11-05

文摘出处:https://www.xfocus.net/bbs/index.php?act=ST&f=2&t=41969

    接着上次的小话题说。
    上次提到因为想要无需硬编码的方案从而未选用SwapContex,后来又想了想用SwapContex也基本不用硬编码,但因为用了其它做法,没有再实现hook SwapContex了。前两天难得放假,写了一下看看效果。
    首先进入2000的SwapContext中,看看它作了什么。

0008:8040422C  OR        CL,CL
0008:8040422E  MOV       BYTE PTR ES:[ESI+2D],02
0008:80404233  PUSHFD                                          //ESP+4 -> EFLAGS
0008:80404234  MOV       ECX,[EBX]
0008:80404236  CMP       DWORD PTR [EBX+0000080C],00
0008:8040423D  PUSH      ECX                                 //ESP -> exception list
0008:8040423E  JNZ       80404338
0008:80404244  MOV       EBP,CR0
0008:80404247  MOV       EDX,EBP
0008:80404249  MOV       CL,[ESI+2C]
0008:8040424C  MOV       [EBX+50],CL
0008:8040424F  CLI
0008:80404250  MOV       [EDI+28],ESP                    //将ESP存入了KTHREAD的KernelStack
0008:80404253  MOV       EAX,[ESI+18]
0008:80404256  MOV       ECX,[ESI+1C]
... ...
    很明显,ESP+8的地方就是在KiSwapThread中的调用SwapContex的返回地址,可由它得到SwapContex函数地址,但没必要,直接hook这个在KiSwapThread中的地址更好些。
    下面的问题就是找出一个KernelStack可访问的非当前线程,这个很容易。示例代码片断(在2000/XP测试):

PCHAR GetSwapAddr()
{
    PCHAR res = 0;
    NTSTATUS  Status;
    PETHREAD Thread;

    if (*NtBuildNumber <= 2195)
        Status = PsLookupThreadByThreadId((PVOID)4, &Thread);
    else
        Status = PsLookupThreadByThreadId((PVOID)8, &Thread);

    if (NT_SUCCESS(Status))
    {
        if (MmIsAddressValid(Thread))
            res = (PCHAR)*PULONG(PCHAR(Thread)+0x28);
        if (MmIsAddressValid(res+8))
            res = (PCHAR)*PULONG(res+8);
        else
            res = 0;
    }

    return res;
}

PBYTE GoBackAddr = 0;
__declspec(naked) VOID HookSwap()
{
    DbgPrint("%08x\n", KeGetCurrentThread());
    _asm mov eax, GoBackAddr
    _asm jmp eax
}

HookSwapFunc()
{
... ...
    PCHAR SwapAddr = GetSwapAddr();
    if (SwapAddr)
        GoBackAddr = HookFunction(SwapAddr, HookSwap);
... ...
}

    HookFunction代码的具体实现自然是仁者见仁了。
    下面是一些结果:

4.343      Default            SwapAddr=80404141
4.343      Default            813b8c00
4.343      Default            fe995480
4.359      Default            81429660
4.359      Default            81429260
4.359      Default            805e5520
4.359      Default            813e15c0
4.359      Default            8139f500
4.359      Default            8139f260
4.375      Default            805e5520
4.375      Default            812ea140
4.390      Default            805e5520
4.390      Default            8139f500
4.390      Default            8139f260
4.406      Default            805e5520
4.422      Default            805e5520
4.422      Default            fe995480
4.422      Default            fe995480
4.422      Default            fe995480
4.422      Default            8139f500
4.422      Default            8139f260
4.422      Default            813a66e0

    没仔细想,可能有错,欢迎指出。

http://www.blogcn.com/user17/pjf/blog/4331410.html
版权所有,未经许可,不得转载