win8的ntoskrnl.exe非常占CPU和狂读硬盘怎么解决
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了win8的ntoskrnl.exe非常占CPU和狂读硬盘怎么解决相关的知识,希望对你有一定的参考价值。
ntoskrnl.exe 是 Windows 操作系统的一个重要进程文件,在系统经过预启动和启动阶段后进入内核调用阶段时由 Ntldr 调用 ntoskrnl.exe, 在 Windows XP 系统中 ntoskrnl.exe 存储了启动 logo 画面。 调用 ntoskrnl.exe 文件时将由 ntdetect.com 收集的硬件信息传递给它,同时被调用的还有 hal.dll 文件。ntoskrnl.exe 是保护性的进程,在你的计算机反复启动的情况下出现。在正常情况下,在任务管理器是以"System"的名字出现的。注意:ntoskrnl.exe 也可能是 w32.bolzano 病毒,如果发现异常的 ntoskrnl.exe 文件,请立即使用杀毒软件进行查杀。 参考技术A 内存自动检测任务引起CPU占用,解决如下:1、控制面板-管理工具-任务计划程序-任务计划程序(本地)-详细信息下拉,
最下面找到process memory diagnostic events-双击,禁用相关的2个计划任务.
2、.Net 核心文件自动编译占用闲时CPU解决如下:
找到.Net Framework 计划任务下面的4个子任务,全部禁用或者手动执行一次后禁用。 参考技术B 杀掉它!估计是个病毒
ring0 ShadowSSDTHook
SSDT:主要处理 Kernel32.dll中的系统调用,如openProcess,ReadFile等,主要在ntoskrnl.exe中实现(微软有给出 ntoskrnl源代码)
ShadowSSDT: 1.主要处理,user32.dll,GDI32.dll中调用的函数,如postMessage,SendMessage,FindWindow,主要在win32k.sys中实现.(微软未给出win32k代码)
2.需要注意的是shadowSSDT并未导出,可用ida在win32k.sys中的导出表搜索,且结构与ssdt相似,但是不能通过windbg dd命令查看值
3.ShadowSSDT表只能在GUI(即有界面的程序进程)环境下才有值,故我们需要调用KeAttachProcess来切换到GUI线程里。
4.用windbg 命令 .process 861ff020 (861ff020 是通过 命令 !process 0 0得到的)切换到GUI线程上下文
过程:1)(输入windbg命令 ) !process 0 0得到其中一个有 图形界面的程序
(数据如下)
PROCESS 861ff020 SessionId: 0 Cid: 0b58 Peb: 7ffde000 ParentCid: 05e4
DirBase: 10080380 ObjectTable: e1dd2808 HandleCount: 73.
Image: windbg.exe
2) (输入命令)
lkd> .process 861ff020
Implicit process is now 861ff020
(切换成功 )
3) 切换成功后,使用dd KeServiceDescriptorTableShadow即可得到该表数据,否则无法得到,得到数据如下
lkd> dd KeServiceDescriptorTableShadow
80553f60 80502b8c 00000000 0000011c 80503000--〉SSDT
80553f70 bf999b80 00000000 0000029b bf99a890 --〉ShadowSSDT
80553f80 00000000 00000000 00000000 00000000
80553f90 00000000 00000000 00000000 00000000
80553fa0 80502b8c 00000000 0000011c 80503000
80553fb0 00000000 00000000 00000000 00000000
80553fc0 00000000 00000000 00000000 00000000
80553fd0 00000000 00000000 00000000 00000000
其实KeServiceDescriptorTableShadow 包含4个系统服务表,但是我们只用前2个(SSDT,ShadowSSDT)
4) 总结:
1) ShadowSSDT在KeServiceDescriptorTableShadow[1]中,而KeServiceDescriptorTableShadow[0]为ssdt
2)如果要查看win32k服务,必须要切换到GUI线程上下文
5.如何得到ShadowSSDT地址:在insight source中可查询到wrk中有KeAddSystemServiceTable函数,里面有对KeServiceDescriptorTableShadow 的调用
思路:利用搜索特征码的方式搜索KeAddSystemServiceTable,取出KeServiceDescriptorTableShadow
64位
HOOK 和 UNHOOK SHADOW SSDT 跟之前的 HOOK/UNHOOK SSDT 类似,区别是查找SSSDT的特征码,以及根据索引计算函数地址的公式,还有一个就是吧跳转函数写在什么位置,SSDT的时候是写在蓝屏函数里了。
一、获得 w KeServiceDescriptorTableShadow的地址
这个跟获得 KeServiceDescriptorTable 差不多,唯一不同就是特征码:
#include "ShadowSSDTHook.h" int NtUserFindWindowExIndex = 378; pfnNtUserFindWindowEx OldNtUserFindWindowEx = NULL; //ShadowSSDT PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorShadowTable; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath) { PDEVICE_OBJECT DeviceObject; NTSTATUS Status; int i = 0; PEPROCESS EProcess; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; RtlInitUnicodeString(&DeviceName,DEVICE_NAME); RtlInitUnicodeString(&LinkName,LINK_NAME); //创建设备对象; Status = IoCreateDevice(DriverObject,0, &DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject); if (!NT_SUCCESS(Status)) { return Status; } Status = IoCreateSymbolicLink(&LinkName,&DeviceName); for (i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DefaultPassThrough; } DriverObject->DriverUnload = UnloadDriver; KeServiceDescriptorShadowTable = GetShadowTableAddress(); if (KeServiceDescriptorShadowTable) { if (LookupProcessByName("explorer.exe", &EProcess) == STATUS_SUCCESS) { KeAttachProcess(EProcess);//附加到目标进程 HookShadowSSDTTable(&KeServiceDescriptorShadowTable[1], &NtUserFindWindowExIndex, &(ULONG_PTR)OldNtUserFindWindowEx, (ULONG_PTR)FakeNtUserFindWindowEx); KeDetachProcess();//解除附加 } } #ifdef WIN64 // __asm // { // xchg rax,rbx // } DbgPrint("WIN64: ShadowSSDTHook IS RUNNING!!!"); #else // __asm // { // xor eax,eax // } DbgPrint("WIN32: ShadowSSDTHook SIS RUNNING!!!"); #endif return STATUS_SUCCESS; } NTSTATUS DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; } VOID UnloadDriver(PDRIVER_OBJECT DriverObject) { PEPROCESS EProcess; UNICODE_STRING LinkName; PDEVICE_OBJECT NextDeviceObject = NULL; PDEVICE_OBJECT CurrentDeviceObject = NULL; RtlInitUnicodeString(&LinkName,LINK_NAME); IoDeleteSymbolicLink(&LinkName); CurrentDeviceObject = DriverObject->DeviceObject; while (CurrentDeviceObject != NULL) { NextDeviceObject = CurrentDeviceObject->NextDevice; IoDeleteDevice(CurrentDeviceObject); CurrentDeviceObject = NextDeviceObject; } KeServiceDescriptorShadowTable = GetShadowTableAddress(); if (KeServiceDescriptorShadowTable) { //获取一个gui线程的进程对象。 if (LookupProcessByName("explorer.exe", &EProcess) == STATUS_SUCCESS) { KeAttachProcess(EProcess);//附加到目标进程 UnHookShadowSSDTTable(&KeServiceDescriptorShadowTable[1], &NtUserFindWindowExIndex, (ULONG_PTR)OldNtUserFindWindowEx); KeDetachProcess();//解除附加 } } DbgPrint("ShadowSSDTHook IS STOPPED!!!"); } PVOID GetShadowTableAddress() { ULONG_PTR ulData = 0; ULONG_PTR i = 0; PUCHAR Temp = (PUCHAR)KeAddSystemServiceTable; //类似王艳萍的内存修改器做法 //扫描特征码 for (i = 0; i<4096; i++, Temp++) { __try { ulData = *(ULONG_PTR*)Temp; } __except (EXCEPTION_EXECUTE_HANDLER) { return FALSE; } if (MmIsAddressValid((PVOID)ulData)) { if (memcmp((PVOID)ulData, KeServiceDescriptorTable, 16) == 0) { if ((PVOID)ulData == KeServiceDescriptorTable) //排除SSDT { continue; } return (PVOID)ulData; } } } return FALSE; } NTSTATUS LookupProcessByName( IN PCHAR ProcessName, OUT PEPROCESS *EProcess ) { NTSTATUS status; ULONG uCount = 0; ULONG uLength = 0; PLIST_ENTRY ListActiveProcess; PEPROCESS CurrentEProcess = NULL; ULONG ulNextProcess = 0; ULONG g_Offset_Eprocess_Flink = 0x88; //XP操作系统 char lpszProName[100]; char *lpszAttackProName = NULL; uLength = strlen(ProcessName); CurrentEProcess = PsGetCurrentProcess(); ulNextProcess = (ULONG)CurrentEProcess; __try { memset(lpszProName, 0, sizeof(lpszProName)); if (uLength > 15) { strncat(lpszProName, ProcessName, 15); } while (1) { lpszAttackProName = NULL; lpszAttackProName = (char *)PsGetProcessImageFileName(CurrentEProcess); if (uLength > 15) { if (lpszAttackProName && strlen(lpszAttackProName) == uLength) { if (_strnicmp(lpszProName, lpszAttackProName, uLength) == 0) { *EProcess = CurrentEProcess; status = STATUS_SUCCESS; break; } } } else { if (lpszAttackProName && strlen(lpszAttackProName) == uLength) { if (_strnicmp(ProcessName, lpszAttackProName, uLength) == 0) { *EProcess = CurrentEProcess; status = STATUS_SUCCESS; break; } } } if ((uCount >= 1) && (ulNextProcess == (ULONG)CurrentEProcess)) { *EProcess = 0x00000000; status = STATUS_NOT_FOUND; break; } ListActiveProcess = (LIST_ENTRY *)((ULONG)CurrentEProcess + g_Offset_Eprocess_Flink); (ULONG)CurrentEProcess = (ULONG)ListActiveProcess->Flink; (ULONG)CurrentEProcess = (ULONG)CurrentEProcess - g_Offset_Eprocess_Flink; uCount++; } } __except (EXCEPTION_EXECUTE_HANDLER) { KdPrint(("LookupProcessByName:%08x\\r\\n", GetExceptionCode())); status = STATUS_NOT_FOUND; } return status; } BOOLEAN HookShadowSSDTTable(PSERVICE_DESCRIPTOR_TABLE ServiceDescriptorShadowSSDTTable, int *Index, ULONG_PTR *OldFuctionAddress, ULONG_PTR FakeFuctionAddress) { BOOLEAN bRetOK = FALSE; __try { //检查 if (MmIsAddressValid(ServiceDescriptorShadowSSDTTable) && MmIsAddressValid(ServiceDescriptorShadowSSDTTable->ServiceTable)) { //检查*index是否在表的有效范围 if (*Index >= 0 && *Index <(int)ServiceDescriptorShadowSSDTTable->TableSize) { //保存原始函数,因为我们的hook过滤函数需要用到。 *OldFuctionAddress = ServiceDescriptorShadowSSDTTable->ServiceTable[*Index]; WPOFF(); InterlockedExchange(&ServiceDescriptorShadowSSDTTable->ServiceTable[*Index], FakeFuctionAddress); bRetOK = TRUE; WPON(); } } } __except (EXCEPTION_EXECUTE_HANDLER) { } return bRetOK; } NTSTATUS FakeNtUserFindWindowEx(ULONG_PTR hWndParent, ULONG_PTR hWndChild, PUNICODE_STRING uniClassName, PUNICODE_STRING uniWindowName, ULONG_PTR Type) { char* ProcessName = NULL; PEPROCESS EProcess; EProcess = IoGetCurrentProcess(); ProcessName = PsGetProcessImageFileName(EProcess); //进行过滤 if (strstr(ProcessName, "Test.exe") != NULL) { DbgPrint("HookFindWindow\\r\\n"); return STATUS_SUCCESS; } return OldNtUserFindWindowEx(hWndParent, hWndChild, uniClassName, uniWindowName, Type); } //去掉内存保护 void WPOFF() { __asm { cli mov eax, cr0 and eax, not 10000h mov cr0, eax } } //恢复内存保护 void WPON() { __asm { mov eax, cr0 or eax, 10000h mov cr0, eax sti } } BOOLEAN UnHookShadowSSDTTable(PSERVICE_DESCRIPTOR_TABLE ServiceDescriptorShadowSSDTTable, int *Index, ULONG_PTR OldFuctionAddress) { BOOLEAN bRetOK = FALSE; __try { //检查 if (MmIsAddressValid(ServiceDescriptorShadowSSDTTable) && MmIsAddressValid(ServiceDescriptorShadowSSDTTable->ServiceTable)) { //检查*index是否在表的有效范围 if (*Index >= 0 && *Index <(int)ServiceDescriptorShadowSSDTTable->TableSize) { WPOFF(); InterlockedExchange(&ServiceDescriptorShadowSSDTTable->ServiceTable[*Index], OldFuctionAddress); bRetOK = TRUE; WPON(); } } } __except (EXCEPTION_EXECUTE_HANDLER) { } return bRetOK; }
#include <ntifs.h> #ifndef CXX_ShadowSSDTHook_H #define CXX_ShadowSSDTHook_H #define DEVICE_NAME L"\\\\Device\\\\ShadowSSDTHookDevice" #define LINK_NAME L"\\\\??\\\\ShadowSSDTHookLink" typedef struct _SERVICE_DESCRIPTOR_TABLE { PULONG ServiceTable; PULONG CounterTable; ULONG TableSize; PUCHAR ArgumentTable; } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE; //SSDT表 extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; extern UCHAR *PsGetProcessImageFileName(PEPROCESS eprocess); typedef NTSTATUS(*pfnNtUserFindWindowEx)(ULONG_PTR hWndParent, ULONG_PTR hWndChild, PUNICODE_STRING uniClassName, PUNICODE_STRING uniWindowName, ULONG_PTR Type); __declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID); VOID UnloadDriver(PDRIVER_OBJECT DriverObject); PVOID GetShadowTableAddress(); NTSTATUS LookupProcessByName(IN PCHAR ProcessName, OUT PEPROCESS * EProcess); BOOLEAN HookShadowSSDTTable(PSERVICE_DESCRIPTOR_TABLE ServiceDescriptorShadowSSDTTable, int * Index, ULONG_PTR * OldFuctionAddress, ULONG_PTR FakeFuctionAddress); NTSTATUS FakeNtUserFindWindowEx(ULONG_PTR hWndParent, ULONG_PTR hWndChild, PUNICODE_STRING uniClassName, PUNICODE_STRING uniWindowName, ULONG_PTR Type); void WPOFF(); void WPON(); BOOLEAN UnHookShadowSSDTTable(PSERVICE_DESCRIPTOR_TABLE ServiceDescriptorShadowSSDTTable, int * Index, ULONG_PTR OldFuctionAddress); NTSTATUS DefaultPassThrough(PDEVICE_OBJECT DeviceObject,PIRP Irp); #endif
以上是关于win8的ntoskrnl.exe非常占CPU和狂读硬盘怎么解决的主要内容,如果未能解决你的问题,请参考以下文章
win7 system进程 ntoskrnl.exe占用CPU很高
win7系统装完诺顿后,ntoskrnl.exe占用CPU高
System中 线程TID48 ntoskrnl.exe!ExQueueWorkItem+0x2f有时突然占用CPU30%到40%