当前位置:首页 > 科技数码

ntcreatefile TsFltMgr.sys系统蓝屏的原因是什么

  同事一WindowsXP系统,正常执行,关闭后,第二天无法启动,详细症状为:

  (1)安全模式以及带网络功能的安全模式都能够进入;

  (2)正常模式,还没出现WindowXP滚动栏就?始重新启动;

  (3)进安全模式,禁用自己主动重新启动后,再正常启动,出现蓝屏,报TsFltMgr.sys内存错误!

  经过互联网查询,和不断摸索,最后发现居然是可恶的QQ软件管家惹的祸,进安全模式果断卸载QQ软件管家后,再重新启动,系统全然正常了。

  以下转载了一篇分析QQ电脑管家的文章,请参考:

  QQ电脑管家中的TsFltMgr Hook框架分析

  新版的QQ电脑管家中多了一个名字叫TsFltMgr.sys的驱动,对该驱动进行了一些简单的分析,看见了一套美丽的Hook框架,发出来与大家分享。分析不正确的地方请多多包涵。

  首先TsFltMgr挂钩了KiFastCallEntry函数,Hook点在这里:

  代码:

  复制代码

  代码如下:

  kd> u KiFastCallEntry+e3

  nt!KiFastCallEntry+0xe3:

  8053dbb3 c1e902 shr ecx,2

  -------------------------------------------------------------------------

  8053dbb6 90 nop

  8053dbb7 90 nop

  8053dbb8 90 nop

  8053dbb9 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

  原始的KiFastCallEntry在 shr ecx, 2 指令后面应该是 mov edi,esp;cmp esi, MmUserProbeAddress,共8个字节,在这里被 TsFltMgr 替换成了3个nop和一个jmp。

  该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,esp

  cmp esi, g_7fff0000

  push g_JmpBack

  ret

  这里须要注意的是 call KiFastCallEntry_Filter 之后的 mov [esp+10h], eax。之前保存现场时的指令pushad会导致寄存器EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI依次入栈,并通过后面的popad指令恢复这些寄存器的值。因此此处的mov [esp+10h], eax实际上是用 KiFastCallEntry_Filter 函数的返回值来改写堆栈中保存的ebx的值,即改写本次系统调用相应的内核函数地址。

  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;

  }

  这里须要说明的是,TsFltMgr内部有一张表,暂且命名为 g_FakeSysCallTable,该表中存放的是指向 FAKE_SYSCALL 结构的指针。表中的每个 FAKE_SYSCALL 结构相应一个系统调用,表的前半部分相应SSDT中的系统调用,1024项以后相应ShadowSSDT里的系统调用。

  当中 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;

  因此 KiFastCallEntry_Filter 函数的所做的就是依据系统调用的功能号在 g_FakeSysCallTable 中索引出相应的 pFakeSysCall 对象,然后推断该系统调用是否须要hook,假设须要则将真实的系统调用地址保存到 pFakeSysCall->ulOrigSysCallAddr 中,并将 pFakeSysCall->ulFakeSysCallAddr 作为假系统调用的地址返回。

  这样的调用过程中动态获取真实系统调用地址的方法使 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;

  }

1.《ntcreatefile TsFltMgr.sys系统蓝屏的原因是什么》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《ntcreatefile TsFltMgr.sys系统蓝屏的原因是什么》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/464973.html

上一篇

笔记本电脑排名2015 2015笔记本电脑cpu天梯排名是怎样

下一篇

电脑桌面图标不显示 电脑桌面图标显示不正常怎么办?快速恢复不正常图标的方法

蓝屏代码0x000007b 电脑设置bios后出现蓝屏代码0x000007B该怎么办?

蓝屏代码0x000007b 电脑设置bios后出现蓝屏代码0x000007B该怎么办?

我们在使用bios时,有时会不小心设置一些我们所不懂的东西,而导致系统蓝屏,设置完bios后出现错误代码为0x000007B的蓝屏故障时该怎么解决?  1、设置完bios后重启电脑,刚进入windows读条状态,即弹出错误代码为0x000007B的蓝屏故障,如下图所示:  2、解决方法:  重启电脑,出现开机画面时可尝试按键盘上的F1、F2或De...

电脑乱码怎么解决 电脑系统显示乱码如何解决

