欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TsFltMgr.sys系統(tǒng)藍(lán)屏的原因分析(小心QQ電腦管家)

  發(fā)布時(shí)間:2015-03-13 14:36:01   作者:佚名   我要評(píng)論
經(jīng)過互聯(lián)網(wǎng)查詢,和不斷摸索,最后發(fā)現(xiàn)居然是可惡的QQ軟件管家惹的禍,進(jìn)安全模式果斷卸載QQ軟件管家后,再重新啟動(dòng),系統(tǒng)全然正常了

同事一WindowsXP系統(tǒng),正常執(zhí)行,關(guān)閉后,第二天無法啟動(dòng),詳細(xì)癥狀為:

(1)安全模式以及帶網(wǎng)絡(luò)功能的安全模式都能夠進(jìn)入;
(2)正常模式,還沒出現(xiàn)WindowXP滾動(dòng)欄就開始重新啟動(dòng);
(3)進(jìn)安全模式,禁用自己主動(dòng)重新啟動(dòng)后,再正常啟動(dòng),出現(xiàn)藍(lán)屏,報(bào)TsFltMgr.sys內(nèi)存錯(cuò)誤!

經(jīng)過互聯(lián)網(wǎng)查詢,和不斷摸索,最后發(fā)現(xiàn)居然是可惡的QQ軟件管家惹的禍,進(jìn)安全模式果斷卸載QQ軟件管家后,再重新啟動(dòng),系統(tǒng)全然正常了。

以下轉(zhuǎn)載了一篇分析QQ電腦管家的文章,請(qǐng)參考:

QQ電腦管家中的TsFltMgr Hook框架分析

新版的QQ電腦管家中多了一個(gè)名字叫TsFltMgr.sys的驅(qū)動(dòng)(應(yīng)該是Sysnap大牛開發(fā)的,膜拜),對(duì)該驅(qū)動(dòng)進(jìn)行了一些簡單的分析,看見了一套美麗的Hook框架,發(fā)出來與大家分享。分析不正確的地方請(qǐng)多多包涵。
首先TsFltMgr掛鉤了KiFastCallEntry函數(shù),Hook點(diǎn)在這里:

代碼:


復(fù)制代碼
代碼如下:

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 指令后面應(yīng)該是 mov edi,esp;cmp esi, MmUserProbeAddress,共8個(gè)字節(jié),在這里被 TsFltMgr 替換成了3個(gè)nop和一個(gè)jmp。

該jmp會(huì)跳轉(zhuǎn)到 KiFastCallEntry_Detour 函數(shù)中,KiFastCallEntry_Detour 函數(shù)代碼例如以下:

代碼:


復(fù)制代碼
代碼如下:

// 保存現(xiàn)場(chǎng)
pushfd
pushad </p> <p>// 調(diào)用 KiFastCallEntry_Filter 函數(shù),實(shí)現(xiàn)過濾
push edi // 本次系統(tǒng)調(diào)用相應(yīng)的SysCall Table的地址(SSDT或SSDTShadow的地址)
push ebx // 本次系統(tǒng)調(diào)用在SysCall Table中相應(yīng)的內(nèi)核函數(shù)地址
push eax // 本次系統(tǒng)調(diào)用相應(yīng)的內(nèi)核函數(shù)在SysCall Table中的功能號(hào)
call KiFastCallEntry_Filter // 調(diào)用KiFastCallEntry_Filter,實(shí)現(xiàn)過濾
mov [esp+10h], eax // 更改本次調(diào)用相應(yīng)的內(nèi)核函數(shù)地址!</p> <p>// 恢復(fù)現(xiàn)場(chǎng)
popad
popfd</p> <p>// 運(yùn)行 KiFastCallEntry 函數(shù)中被替換掉的指令,并跳回原函數(shù)
mov edi,esp
cmp esi, g_7fff0000
push g_JmpBack
ret

這里須要注意的是 call KiFastCallEntry_Filter 之后的 mov [esp+10h], eax。之前保存現(xiàn)場(chǎng)時(shí)的指令pushad會(huì)導(dǎo)致寄存器EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI依次入棧,并通過后面的popad指令恢復(fù)這些寄存器的值。因此此處的mov [esp+10h], eax實(shí)際上是用 KiFastCallEntry_Filter 函數(shù)的返回值來改寫堆棧中保存的ebx的值,即改寫本次系統(tǒng)調(diào)用相應(yīng)的內(nèi)核函數(shù)地址。

KiFastCallEntry_Filter 是真正實(shí)現(xiàn)過濾的函數(shù),該函數(shù)的參數(shù)和返回值上文已經(jīng)說明了,其詳細(xì)實(shí)現(xiàn)分析整理后,C語言描寫敘述例如以下:

代碼:


復(fù)制代碼
代碼如下:

ULONG __stdcall KiFastCallEntry_Filter(ULONG ulSyscallId, ULONG ulSyscallAddr, PULONG pulSyscallTable)
{
PFAKE_SYSCALL pFakeSysCall = NULL;</p> <p> if ( ulSyscallId >= 0x400 )
return ulSyscallAddr;</p> <p> 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
}</p> <p> if ( pFakeSysCall && pFakeSysCall->ulFakeSysCallAddr )
{
pFakeSysCall->ulOrigSysCallAddr = ulSyscallAddr;
return pFakeSysCall->ulFakeSysCallAddr;
}
return ulSyscallAddr;
}

這里須要說明的是,TsFltMgr內(nèi)部有一張表,暫且命名為 g_FakeSysCallTable,該表中存放的是指向 FAKE_SYSCALL 結(jié)構(gòu)的指針。表中的每個(gè) FAKE_SYSCALL 結(jié)構(gòu)相應(yīng)一個(gè)系統(tǒng)調(diào)用,表的前半部分相應(yīng)SSDT中的系統(tǒng)調(diào)用,1024項(xiàng)以后相應(yīng)ShadowSSDT里的系統(tǒng)調(diào)用。

