TsFltMgr.sys系统蓝屏的原因就在于QQ电脑管家!
来源:互联网 发布:中国主席怎么选举 知乎 编辑:程序博客网 时间:2024/04/30 09:59
同事一WindowsXP系统,正常运行,关闭后,第二天无法启动,具体症状为:
(1)安全模式以及带网络功能的安全模式都可以进入;
(2)正常模式,还没出现WindowXP滚动条就开始重启;
(3)进安全模式,禁用自动重启后,再正常启动,出现蓝屏,报TsFltMgr.sys内存错误!
经过互联网查询,和不断摸索,最后发现竟然是可恶的QQ软件管家惹的祸,进安全模式果断卸载QQ软件管家后,再重启,系统完全正常了。
下面转载了一篇分析QQ电脑管家的文章,请参考:
QQ电脑管家中的TsFltMgr Hook框架分析
新版的QQ电脑管家中多了一个名字叫TsFltMgr.sys的驱动(应该是Sysnap大牛开发的,膜拜),对该驱动进行了一些简单的分析,看见了一套漂亮的Hook框架,发出来与大家分享。分析不对的地方请多多包涵。
首先TsFltMgr挂钩了KiFastCallEntry函数,Hook点在这里:
代码:
kd> u KiFastCallEntry+e3nt!KiFastCallEntry+0xe3:8053dbb3 c1e902 shr ecx,2-------------------------------------------------------------------------8053dbb6 90 nop8053dbb7 90 nop8053dbb8 90 nop8053dbb9 e962170c77 jmp TsFltMgr+0x2320 (f75ff320)-------------------------------------------------------------------------8053dbbe 0f83a8010000 jae nt!KiSystemCallExit2+0x9f (8053dd6c)8053dbc4 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]8053dbc6 ffd3 call ebx
该jmp会跳转到 KiFastCallEntry_Detour 函数中,KiFastCallEntry_Detour 函数代码如下:
代码:
// 保存现场pushfd pushad // 调用 KiFastCallEntry_Filter 函数,实现过滤push edi // 本次系统调用对应的SysCall Table的地址(SSDT或SSDTShadow的地址)push ebx // 本次系统调用在SysCall Table中对应的内核函数地址push eax // 本次系统调用对应的内核函数在SysCall Table中的功能号call KiFastCallEntry_Filter // 调用KiFastCallEntry_Filter,实现过滤mov [esp+10h], eax // 更改本次调用对应的内核函数地址!// 恢复现场popad popfd// 执行 KiFastCallEntry 函数中被替换掉的指令,并跳回原函数mov edi,espcmp esi, g_7fff0000push g_JmpBackret
KiFastCallEntry_Filter 是真正实现过滤的函数,该函数的参数和返回值上文已经说明了,其具体实现分析整理后,C语言描述如下:
代码:
ULONG __stdcall KiFastCallEntry_Filter(ULONG ulSyscallId, ULONG ulSyscallAddr, PULONG pulSyscallTable) { PFAKE_SYSCALL pFakeSysCall = NULL; if ( ulSyscallId >= 0x400 ) return ulSyscallAddr; if ( pulSyscallTable == g_KiServiceTable && ulSyscallId <= g_ServiceNum/* 0x11c */ ) { pFakeSysCall = g_FakeSysCallTable[ulSyscallId]; // SSDT } else if (pulSyscallTable == g_KeServiceDescriptorTable && g_KeServiceDescriptorTable && ulSyscallId <= g_ServiceNum/* 0x11c */) { pFakeSysCall = g_FakeSysCallTable[ulSyscallId]; // SSDT } else if (pulSyscallTable == g_W32pServiceTableAddr && ulSyscallId <= g_ShadowServiceNum/* 0x29b */) { pFakeSysCall = g_FakeSysCallTable[ulSyscallId + 1024]; // ShadowSSDT } if ( pFakeSysCall && pFakeSysCall->ulFakeSysCallAddr ) { pFakeSysCall->ulOrigSysCallAddr = ulSyscallAddr; return pFakeSysCall->ulFakeSysCallAddr; } return ulSyscallAddr;}
其中 FAKE_SYSCALL 结构大致如下(其中很多域的作用没弄明白):
代码:
typedef struct __FAKE_SYSCALL__ { ULONG xxx1; ULONG ulSyscallId; // 该系统调用的功能号 ULONG xxx3; ULONG ulTableIndex; ULONG xxx5; ULONG ulCountForPreWork; ULONG ulCountForPostWork; ULONG xxx8; ULONG ulOrigSysCallAddr; // 真实的系统调用地址 ULONG ulFakeSysCallAddr; // 假的系统调用地址 ULONG xxx11; ULONG xxx12; ULONG xxx13; ……} FAKE_SYSCALL, *PFAKE_SYSCALL, **PPFAKE_SYSCALL;
这种调用过程中动态获取真实系统调用地址的方法使 TsFltMgr 的Hook框架有较高的兼容性,例如不会使加载顺序晚于TsFltMgr的驱动中的SSDT Hook失效,例如QQ电脑管家本身带的TSKsp.sys驱动。
对于我的测试系统(XP_SP2),TsFltMgr hook的函数有:
代码:
// SSDT中:NtCreateFile、NtCreateKey、NtCreateSection、NtCreateSymbolicLinkObject、NtCreateThread、NtDeleteFile、NtDeleteKey、NtDeleteValueKey、NtDeviceIoControlFile、NtDuplicateObject、NtEnumerateValueKey、NtLoadDriver、NtOpenProcess、NtOpenSection、NtProtectVirtualMemory、NtQueryValueKey、NtRequestWaitReplyPort、NtSetContextThread、NtSetInformationFile、NtSetSystemInformation、NtSetValueKey、NtSuspendThread、NtSystemDebugControl、NtTerminateProcess、NtTerminateThread、NtWriteFile、NtWriteVirtualMemory// ShadowSSDT中:NtUserBuildHwndList、NtUserFindWindowEx、NtUserGetForegroundWindow、NtUserMoveWindow、NtUserQueryWindow、NtUserSendInput、NtUserSetParent、NtUserSetWindowLong、NtUserSetWindowPlacement、NtUserSetWindowPos、NtUserShowWindow、NtUserShowWindowAsync、NtUserWindowFromPoint
代码:
NTSTATUS __stdcall FakeNt_XXX(xxx){ PFAKE_SYSCALL pFakeSysCall; ULONG ulXXX = 0; ULONG ulStatus; NTSTATUS status; ULONGLONG ullTickCount; pFakeSysCall = g_pFakeSysCall_Nt_XXX; // 该系统调用对应的 pFakeSysCall 对象 status = STATUS_ACCESS_DENIED; // 貌似是做性能测试时候需要的,实际版本中 g_bPerformanceTest 为 FALSE if ( g_bPerformanceTest ) { ullTickCount = KeQueryInterruptTime(); } // 系统调用的调用前处理! // +++ InterlockedIncrement(&pFakeSysCall->ulCountForPreWork); ulStatus = PreWork(&ulXXX, pFakeSysCall); InterlockedDecrement(&pFakeSysCall->ulCountForPreWork); // --- if ( ulStatus != 0xEEEE0004 && ulStatus != 0xEEEE0005) { OrigSysCall * pOrigSysCall = pFakeSysCall->ulOrigSysCallAddr; // 调用原始系统调用! if ( pOrigSysCall && NT_SUCCESS(pOrigSysCall(xxx)) ) { // 系统调用的调用后处理! // +++ InterlockedIncrement(&pFakeSysCall->ulCountForPostWork), ulStatus = PostWork(&ulXXX), InterlockedDecrement(&pFakeSysCall->ulCountForPostWork), // --- } } // 0xEEEE0004 应该是拒绝调用的意思,0xEEEE0005 应该是允许调用的意思 if (ulStatus == 0xEEEE0005) status = STATUS_SUCCESS; // PsGetCurrentProcessId 这个调用的返回值后面并没有用到,可能是多余的 PsGetCurrentProcessId(); // 貌似是做性能测试时候需要的 if ( g_pFakeSysCall_NtTerminateProcess->xxx5 && ullTickCount && g_bPerformanceTest) { PerformanceTest(&g_pFakeSysCall_NtTerminateProcess->xxx13, ullTickCount); } return status;}
- TsFltMgr.sys系统蓝屏的原因就在于QQ电脑管家!
- 电脑蓝屏的原因
- 电脑公司特别版8.5出现 fastfat.sys文件不正确及蓝屏错误的原因之一
- 电脑蓝屏故障的原因以及解决方法
- 硬件原因导致电脑蓝屏的解决方法
- 电脑蓝屏的原因及解决办法
- 电脑"蓝屏"原因
- 电脑蓝屏原因查找
- 电脑蓝屏自动关机(方法篇----非系统原因)
- QQ电脑管家欲擒故纵,出尔反尔?
- 循环的魅力之冰冻QQ电脑管家6.9...
- 2007-6-28 错误的原因就在于自己
- 找到系统蓝屏的真正原因
- 常见原因导致的电脑蓝屏的解决方法
- 电脑蓝屏死机的原因及症状表现
- QQ登不上出现蓝屏代码0X000000EA,电脑蓝屏的解决方法
- QQ电脑管家登录协议分析
- 高仿QQ电脑管家8 界面
- Android中adb shell下查询中文记录乱码解决方法
- 进制转换
- 关于Genymotion的体验
- java性能调优总概
- Audio音频系统 —AudioFlinger(1)
- TsFltMgr.sys系统蓝屏的原因就在于QQ电脑管家!
- Android 自定义控件
- (android地图开发) 高德地图添加自定义菜单栏
- TeamViewer使用心得
- TVideoGrabber如何将网络摄像头影像实时发布到网络
- java下的字符编码转换总结
- android ContentProvider入门使用
- poj 2181 Jumping Cows
- CentOS 6.2安装第三方软件库epel