首页
社区
课程
招聘
未解决 [求助]cr0的写保护位修改后会蓝屏,帮忙看一下。
发表于: 2020-3-16 13:58 2836

未解决 [求助]cr0的写保护位修改后会蓝屏,帮忙看一下。

2020-3-16 13:58
2836
my_ssdt.h
#pragma once
#include <ntddk.h>
#include <windef.h>

VOID Unload(__in struct _DRIVER_OBJECT  *DriverObject);

NTSTATUS Dispatch_func(__in PDEVICE_OBJECT pDevObj, __in PIRP pIrp);

//定义ssdt表结构体
typedef struct _ServiceDescriptorTable {
	PVOID ServiceTableBase;
	PVOID ServiceCounterTable;
	unsigned int NumberOfServices;
	PVOID ParamTableBase;
}*PServiceDescriptorTable;
extern PServiceDescriptorTable KeServiceDescriptorTable;
//extern LONG KeServiceDescriptorTable;

#pragma pack(1)
typedef struct _JmpCode{
	BYTE E9;
	DWORD JmpAddr;
}JCode, *pJCode;
#pragma pack()
ULONG cur, old;
JCode HookJC;

//获取NtClose当前在ssdt中的地址
ULONG GetCurrentAddr() {
	LONG t_addr, SSDT_Adr;

	t_addr = KeServiceDescriptorTable->ServiceTableBase;
	
	SSDT_Adr = t_addr + 0x19 * 4;
	KdPrint(("NtClose在0环中当前的地址是%x \n", *(PLONG)SSDT_Adr));

	return (ULONG)(*(PLONG)SSDT_Adr);
}

//获取NtClose当前在ssdt中的地址(汇编)
ULONG GetCurrentAddr_asm() {
	ULONG Addr;
	KdPrint(("PServiceDescriptorTable = %x", KeServiceDescriptorTable));
	
	__asm
	{
		push ebx
		push eax
			
			int 3
			
			mov ebx, KeServiceDescriptorTable	//ssdt的位置
			mov ebx, [ebx]
			mov eax, 19h
			shl eax, 2
			mov ebx, [ebx+eax]
			mov Addr, ebx
		pop eax
		pop ebx
	}
	KdPrint(("(汇编)NtClose在0环中当前的地址是%x \n", Addr));
	return Addr;
}

//获取NtClose在ssdt中的原始地址
ULONG GetOldAddr()
{
	UNICODE_STRING Old_NtClose;
	ULONG Old_addr;
	
	RtlInitUnicodeString(&Old_NtClose, L"NtClose");
	//MmGetSystemRoutineAddress只能查被导出了的函数,未被导出的函数查不到。
	Old_addr = MmGetSystemRoutineAddress(&Old_NtClose);	

	KdPrint(("NtClosede在0环中原始的地址是%x \n", Old_addr));
	return Old_addr;
}

//脱钩
VOID UnHook()
{
	pJCode pJC_cur, pJC_old;

	pJC_cur = (pJCode)cur;
	pJC_old = (pJCode)old;

	//修改cr0寄存器,关闭页写保护;CR0的第17位,1表示保护,0表示为保护。
	/*这段代码加了之后运行会蓝屏。去掉就好了。
        __asm
	{
		cli 

		push eax

		mov eax, cr0
		and eax, not 10000h
		mov cr0, eax

		pop eax
	}*/

	HookJC.E9 = pJC_cur->E9;
	HookJC.JmpAddr = pJC_cur->JmpAddr;

	pJC_cur->E9 = 0xE9;
	pJC_cur->JmpAddr = (DWORD)pJC_old - (DWORD)pJC_cur - 5;

	//恢复cr0寄存器,开启页写保护。
	__asm
	{
		push eax
			
		mov eax, cr0
		or eax, 10000h
		mov cr0, eax

		pop eax
	}
}

//恢复脱钩
VOID ReHook()
{
	pJCode pJC_cur;
	pJC_cur = (pJCode)cur;

	//修改cr0寄存器,关闭页写保护;CR0的第17位,1表示保护,0表示为保护。
	__asm
	{
		cli

		push eax

		mov eax, cr0
		and eax, not 10000h
		mov cr0, eax

		pop eax
	}

	pJC_cur->E9 = HookJC.E9;
	pJC_cur->JmpAddr = HookJC.JmpAddr;

	//恢复cr0寄存器,开启页写保护。
	__asm
	{
		push eax

		mov eax, cr0
		or eax, 10000h
		mov cr0, eax

		pop eax
	}
}

