Win10 1903过TP的双机调试

了解内核知识已经有一段时间了,想双机调试一下XP,网上也找了不少资料。
https://bbs.pediy.com/thread-248912.htm

https://blog.csdn.net/kingswb/article/details/51194105
差不多我用到的大部分代码都是从上面cv(Ctrl+c---->Ctrl+v)下来的
1、首先解决The context is partially valid. Only x86 user-mode context is available. 
具体方式是hookKdpTrap
2、 防止安全组件加载失败
SharedUserData->KdDebuggerEnabled = FALSE;  //防止安全组件加载失败,SharedUserData这个是一个导出的全局变量直接写就行
3、XP会清零KdDebuggerEnabled
这里本来是打算做一个定时器,但是还是会导致TesNginx.Sycccccccccccccc出现蓝屏,所以只有手动的去修改
4、断链隐藏 kdcom,防止kdcom内存被清空导致和windbg通讯不了
5、XP会检测KdEnteredDebugger,如果是1就直接蓝屏
处理方式是让他去找其他位置(PUCHAR)KdEnteredDebugger + 0x30;  //据暗中观察,+0x30 的位置恒为0
做完这些之后基本上就能够下断点了,但是其实还是有问题(由于hook了系统函数有一定的几率会触发109错误->PathGuard,一开始我也分不清楚,后来慢慢的也了解了)
之后放上一张过了图片


最后把代码也带上吧,.asm文件很简单简单的inlinhook就行了

#include <Ntifs.h>
#include <ntimage.h>

extern void debg();
//关闭写保护
KIRQL WPOFFx64(){
	KIRQL irql = KeRaiseIrqlToDpcLevel();
	UINT64 cr0 = __readcr0();
	cr0 &= 0xfffffffffffeffff;
	__writecr0(cr0);
	_disable();
	return irql;
}
//开启写保护
void WPONx64(KIRQL irql){
	UINT64 cr0 = __readcr0();
	cr0 |= 0x10000;
	_enable();
	__writecr0(cr0);
	KeLowerIrql(irql);
}


//这里尝试过tp的双机调试,环境为win10 1903
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//1、首先解决The context is partially valid. Only x86 user-mode context is available. 

/*
nt!KdpTrap:
fffff807`64bfffc8 48895c2408      mov     qword ptr [rsp+8],rbx
fffff807`64bfffcd 4889542410      mov     qword ptr [rsp+10h],rdx
fffff807`64bfffd2 57              push    rdi
fffff807`64bfffd3 4883ec40        sub     rsp,40h
fffff807`64bfffd7 33d2            xor     edx,edx
*/
ULONG64 orgkdt =  0xfffff80166201fc8;
//ULONG64 orgkdt= 0xfffff80764bfffc8;//直接写硬编码,这里需要进行修改<-------------------------------------------------------------------------------------------------------------------------------------------------------


NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
extern NTSTATUS hdbktrap(IN PKTRAP_FRAME 	TrapFrame,IN PKEXCEPTION_FRAME 	ExceptionFrame,IN PEXCEPTION_RECORD 	ExceptionRecord,IN PCONTEXT 	ContextRecord,IN KPROCESSOR_MODE 	PreviousMode,IN BOOLEAN 	SecondChanceException);

//这里做一个跳转
VOID ModifyKdpTrap(PVOID myaddress,PVOID targetaddress) {
	KIRQL irql;
	ULONGLONG myfun;
	UCHAR jmp_code[] = "\x48\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xE0\x00\x00";//mov rax xxx,jmp rax
	myfun = (ULONGLONG)myaddress;//替换成自己的函数地址
	RtlCopyMemory(jmp_code + 2, &myfun, 8);
	//debg();
	irql = WPOFFx64();
	RtlCopyMemory(targetaddress, jmp_code, 12);
	WPONx64(irql);
}

//这里完成hook
NTSTATUS HookKdpTrap(
	IN PKTRAP_FRAME 	TrapFrame,
	IN PKEXCEPTION_FRAME 	ExceptionFrame,
	IN PEXCEPTION_RECORD 	ExceptionRecord,
	IN PCONTEXT 	ContextRecord,
	IN KPROCESSOR_MODE 	PreviousMode,
	IN BOOLEAN 	SecondChanceException){
	
	PEPROCESS hp = PsGetCurrentProcess();
	if (!_stricmp((char *)PsGetProcessImageFileName(hp), "TASLogin.exe")){
		return STATUS_SUCCESS;
	}
	return hdbktrap(TrapFrame, ExceptionFrame, ExceptionRecord, ContextRecord, PreviousMode, SecondChanceException);
}

