昨天遇到一件怪事,在进行远程线程注入的时候从csrss进程中竟然弹出了vc的ASSERT对话框。根据对话框提示信息找到了断言的位置在mfc的auxdata.cpp的第95行代码:
void AUX_DATA::UpdateSysMetrics()
{
// System metrics
cxIcon = GetSystemMetrics(SM_CXICON);
cyIcon = GetSystemMetrics(SM_CYICON);
// System metrics which depend on subsystem version
afxData.cxVScroll = GetSystemMetrics(SM_CXVSCROLL) + CX_BORDER;
afxData.cyHScroll = GetSystemMetrics(SM_CYHSCROLL) + CY_BORDER;
// Device metrics for screen
HDC hDCScreen = GetDC(NULL);
ASSERT(hDCScreen != NULL); <------------------就是这个断言
cxPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSX);
cyPixelsPerInch = GetDeviceCaps(hDCScreen, LOGPIXELSY);
ReleaseDC(NULL, hDCScreen);
}
具体的环境就是win xp进行多用户登陆:首先登陆一个windows帐号user1, session id = 0, 对csrss进程成功进行了远程线程注入。接着在保持user1登陆的情况下切换用户登陆到user2,进去之后同样的对新的session(session id = 1)的csrss进程进行远程线程注入,没什么问题。但是切回到user1后发现界面上有一个断言对话框,显示了上面代码位置的断言失败。查看这个对话框所在的进程确实是session 0的csrss进程。因为是一个稳定的重现的问题,使用windbg远程附加到session 0的csrss进程,查看弹出对话框的线程调用栈如下:
ChildEBP RetAddr
0071f8d8 77d193f5 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0071f910 77d2688a USER32!NtUserWaitMessage+0xc
0071f938 77d3b7c5 USER32!InternalDialogBox+0xd0 (FPO: [6,1,4])
0071fbf8 77d3b12b USER32!SoftModalMessageBox+0x938 (FPO: [1,165,4])
0071fd48 77d65fdf USER32!MessageBoxWorker+0x2ba (FPO: [1,78,4])
0071fda0 764f9b1b USER32!MessageBoxTimeoutW+0x7a (FPO: [6,19,0])
0071fe7c 764f9d5b winsrv!HardErrorHandler+0x2e8 (FPO: [0,44,4])
0071fe9c 764fb0f1 winsrv!ProcessHardErrorRequest+0x9b (FPO: [1,3,4])
0071febc 764fb173 winsrv!UserHardErrorEx+0x234 (FPO: [3,2,4])
0071fed0 75aa47a0 winsrv!UserHardError+0x12 (FPO: [2,0,0])
0071fff4 00000000 CSRSRV!CsrApiRequestThread+0x18a (FPO: [Non-Fpo])
这里很奇怪,断言的调用链里面应该会出现__crtMessageBoxA,除非是符号不对,但是调用栈里面所有的返回地址都有符号。
难道是调用栈不完整,于是结合汇编代码对调用栈进行核实---没问题。一个偶然的原因在ReactOS上面看了一下CsrApiRequestThread函数的源代码才意识到这个对话框是通过LPC端口投递过来的消息显示。winsrv!UserHardError是最后一个出错处理回调例程。
用户态调试查不出这个LPC是哪里投递过来的,转而使用内核态调试。
根据从运程线程注入的结果,对session 1的csrss进程进行的远程线程一直没有收到注入成功的回复,很自然想到看一下session 1的csrss进程的情况。
kd> !process 81a81468
PROCESS 81a81468 SessionId: 1 Cid: 0238 Peb: 7ffd5000 ParentCid: 0240
DirBase: 084003e0 ObjectTable: e178ca80 HandleCount: 128.
Image: csrss.exe
VadRoot 81711920 Vads 100 Clone 0 Private 702. Modified 2674. Locked 0.
DeviceMap e10000b8
Token e1474138
ElapsedTime 00:01:01.984
UserTime 00:00:01.500
KernelTime 00:00:01.921
QuotaPoolUs