同事一WindowsXP系統(tǒng),正常執(zhí)行,關(guān)閉后,第二天無法啟動,詳細(xì)癥狀為:
(1)安全模式以及帶網(wǎng)絡(luò)功能的安全模式都能夠進(jìn)入;
(2)正常模式,還沒出現(xiàn)WindowXP滾動欄就開始重新啟動;
(3)進(jìn)安全模式,禁用自己主動重新啟動后,再正常啟動,出現(xiàn)藍(lán)屏,報TsFltMgr.sys內(nèi)存錯誤!
經(jīng)過互聯(lián)網(wǎng)查詢,和不斷摸索,最后發(fā)現(xiàn)居然是可惡的QQ軟件管家惹的禍,進(jìn)安全模式果斷卸載QQ軟件管家后,再重新啟動,系統(tǒng)全然正常了。
以下轉(zhuǎn)載了一篇分析QQ電腦管家的文章,請參考:
QQ電腦管家中的TsFltMgr?Hook框架分析
新版的QQ電腦管家中多了一個名字叫TsFltMgr.sys的驅(qū)動(應(yīng)該是Sysnap大牛開發(fā)的,膜拜),對該驅(qū)動進(jìn)行了一些簡單的分析,看見了一套美麗的Hook框架,發(fā)出來與大家分享。分析不正確的地方請多多包涵。
首先TsFltMgr掛鉤了KiFastCallEntry函數(shù),Hook點(diǎn)在這里:
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
該jmp會跳轉(zhuǎn)到?KiFastCallEntry_Detour?函數(shù)中,KiFastCallEntry_Detour?函數(shù)代碼例如以下:
//?保存現(xiàn)場 pushfd???????? pushad???????? //?調(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中的功能號 call?KiFastCallEntry_Filter?//?調(diào)用KiFastCallEntry_Filter,實(shí)現(xiàn)過濾 mov??[esp+10h],?eax?????????//?更改本次調(diào)用相應(yīng)的內(nèi)核函數(shù)地址! //?恢復(fù)現(xiàn)場 popad???????? popfd //?運(yùn)行?KiFastCallEntry?函數(shù)中被替換掉的指令,并跳回原函數(shù) mov?????edi,esp cmp?????esi,?g_7fff0000 push????g_JmpBack ret
KiFastCallEntry_Filter?是真正實(shí)現(xiàn)過濾的函數(shù),該函數(shù)的參數(shù)和返回值上文已經(jīng)說明了,其詳細(xì)實(shí)現(xiàn)分析整理后,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; }
當(dāng)中?FAKE_SYSCALL?結(jié)構(gòu)大致例如以下(當(dāng)中非常多域的作用沒弄明確):
typedef?struct?__FAKE_SYSCALL__?{ ????ULONG?xxx1; ????ULONG?ulSyscallId;????????//?該系統(tǒng)調(dià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;
這樣的調(diào)用過程中動態(tài)獲取真實(shí)系統(tǒng)調(diào)用地址的方法使?TsFltMgr?的Hook框架有較高的兼容性,比如不會使載入順序晚于TsFltMgr的驅(qū)動中的SSDT?Hook失效,比如QQ電腦管家本身帶的TSKsp.sys驅(qū)動。
對于我的測試系統(tǒng)(XP_SP2),TsFltMgr?hook的函數(shù)有:
//?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;??//?該系統(tǒng)調(diào)用相應(yīng)的?pFakeSysCall?對象 ???? ????status?=?STATUS_ACCESS_DENIED; ?? ????//?貌似是做性能測試時候須要的,實(shí)際版本號中?g_bPerformanceTest?為?FALSE ????if?(?g_bPerformanceTest?)?{ ????????ullTickCount?=?KeQueryInterruptTime(); ????} ????//?系統(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; ????????//?調(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), ????????????//?--- ????????} ????} ????//?0xEEEE0004?應(yīng)該是拒絕調(diào)用的意思,0xEEEE0005?應(yīng)該是同意調(diào)用的意思 ????if?(ulStatus?==?0xEEEE0005) ????????status?=?STATUS_SUCCESS; ????//?PsGetCurrentProcessId?這個調(diào)用的返回值后面并沒實(shí)用到,可能是多余的 ????PsGetCurrentProcessId(); ????//?貌似是做性能測試時候須要的 ????if?(?g_pFakeSysCall_NtTerminateProcess->xxx5?&&?ullTickCount?&&?g_bPerformanceTest)?{ ????????PerformanceTest(&g_pFakeSysCall_NtTerminateProcess->xxx13,?ullTickCount); ????} ????return?status; }
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