//修改指定内存的数据
VOID ModifyMem() 
{


}

main.c
#include "my_ssdt.h"

NTSTATUS DriverEntry(
	__in PDRIVER_OBJECT DriverObject,
	__in PUNICODE_STRING RegistryPathName
)
{
	KdBreakPoint();
	
	KdPrint(("DriverEntry"));
	//DbgPrint(("DriverEntry"));	KdPrint和DbgPrint的区别是,KdPrint在Release版本中会被忽略。
	
	old = GetOldAddr();
	cur = GetCurrentAddr();
	//GetCurrentAddr_asm();
	if (old != cur)
	{
		KdPrint(("NtClose已经被Hook了 \n"));
		
		KdPrint(("现在来将这个函数脱钩 \n"));
		UnHook();
		KdPrint(("改完了,看一下 \n"));
	}

	DriverObject->DriverUnload = Unload;
	
	DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch_func;
	DriverObject->MajorFunction[IRP_MJ_READ] = Dispatch_func;
	DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch_func;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch_func;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch_func;

	return STATUS_SUCCESS;
}

VOID Unload(
	__in struct _DRIVER_OBJECT  *DriverObject
)
{
	KdBreakPoint();

	KdPrint(("Unload"));
	//GetCurrentAddr_asm();
	ReHook();
}

NTSTATUS Dispatch_func(__in PDEVICE_OBJECT pDevObj, __in PIRP pIrp)
{
	//对响应的IRP进行处理
	pIrp->IoStatus.Information = 0;
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	KdPrint(("完成派遣函数"));

	return STATUS_SUCCESS;
}


帮忙看下UnHook函数,这段代码把cr0的第17位改成0,然后修改了被hook的函数让它跳到正常的位置。功能是把被procmon24.sys钩住的ntclose函数还原。

但是加上第88到第100行这段代码后运行会蓝屏,去掉就好了。

这是为啥?

我查过了pde和pte,要修改的地址的物理页是可以写的,理论上不需要改cr0页可以写。但是为什么我加了这段代码会蓝屏呢?

这是!analyze -v现实的信息
1: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: d9234d57, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: ee133f61, If non-zero, the instruction address which referenced the bad memory
	address.
Arg4: 00000000, (reserved)

Debugging Details:
------------------

*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: kernel32!pNlsUserInfo                         ***
***                                                                   ***
*************************************************************************

WRITE_ADDRESS:  d9234d57 

FAULTING_IP: 
PROCMON24+8f61
ee133f61 ff85ff0f84ea    inc     dword ptr [ebp-157BF001h]

MM_INTERNAL_CODE:  0

IMAGE_NAME:  PROCMON24.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  5a8222fc

MODULE_NAME: PROCMON24

FAULTING_MODULE: ee12b000 PROCMON24

DEFAULT_BUCKET_ID:  DRIVER_FAULT

BUGCHECK_STR:  0x50

PROCESS_NAME:  services.exe

TRAP_FRAME:  ee9f3cd0 -- (.trap 0xffffffffee9f3cd0)
ErrCode = 00000002
eax=00000019 ebx=ee133f50 ecx=00000000 edx=ee9ecfa0 esi=00ccf7c8 edi=64804dd2
eip=ee133f61 esp=ee9f3d44 ebp=ee9f3d58 iopl=0         nv up ei ng nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010292
PROCMON24+0x8f61:
ee133f61 ff85ff0f84ea    inc     dword ptr [ebp-157BF001h] ss:0010:d9234d57=????????
Resetting default scope

LAST_CONTROL_TRANSFER:  from 804f9df9 to 8052c5dc