當(dāng)中 FAKE_SYSCALL 結(jié)構(gòu)大致例如以下(當(dāng)中非常多域的作用沒弄明確):

代碼:


復(fù)制代碼
代碼如下:

typedef struct __FAKE_SYSCALL__ {
ULONG xxx1;
ULONG ulSyscallId; // 該系統(tǒng)調(diào)用的功能號(hào)
ULONG xxx3;
ULONG ulTableIndex;
ULONG xxx5;
ULONG ulCountForPreWork;
ULONG ulCountForPostWork;
ULONG xxx8;
ULONG ulOrigSysCallAddr; // 真實(shí)的系統(tǒng)調(diào)用地址
ULONG ulFakeSysCallAddr; // 假的系統(tǒng)調(diào)用地址
ULONG xxx11;
ULONG xxx12;
ULONG xxx13;
……
} FAKE_SYSCALL, *PFAKE_SYSCALL, **PPFAKE_SYSCALL;

因此 KiFastCallEntry_Filter 函數(shù)的所做的就是依據(jù)系統(tǒng)調(diào)用的功能號(hào)在 g_FakeSysCallTable 中索引出相應(yīng)的 pFakeSysCall 對(duì)象,然后推斷該系統(tǒng)調(diào)用是否須要hook,假設(shè)須要?jiǎng)t將真實(shí)的系統(tǒng)調(diào)用地址保存到 pFakeSysCall->ulOrigSysCallAddr 中,并將 pFakeSysCall->ulFakeSysCallAddr 作為假系統(tǒng)調(diào)用的地址返回。

這樣的調(diào)用過程中動(dòng)態(tài)獲取真實(shí)系統(tǒng)調(diào)用地址的方法使 TsFltMgr 的Hook框架有較高的兼容性,比如不會(huì)使載入順序晚于TsFltMgr的驅(qū)動(dòng)中的SSDT Hook失效,比如QQ電腦管家本身帶的TSKsp.sys驅(qū)動(dòng)。

對(duì)于我的測(cè)試系統(tǒng)(XP_SP2),TsFltMgr hook的函數(shù)有:

代碼:


復(fù)制代碼
代碼如下:

// 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</p> <p>// ShadowSSDT中:
NtUserBuildHwndList、NtUserFindWindowEx、NtUserGetForegroundWindow、NtUserMoveWindow、NtUserQueryWindow、NtUserSendInput、NtUserSetParent、NtUserSetWindowLong、NtUserSetWindowPlacement、NtUserSetWindowPos、NtUserShowWindow、NtUserShowWindowAsync、NtUserWindowFromPoint

全部假系統(tǒng)函數(shù)都有統(tǒng)一的代碼框架,假系統(tǒng)函數(shù)的代碼框架大致例如以下:

代碼:

復(fù)制代碼
代碼如下:

NTSTATUS __stdcall FakeNt_XXX(xxx)
{
PFAKE_SYSCALL pFakeSysCall;
ULONG ulXXX = 0;
ULONG ulStatus;
NTSTATUS status;
ULONGLONG ullTickCount;

pFakeSysCall = g_pFakeSysCall_Nt_XXX; // 該系統(tǒng)調(diào)用相應(yīng)的 pFakeSysCall 對(duì)象

status = STATUS_ACCESS_DENIED;
</p> <p> // 貌似是做性能測(cè)試時(shí)候須要的,實(shí)際版本號(hào)中 g_bPerformanceTest 為 FALSE
if ( g_bPerformanceTest ) {
ullTickCount = KeQueryInterruptTime();
}</p> <p>
// 系統(tǒng)調(diào)用的調(diào)用前處理!
// +++
InterlockedIncrement(&pFakeSysCall->ulCountForPreWork);
ulStatus = PreWork(&ulXXX, pFakeSysCall);
InterlockedDecrement(&pFakeSysCall->ulCountForPreWork);
// ---

if ( ulStatus != 0xEEEE0004 && ulStatus != 0xEEEE0005)
{
OrigSysCall * pOrigSysCall = pFakeSysCall->ulOrigSysCallAddr;</p> <p> // 調(diào)用原始系統(tǒng)調(diào)用!
if ( pOrigSysCall && NT_SUCCESS(pOrigSysCall(xxx)) )
{
// 系統(tǒng)調(diào)用的調(diào)用后處理!
// +++
InterlockedIncrement(&pFakeSysCall->ulCountForPostWork),
ulStatus = PostWork(&ulXXX),
InterlockedDecrement(&pFakeSysCall->ulCountForPostWork),
// ---
}
}</p> <p> // 0xEEEE0004 應(yīng)該是拒絕調(diào)用的意思,0xEEEE0005 應(yīng)該是同意調(diào)用的意思
if (ulStatus == 0xEEEE0005)
status = STATUS_SUCCESS;</p> <p> // PsGetCurrentProcessId 這個(gè)調(diào)用的返回值后面并沒實(shí)用到,可能是多余的
PsGetCurrentProcessId();</p> <p> // 貌似是做性能測(cè)試時(shí)候須要的
if ( g_pFakeSysCall_NtTerminateProcess->xxx5 && ullTickCount && g_bPerformanceTest) {
PerformanceTest(&g_pFakeSysCall_NtTerminateProcess->xxx13, ullTickCount);
}</p> <p> return status;
}

以上就是對(duì)TsFltMgr Hook框架的一些分析,祝大家元宵快樂~ 

相關(guān)文章

最新評(píng)論