对tsfltmgr.sys系统蓝屏的原因分析(小心QQ控制器)

对tsfltmgr.sys系统蓝屏的原因分析(小心QQ控制器)
经过互联网搜索和不断探索,结果是QQ软件管家造成的灾难。进入安全模式后,坚决卸载QQ软件管家,重新启动系统完全正常。
一个同事WindowsXP系统正常执行关闭之后,第二天不能启动,症状的细节:
(1)可以输入具有网络功能的安全模式和安全模式。
(2)正常模式,没有windowxp滚动条开始重启
(3)进入安全模式,禁用主动重启,然后正常启动,出现蓝屏报告tsfltmgr.sys内存错误
经过互联网搜索和不断探索,原来是一场灾难,QQ软件管家不得不责怪。进入安全模式后,坚决卸载QQ软件管家,重新启动,系统完全正常。
下面是一篇转载的文章,供QQ电脑管家分析,请参考
在QQ电脑管家tsfltmgr钩框架分析
QQ电脑管家新版本有一个tsfltmgr.sys驱动,这是由sysnap,使驱动程序的一些简单的分析。我们看到了一个漂亮的钩子框架,并把它寄给大家。
首先,TsFltMgr是联系在一起的kifastcallentry功能,与钩点这里:
代码:

复制代码代码如下所示:
KD >你kifastcallentry + E3
NT!kifastcallentry + 0xe3:
8053dbb3 c1e902 SHR ECX,2
-------------------------------------------------------------------------
90 8053dbb6 NOP
90 8053dbb7 NOP
90 8053dbb8 NOP
8053dbb9 e962170c77 JMP tsfltmgr + 0x2320(f75ff320)
-------------------------------------------------------------------------
Jae 8053dbbe 0f83a8010000 NT!kisystemcallexit2 + 0x9f(8053dd6c)
8053dbc4 f3a5 REP MOVS DWORD PTR:{ } { ESI EDI,DWORD PTR }
8053dbc6 ffd3叫EBX

在SHR ECX原kifastcallentry,2说明应MOV EDI,ESP,CMP ESI,mmuserprobeaddress,共8字节,这是由3 tsfltmgr NOP和tsfltmgr取代了这里。
JMP将跳转到kifastcallentry_detour功能,和kifastcallentry_detour函数的代码,例如,如下:
代码:

复制代码代码如下所示:
保存场景
pushfd
的pushad / kifastcallentry_filter函数调用,滤波器
EDI / /推进系统调用表的相应系统调用的地址(或ssdtshadow SSDT地址)
EBX / /推在核函数对应的系统调用系统调用表。
功能 / /压入系统调用表在SysCall相应的核函数
电话kifastcallentry_filter / /电话kifastcallentry_filter滤波器
MOV { ESP + 10h },EAX / /改变相应的调用内核地址!恢复站点
POPAD
指令代替popfd / / kifastcallentry功能跑,跳回到原来的功能
MOV EDI,ESP
CMP ESI,g_7fff0000
推g_jmpback
RET

