差不多我用到的大部分代码都是从上面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就行了
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
#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;
}
|
总结
以上所述是小编给大家分享的Win10 1903过TP的双机调试问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
原文链接:https://blog.csdn.net/qq_37353105/article/details/103099412








发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。