STACK_TEXT:  
ee9f3804 804f9df9 00000003 d9234d57 00000000 nt!RtlpBreakWithStatusInstruction
ee9f3850 804fa9e4 00000003 00000000 c06c91a0 nt!KiBugCheckDebugBreak+0x19
ee9f3c30 804faf33 00000050 d9234d57 00000001 nt!KeBugCheck2+0x574
ee9f3c50 8052136a 00000050 d9234d57 00000001 nt!KeBugCheckEx+0x1b
ee9f3cb8 80545578 00000001 d9234d57 00000000 nt!MmAccessFault+0x9a8
ee9f3cb8 ee133f61 00000001 d9234d57 00000000 nt!KiTrap0E+0xd0
WARNING: Stack unwind information not available. Following frames may be wrong.
ee9f3d58 8054261c 000003c8 00ccf7dc 7c92e4f4 PROCMON24+0x8f61
ee9f3d58 7c92e4f4 000003c8 00ccf7dc 7c92e4f4 nt!KiFastCallEntry+0xfc
00ccf7b8 7c92cfdc 010075da 000003c8 00000000 ntdll!KiFastSystemCallRet
00ccf7bc 010075da 000003c8 00000000 006c60dc ntdll!ZwClose+0xc
00ccf7dc 010074e9 00000000 00000000 006c6068 services!ScGetClientSid+0xc3
00ccf860 01006991 0000001d 006c60dc 00000000 services!ScLogControlEvent+0x68
00ccf880 01005e0d 000cd260 00000000 00000000 services!RStartServiceW+0xa0
00ccf8cc 77e599f4 000cd260 00000000 00000000 services!RStartServiceA+0xbd
00ccf8ec 77ed421a 01005de7 00ccf900 00000003 RPCRT4!Invoke+0x30
00ccfcf4 77ed46ee 00000000 00000000 000c89cc RPCRT4!NdrStubCall2+0x297
00ccfd10 77e594bd 000c89cc 000af078 000c89cc RPCRT4!NdrServerCall2+0x19
00ccfd44 77e59422 01002579 000c89cc 00ccfdec RPCRT4!DispatchToStubInC+0x38
00ccfd98 77e5934e 0000001f 00000000 0101a150 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x113
00ccfdbc 77e5be64 000c89cc 00000000 0101a150 RPCRT4!RPC_INTERFACE::DispatchToStub+0x84
00ccfdf8 77e5bcc1 000ceed0 000a5940 000cc160 RPCRT4!LRPC_SCALL::DealWithRequestMessage+0x2db
00ccfe1c 77e5bc05 000a597c 00ccfe38 000cc160 RPCRT4!LRPC_ADDRESS::DealWithLRPCRequest+0x16d
00ccff80 77e56caf 00ccffa8 77e56ad1 000a5940 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0x310
00ccff88 77e56ad1 000a5940 00000000 01001906 RPCRT4!RecvLotsaCallsWrapper+0xd
00ccffa8 77e56c97 000ab378 00ccffec 7c80b713 RPCRT4!BaseCachedThreadRoutine+0x79
00ccffb4 7c80b713 000cdf18 00000000 01001906 RPCRT4!ThreadStartRoutine+0x1a
00ccffec 00000000 77e56c7d 000cdf18 00000000 kernel32!BaseThreadStart+0x37


STACK_COMMAND:  kb

FOLLOWUP_IP: 
PROCMON24+8f61
ee133f61 ff85ff0f84ea    inc     dword ptr [ebp-157BF001h]

SYMBOL_STACK_INDEX:  6

SYMBOL_NAME:  PROCMON24+8f61

FOLLOWUP_NAME:  MachineOwner

FAILURE_BUCKET_ID:  0x50_PROCMON24+8f61

BUCKET_ID:  0x50_PROCMON24+8f61

Followup: MachineOwner
---------


看样子是procmon24.sys这个驱动程序导致的蓝屏,但是我不知道为什么。

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 188
活跃值: (581)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
忘记说了,是xp系统。
2020-3-16 14:20
0
雪    币: 210
活跃值: (1627)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
老生常谈的问题了 这个问题再看雪都看到不下于三四次了 去搜索下titanHide怎么写hook的吧 mdl不香么 非要用cr0
2020-3-16 14:41
0
雪    币: 188
活跃值: (581)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
4
cli和sti这两条命令要加;,不然就会蓝屏。。。晕
2020-3-16 17:26
0
雪    币: 83
活跃值: (1082)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
原来如此
2020-3-17 04:06
0
游客
登录 | 注册 方可回帖
返回
//