The reason for tsfltmgr. sys system blue screen is QQ computer manager!

Source: Internet
Author: User
Tags ssdt

My colleague is a Windows XP system and runs normally. After it is disabled, it cannot be started the next day. The specific symptoms are as follows:

(1) Both the security mode and the security mode with network functions can be entered;

(2) In normal mode, restart if the windowxp scroll bar is not displayed;

(3) Go to security mode. After Automatic Restart is disabled, restart the instance properly. A blue screen is displayed and a tsfltmgr. sys memory error is reported!

After Internet queries and constant exploration, I finally found that the QQ Software manager was a curse. In the security mode, I decided to uninstall the QQ Software manager and restart it. The system was completely normal.


The following is a reprinted article on the analysis of QQ computer manager. For details, refer:

Tsfltmgr hook framework analysis in QQ Computer Manager


The new QQ computer manager has another name named tsfltmgr. sys Driver (which should have been developed by sysnap Daniel and worshipped), made some simple analysis on the driver, saw a set of beautiful hook frameworks, and shared them with you. Please forgive me for the incorrect analysis.

First, tsfltmgr hooks the kifastcallentry function. The hook points here:

Code:

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

The original kifastcallentry is in SHR ECx. The command 2 is followed by mov EDI, esp; cmp esi, mmuserprobeaddress, which contains 8 bytes. tsfltmgr replaces three NOP and one JMP.

The JMP will jump to the kifastcallentry_detour function. The code of the kifastcallentry_detour function is as follows:

Code:

// Save the field pushfd pushad // call the kifastcallentry_filter function to filter the push EDI // The syscall table address (ssdt or ssdtshadow address) of the system call) push EBX // The kernel function address corresponding to this system call in syscall table push eax // call kifastcallentry_filter in syscall table, implement filtering mov [esp + 10 h], eax // change the kernel function address corresponding to this call! // Restore the on-site popfd of popad // execute the command replaced by the kifastcallentry function and switch back to the original function mov EDI, espcmp ESI, g_7fff1_push g_jmpbackret

Note the mov [esp + 10 h] And eax values after the call kifastcallentry_filter. The command pushad before saving the field will cause the registers eax, ECx, EDX, EBX, ESP, EBP, ESI, and EDI to go to the stack in sequence, and use the following popad command to restore the value of these registers. Therefore, in mov [esp + 10 h], eax actually uses the return value of the kifastcallentry_filter function to rewrite the value of EBX stored in the stack, that is, the address of the kernel function corresponding to this system call.

Kifastcallentry_filter is a function that implements filtering. The parameters and return values of this function have been described above. After the specific implementation analysis, the C language is described as follows:

Code:

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;}

It should be noted that tsfltmgr has a table named g_fakesyscalltable, which stores a pointer to the fake_syscall structure. Each fake_syscall structure in the table corresponds to a system call. The first half of the table corresponds to the system call in ssdt, and the second half corresponds to the system call in shadowssdt.

The fake_syscall structure is roughly as follows (the functions of many of them are not clear ):

Code:

Typedef struct _ {ulong XXX1; ulong ulsyscallid; // function number called by the system: ulong xxx3; ulong ultableindex; ulong xxx5; ulong extension; ulong ulcountforpostwork; ulong xxx8; ulong ulorigsyscalladdr; // Real System Call address ulong ulfakesyscalladdr; // false System Call address ulong xxx11; ulong xxx12; ulong xxx13 ;......} Fake_syscall, * pfake_syscall, ** ppfake_syscall;

Therefore, what the kifastcallentry_filter function does is to extract the corresponding pfakesyscall object in g_fakesyscalltable Based on the function number called by the system, and then determine whether the hook is required for the system call, if necessary, save the real system call address to pfakesyscall-> ulorigsyscalladdr, and return pfakesyscall-> ulfakesyscalladdr as the fake System Call address.

This method of dynamically obtaining the actual system call address makes the hook framework of tsfltmgr highly compatible. For example, it does not invalidate the ssdt hook in the driver whose Loading Order is later than tsfltmgr, for example, the tsksp of QQ Computer Manager. SYS driver.

For my test system (xp_sp2), The tsfltmgr hook functions include:

Code:

// In ssdt: ntcreatefile, ntcreatekey, ntcreatesection, delimiter, delimiter, ntdeletefile, ntdeletekey, delimiter, ntloaddriver, ntopenprocess, ntopensection, delimiter, ntsetinformationfile, ntsetsysteminformation, ntsetvaluekey, ntsuspendthread, ntsystemdebugcontrol, ntterminateprocess, ntterminatethread, ntwritefile, ntwritevirtualmemory // shadowssdt: examples, examples, examples, ntusermovewindow, ntuserquerywindow, ntusersendinput, ntusersetparent, ntusersetwindowlong, ntusersetwindowplacement, ntusersetwindowpos, ntusershowwindow, ntusershowwindowasync, ntuserwindowfrompoint

All false system functions have a unified code framework. The code framework of false system functions is roughly as follows:

Code:

Ntstatus _ stdcall fakent_xxx (XXX) {pfake_syscall pfakesyscall; ulong ulxxx = 0; ulong ulstatus; ntstatus status; ulonglong ulltickcount; pfakesyscall = success; // This system calls the corresponding pfakesyscall object status = STATUS_ACCESS_DENIED; // It seems to be required for performance testing. In actual versions, g_bperformancetest is false if (g_bperformancetest) {ulltickcount = kequeryinterrupttime () ;}// pre-processing of system call! // ++ Interlockedincrement (& amp; response-> ulcountforprework); ulstatus = prework (& ulxxx, priority); interlockeddecrement (& pfakesyscall-> ulcountforprework); // --- If (ulstatus! = 0xeeee0004 & ulstatus! = 0xeeee0005) {origsyscall * porigsyscall = pfakesyscall-> ulorigsyscalladdr; // call the original system call! If (porigsyscall & nt_success (porigsyscall (XXX) {// post-processing of system call! // ++ Interlockedincrement (& pfakesyscall-> ulcountforpostwork), ulstatus = postwork (& ulxxx), interlockeddecrement (& pfakesyscall-> ulcountforpostwork ), // ---} // 0xeeee0004 indicates that the call is denied. 0xeeee0005 indicates that the call is allowed. If (ulstatus = 0xeeee0005) status = STATUS_SUCCESS; // The returned value of the call psgetcurrentprocessid is not used. It may be a redundant psgetcurrentprocessid (); // It seems to be the IF (g_pfakesyscall_ntterminateprocess-> xxx5 & ulltickcount & g_bperformancetest) {performancetest (& g_pfakesyscall_ntterminateprocess-> xxx13, ulltickcount);} return status ;}

The above is an analysis of the tsfltmgr hook framework. I wish you a happy Lantern Festival ~

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.