电脑乱码怎么解决 电脑系统显示乱码如何解决

有网友的电脑出了问题,系统的菜单,标题等处变成了乱码,到百度知道求助,提供了一张如下的乱码图片,希望得到解决。出现乱码的有几种情况,一是系统乱码,主要是桌面,菜单,标题,对话框等处出现乱码。二是文档中的内容出现乱码,三是网页乱码,四是软件窗口乱码,上面网友出现的就是第一种情况“系统乱码”。本文用二种方法修复系统乱码的问题。  解决方法一:区域语言...

安全模式进去也是蓝屏 windows进入系统安全模式时蓝屏怎么办?

安全模式进去也是蓝屏 windows进入系统安全模式时蓝屏怎么办?

不管是普通进入系统还是进入系统安全模式都蓝屏。有时用着电脑正用着忽然蓝屏。内存原因引起的蓝屏,实在太多了,就一细说啥原因了,如果是台式电脑就直接拆开机箱,把内存拔掉,把内存金手指部分擦擦再重新插回去,最好同时把内存擦槽也擦一下。机箱都拆开了,检查一下是否灰尘过多,灰尘过多的话也清理一下。一般来说由内存原因引起的系统蓝屏太多,所以不管是什么原因就先...

cmd查ip地址 如何用cmd查看电脑IP cmd查看本机IP方法

cmd查ip地址 如何用cmd查看电脑IP cmd查看本机IP方法

如何用cmd查看电脑IP cmd查看本机IP方法  在填写有些软件的时候需要填写本机ip地址,而利用cmd查看本机IP地址十分方便。那么如何用cmd查看ip?下面就为大家介绍cmd查看本机ip方法,希望能帮到大家。  工具/原料  电脑一枚  cmd程序  方法/步骤  1、按 Win键+R 进入运行窗口。输入 cmd ,点确定。  2、出现cm...

c000005 应用程序无法正常启动错误代码c0000005怎么办

c000005 应用程序无法正常启动错误代码c0000005怎么办

打开程序出现提示“异常代码c0000005”,无法正常启动应用程序怎么办呢?这种情况多数是兼容性的问题造成的。  1、以最常用的ww为例,直接打开会出现“异常代码c0000005”。  2、现在只需右键主程序,选择-属性。  3、点击-兼容性标签。  4、勾选以兼容模式运行这个程序,并尝试选择合适的版本。  5、点击应用并确定。  6、再次打开W...

0x0000007a 电脑开机蓝屏代码0x0000007a怎么办

0x0000007a 电脑开机蓝屏代码0x0000007a怎么办

电脑开机蓝屏代码0x0000001a怎么办?电脑蓝屏是很多用户都遇到的情况,蓝屏的原因也有非常之多,每次蓝屏都有一个蓝屏代码,可以根据这个代码来判断具体的问题所在,需要的朋友可以参考下。  蓝屏故障,先看截图,查询停机码,再逐一排障。  1、有的电脑蓝屏之后一闪而过,根本看不清蓝屏的画面,主要是在操作系统中设置了自动重启的缘故,可以让其遇到蓝屏停...

0x0000007B 电脑开机蓝屏错误代码0x0000007B怎么办

0x0000007B 电脑开机蓝屏错误代码0x0000007B怎么办

电脑开机蓝屏错误代码0x0000007B怎么办?蓝屏停机码7B的出错案列比较多,这是一个和硬盘有关的故障,所以只要从这方面去逐一排障即可,下面我起来看看解决办法,需要的朋友可以参考下。  蓝屏停机码7B的出错案列比较多,这是一个和硬盘有关的故障,所以只要从这方面去逐一排障即可。  1、A problem has been detected and...

0x000000ed 电脑开机蓝屏代码为0x000000ED怎么办

0x000000ed 电脑开机蓝屏代码为0x000000ED怎么办

计算机开机出现蓝屏代码STOP(停止):0x000000ED,不能进入操作系统。如何解决蓝屏代码为0x000000ED电脑蓝屏问题呢?  1、左键双击:蓝屏助手(软媒魔方中有)图标。  2、在打开的蓝屏助手对话框,点击:代码查询,再输入蓝屏代码的最后两位代码,如:ED,点击:查询。  3、在蓝屏助手窗口,可以看到故障原因:一般是由于磁盘存在错误导...