//这里做一个还原
void UnHookKdpTrap() {
	KIRQL irql;
	UCHAR orignal_code[] = "\x48\x89\x5c\x24\x08\x48\x89\x54\x24\x10\x57\x48\x83\xec\x40";//mov rax xxx,jmp rax
	irql = WPOFFx64();
	RtlCopyMemory(orgkdt, orignal_code, 15);
	WPONx64(irql);
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------



//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//2、 防止安全组件加载失败
VOID DisableKdDebuggerEnabled() {
	SharedUserData->KdDebuggerEnabled = FALSE;  //防止安全组件加载失败
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------



//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//3、TP会清零KdDebuggerEnabled,这里做一个每隔一秒的定时器

//----------------------------------------------------------------------------------------------------------------------------------------------------------------



//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//4、断链隐藏 kdcom,防止kdcom内存被清空导致和windbg通讯不了
/*
0: kd> dt _eprocess
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x2e0 ProcessLock      : _EX_PUSH_LOCK
   +0x2e8 UniqueProcessId  : Ptr64 Void
   +0x2f0 ActiveProcessLinks : _LIST_ENTRY
*/
PDRIVER_OBJECT pDriverObject = NULL;
typedef struct _KLDR_DATA_TABLE_ENTRY {
	LIST_ENTRY InLoadOrderLinks;
	PVOID ExceptionTable;
	ULONG ExceptionTableSize;
	PVOID GpValue;
	ULONG UnKnow;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT __Unused5;
	PVOID SectionPointer;
	ULONG CheckSum;
	PVOID LoadedImports;
	PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;

VOID HideDriver(){
	PKLDR_DATA_TABLE_ENTRY entry = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
	PKLDR_DATA_TABLE_ENTRY firstentry;
	UNICODE_STRING uniDriverName;

	firstentry = entry;

	// 初始化要隐藏驱动的驱动名
	RtlInitUnicodeString(&uniDriverName, L"kdcom.dll");

	while ((PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink != firstentry){
		if (entry->FullDllName.Buffer != 0){
			if (RtlCompareUnicodeString(&uniDriverName, &(entry->BaseDllName), FALSE) == 0){
				//DbgPrint("隐藏驱动 %ws 成功!\n", entry->BaseDllName.Buffer);
				// 修改 Flink 和 Blink 指针, 以跳过我们要隐藏的驱动
				*((ULONG*)entry->InLoadOrderLinks.Blink) = (ULONG)entry->InLoadOrderLinks.Flink;
				entry->InLoadOrderLinks.Flink->Blink = entry->InLoadOrderLinks.Blink;

				/*
					使被隐藏驱动LIST_ENTRY结构体的Flink, Blink域指向自己
					因为此节点本来在链表中, 那么它邻接的节点驱动被卸载时,
					系统会把此节点的Flink, Blink域指向它相邻节点的下一个节点.
					但是, 它此时已经脱离链表了, 如果现在它原本相邻的节点驱动被
					卸载了, 那么此节点的Flink, Blink域将有可能指向无用的地址, 而
					造成随机性的BSoD.
				*/
				entry->InLoadOrderLinks.Flink = (LIST_ENTRY*)&(entry->InLoadOrderLinks.Flink);
				entry->InLoadOrderLinks.Blink = (LIST_ENTRY*)&(entry->InLoadOrderLinks.Flink);

				break;
			}
		}
		// 链表往前走
		entry = (PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;
	}
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//5、处理TP蓝屏
/*
fffff807`642d2210 48895c2420      mov     qword ptr [rsp+20h],rbx
fffff807`642d2215 4488442418      mov     byte ptr [rsp+18h],r8b
fffff807`642d221a 56              push    rsi
fffff807`642d221b 57              push    rdi
fffff807`642d221c 4154            push    r12
fffff807`642d221e 4155            push    r13
fffff807`642d2220 4157            push    r15
fffff807`642d2222 4883ec20        sub     rsp,20h

*/
#define KdEnteredDebugger 0xfffff80165d061e0
//#define KdEnteredDebugger 0xfffff80764704100//直接写硬编码,这里需要进行修改<-----------------------------------------------------------------------------------------------------------------------------------------------


extern PMDL hookIoAllocateMdl(__drv_aliasesMem PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN  ChargeQuota, PIRP Irp);
ULONG64 IoAllocateM=0;

//这里做一个跳转
VOID ModifyIoAllocateMdl(PVOID myaddress, PVOID targetaddress) {
	KIRQL irql;
	ULONGLONG myfun;
	UCHAR jmp_code[] = "\x48\xB8\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xE0\x00\x00";//mov rax xxx,jmp rax
	myfun = (ULONGLONG)myaddress;//替换成自己的函数地址
	RtlCopyMemory(jmp_code + 2, &myfun, 8);
	//debg();
	irql = WPOFFx64();
	RtlCopyMemory(targetaddress, jmp_code, 12);
	WPONx64(irql);
}

PMDL newIoAllocateMdl(__drv_aliasesMem PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN  ChargeQuota, PIRP Irp){

	//debg();
	if(VirtualAddress == KdEnteredDebugger){
		//DbgPrint("[KdEnteredDebugger] address: %p\n", KdEnteredDebugger);
		VirtualAddress = (PUCHAR)KdEnteredDebugger + 0x30;  //据暗中观察,+0x30 的位置恒为0
	}

	return hookIoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);

}

//这里做一个还原
void UnHookIoAllocateMdl() {
	KIRQL irql;
	UCHAR orignal_code[] = "\x48\x89\x5c\x24\x20\x44\x88\x44\x24\x18\x56\x57\x41\x54\x41\x55";
	irql = WPOFFx64();
	RtlCopyMemory(IoAllocateMdl, orignal_code, 15);
	WPONx64(irql);
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------




VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
	//还原之前的KdpTraphook
	UnHookKdpTrap();
	//还原之前的IoAllocateMdl
	UnHookIoAllocateMdl();
	//取消定时器
	

	DbgPrint("See You !\n");
}




NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath) {
	pDriverObject = DriverObject;
	DriverObject->DriverUnload = DriverUnload;

	//这里把这个函数进行了hook
	ModifyKdpTrap(HookKdpTrap, orgkdt);

	//防止安全组件加载失败
	DisableKdDebuggerEnabled();

	//摘掉kdcom的eprocess
	HideDriver();

	//干掉TP蓝屏
	IoAllocateM = (ULONG64)IoAllocateMdl;//得到函数的地址
	ModifyIoAllocateMdl(newIoAllocateMdl, IoAllocateMdl);

	//设置定时器


	return STATUS_SUCCESS;
}

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Win10虚拟机过TP(Tech Preview)指的是在Win10操作系统上运行虚拟机,并使用其进行技术预览。在进行Win10虚拟机过TP时,需要注意以下几点。 首先,确保虚拟机软件兼容Win10操作系统。常见的虚拟机软件如VMware Workstation、VirtualBox等通常都支持Win10,并提供对应的安装程序。 其次,安装虚拟机软件后,可以创建一个新的虚拟机,选择Win10作为虚拟机的操作系统类型。在设置虚拟机时,需要给予足够的硬件资源,例如分配足够的内存、处理器核心等。这可以保证虚拟机在运行Win10时有足够的性能。 然后,从官方渠道下载Win10的ISO镜像文件。在虚拟机中,选择安装操作系统,并加载之前下载的Win10 ISO文件。按照安装向导进行设置和安装操作系统,这包括选择安装类型、分区和输入许可证密钥等步骤。 安装完成后,Win10虚拟机就可以在虚拟机软件中运行了。在虚拟机中,可以体验Win10的新功能、更新和改进等。此外,还可以安装其他应用程序、测试软件兼容性等。 最后,需要注意在虚拟机中进行的所有操作不会影响主机系统。虚拟机相当于一个独立的计算机系统,其中的数据和设置不会影响主机系统。可以根据需要对虚拟机进行快照和还原操作,方便后续使用和测试。 总之,运行Win10虚拟机过TP可以提供一个安全、独立的环境,用于测试和体验Win10技术预览版本,同时不会对主机系统造成任何影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值