windows 子系统认识(2)
环境:XP
为了看和子系统联系有多重要,我在kernel32.dll中,IDA看了下引用,如下:
可以看出,这个通信确实很重要。
其中CreateRemoteThread()函数的调用也需要调用通知子系统创建了线程(截图未全显示),代码片段如下:
// // Call the Windows server to let it know about the // process. // if ( !BaseRunningInServerProcess ) { a->ThreadHandle = Handle; a->ClientId = ClientId; CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX, BasepCreateThread ), sizeof( *a ) ); Status = m.ReturnValue; } else { if (hProcess != NtCurrentProcess()) { CSRREMOTEPROCPROC ProcAddress; ProcAddress = (CSRREMOTEPROCPROC)GetProcAddress( GetModuleHandleA("csrsrv"), "CsrCreateRemoteThread" ); if (ProcAddress) { Status = (ProcAddress)(Handle, &ClientId); } } } if (!NT_SUCCESS(Status)) { Status = (NTSTATUS)STATUS_NO_MEMORY; } else { if ( ARGUMENT_PRESENT(lpThreadId) ) { *lpThreadId = (DWORD)ClientId.UniqueThread; } if (!( dwCreationFlags & CREATE_SUSPENDED) ) { NtResumeThread(Handle,&i); } }
1。首先看到STATUS_NO_MEMORY,我想起了一些线索。网上有朋友说过在WIN7下创建远程线程注入时,有时候会返回这个错误,貌似是说跨session的时候,暂且不说是什么原因。
在这里我们可以看到,只要LPC通信失败,返回值都会被设置为STATUS_NO_MEMORY。
2。CsrClientCallServer通信过去后,其中的BASESRV_SERVERDLL_INDEX指明使用了basesrv.dll提供的函数分发表。最后定位调用了BaseSrvCreateThread()函数
IDA了下,BaseSrvCreateThread(),发现里面只要是调用了下面几个函数
CsrLockProcessByClientId
NtDuplicateObject
最后又回到了csrsrv!CsrCreateThread(),其实有不少函数最终的处理都是又跑回了csrsrv!模块的对应函数,如CsrCreateProcess也是
CsrCreateThread就是网上说的把创建出来的 线程/进程 啥的插入到全局链表的工作了。