要注意MOV ESP + 10h { },eax,叫kifastcallentry_filter.before救场后,指令pushad会导致寄存器EAX,EBX,ECX,EDX,ESP,EBP,ESI、EDI堆叠顺序,并通过POPAD指令后恢复这些寄存器的值,所以MOV EAX 10h }和{ ESP +这里实际上重写存储与kifastcallentry_filter函数,即返回值栈EBX的值,修改系统调用相应的内核函数地址。
kifastcallentry_filter是真正的过滤功能。已经解释了函数的参数和返回值。经过详细的实现,C语言描述和叙述,例如,
代码:

复制代码代码如下所示:
页__stdcall kifastcallentry_filter(ULONG ulsyscallid,则ulsyscalladdr,普隆pulsyscalltable)
{
pfake_syscall pfakesyscall = null;如果(ulsyscallid = 0x400)
返回ulsyscalladdr;如果(pulsyscalltable = = g_kiservicetable ulsyscallid <= g_servicenum / / 0x11c)
{
pfakesyscall = g_fakesyscalltable { ulsyscallid }; / / SSDT
}
如果(pulsyscalltable = = g_keservicedescriptortable
g_keservicedescriptortable ulsyscallid <= g_servicenum / * 0x11c)。
{
pfakesyscall = g_fakesyscalltable { ulsyscallid }; / / SSDT
}
如果(pulsyscalltable = = g_w32pservicetableaddr ulsyscallid <= g_shadowservicenum / * * 0x29b)
{
pfakesyscall = g_fakesyscalltable { ulsyscallid + 1024 }; / / shadowssdt
}如果(pfakesyscall pfakesyscall -> ulfakesyscalladdr)
{
pfakesyscall -> ulorigsyscalladdr = ulsyscalladdr;
返回pfakesyscall -> ulfakesyscalladdr;
}
返回ulsyscalladdr;
}

需要交代一下,里面有TsFltMgr表,暂命名为g_fakesyscalltable,持有fake_syscall结构指针。表中的每一fake_syscall结构对应一个系统调用。表的前半部分对应于SSDT的系统调用,而1024个是在ShadowSSDT,对应的系统调用。
该fake_syscall结构大致如下(在非常多的领域中的作用尚不明确)。
代码:

复制代码代码如下所示:
__fake_syscall__ { typedef struct
ulong XXX1;
页ulsyscallid; / /系统调用函数
ulong XXX3;
ultableindex页;
xxx5页;
ulcountforprework页;
ulcountforpostwork页;
xxx8页;
页ulorigsyscalladdr; / /真正的系统调用。
页ulfakesyscalladdr; / /假地址的系统调用
xxx11页;
xxx12页;
xxx13页;
hellip;hellip;
} fake_syscall,* * * ppfake_syscall pfake_syscall;

的kifastcallentry_filter功能是根据功能完成的,在g_fakesyscalltable电缆系统调用导致相应的pfakesyscall对象,然后推断系统调用需要挂钩,将需要承担实际的系统调用地址存放在pfakesyscall -> ulorigsyscalladdr,和pfakesyscall -> ulfakesyscalladdr作为系统调用返回错误的地址。
这样的方式来获得真正的系统调用地址动态可使钩框架tsfltmgr高度兼容,例如,它会在驱动程序的加载顺序是晚于TsFltMgr SSDT HOOK不失效,如tsksp.sys驱动通过QQ电脑管家本身。
我的测试系统(xp_sp2),对tsfltmgr钩子函数:
代码:

复制代码代码如下所示:
/ / SSDT:
NtCreateFile,NtCreateKey,只要,ntcreatesymboliclinkobject NtCreateThread,NtDeleteFile,NtDeleteKey,NtDeviceIoControlFile,NtDeleteValueKey,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,NtUserSetWindowPos,NtUserShowWindow,ntusersetwindowplacement,NtUserShowWindowAsync,NtUserWindowFromPoint

所有的伪系统函数都有统一的代码框架,伪系统函数的代码框架大致如下:
代码:

复制代码代码如下所示:
NTSTATUS __stdcall fakent_xxx(XXX)
{
pfake_syscall pfakesyscall;
页ulxxx = 0;
ulstatus页;
NTSTATUS状态;
ulonglong ulltickcount;

pfakesyscall = g_pfakesyscall_nt_xxx; / /系统调用相应的pfakesyscall对象

状态= status_access_denied;
这是 / /做性能测试时,实际的版本号是假的g_bperformancetest
如果(g_bperformancetest){
ulltickcount = kequeryinterrupttime();
}
调用处理前的系统调用!

interlockedincrement(pfakesyscall -> ulcountforprework);
ulstatus =工作(ulxxx,pfakesyscall);
interlockeddecrement(pfakesyscall -> ulcountforprework);


如果(ulstatus!= 0xeeee0004 ulstatus!= 0xeeee0005)
{
origsyscall = pfakesyscall -> ulorigsyscalladdr * porigsyscall; / /调用原来的系统调用!
如果(porigsyscall nt_success(porigsyscall(XXX)))
{
调用后处理系统调用!

interlockedincrement(pfakesyscall -> ulcountforpostwork),
ulstatus =岗位(ulxxx),
interlockeddecrement(pfakesyscall -> ulcountforpostwork),

}
} / / 0xeeee0004应该拒绝电话,0xeeee0005应当约定叫。
如果(ulstatus = 0xeeee0005)
状态= status_success; / / psgetcurrentprocessid返回值这一回电话和不实用的,可能是多余的。
(psgetcurrentprocessid); / /似乎做性能测试时需要
如果(g_pfakesyscall_ntterminateprocess -> xxx5 ulltickcount g_bperformancetest){
性能测试(g_pfakesyscall_ntterminateprocess -> xxx13,ulltickcount);
返回状态;
}

以上是对tsfltmgr钩框架分析,祝你元宵节快乐~
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部