我是靠谱客的博主 笨笨饼干,这篇文章主要介绍KdDisableDebugger()反调试,现在分享给大家,希望可以做个参考。

NTSTATUS KdDisableDebugger();
剥离内核调试器成功,返回 STATUS_SUCCESS
如果并没有内核调试器,返回STATUS_DEBUGGER_INACTIVE
如果内核调试器处于阻塞状态返回STATUS_ACCESS_DENIED
KdDisableDebugger函数会判断一个全局变量,当系统不是在调试下启动时,该值为1,在调试下启动时该值被置0,且该值只在操作系统启动时被初始化了一次(推测),当该值为0时,KdDisableDebugger会调用相关函数使内核调试器与操作系统分离,该全局变量仅作为一个标识
反调试

复制代码
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
#include <ntddk.h> #pragma warning(disable:4100) #define DELAY_ONE_MICROSECOND (-10) #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000) BOOLEAN g_bExit = FALSE; PVOID pThreadObj = NULL; VOID MySleep(LONG msec); VOID CheckDebug(PVOID pContext); NTSTATUS CreateThread(); VOID DriverUnload(PDRIVER_OBJECT pDriver) { KdPrint(("驱动正在被关闭n")); g_bExit = TRUE; if (pThreadObj!=NULL) { //等待对象 KeWaitForSingleObject(pThreadObj, Executive, KernelMode, FALSE, NULL); //因为使用了 ObRefrenceObjceByHandle.所以引用对象+1了.现在需要引用对象-1 ObDereferenceObject(pThreadObj); } // 卸载驱动 } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) { DbgPrint("驱动正在被启动n"); NTSTATUS ntStatus = 0; ntStatus = CreateThread(); //指定卸载函数 pDriver->DriverUnload = DriverUnload; return ntStatus; } //================================================================== //函数名: MySleep //功能:睡眠函数,类似于三环的sleep() //输入参数1:msec,睡眠的时间,单位秒 //返回值:null //================================================================== VOID MySleep(LONG msec) { LARGE_INTEGER my_interval; my_interval.QuadPart = DELAY_ONE_MILLISECOND; my_interval.QuadPart *= msec; KeDelayExecutionThread(KernelMode, 0, &my_interval); } VOID CheckDebug(PVOID pContext) { while (1) { DbgPrint("执行KdDisableDebugger()...n"); KdDisableDebugger(); MySleep(2000); if (g_bExit == TRUE) break; } PsTerminateSystemThread(STATUS_SUCCESS); } NTSTATUS CreateThread() { //创建线程 HANDLE hThread; NTSTATUS ntStatus; ntStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, (HANDLE)0, NULL, CheckDebug, //你创建函数的回调地址 NULL); //给你创建函数传递的参数值 //等待线程创建完毕. if (!NT_SUCCESS(ntStatus)) return ntStatus; //判断IRQL 降低权限 if (KeGetCurrentIrql() != PASSIVE_LEVEL) ntStatus = KfRaiseIrql(PASSIVE_LEVEL); ntStatus = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, &pThreadObj, NULL); if (!NT_SUCCESS(ntStatus)) return ntStatus; //关闭线程句柄 ZwClose(hThread); return ntStatus; }

反反调试
将此全局变量重新置为1
用到的相关结构体

复制代码
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
#ifdef _WIN64 typedef struct _LDR_DATA { LIST_ENTRY listEntry; ULONG64 __Undefined1; ULONG64 __Undefined2; ULONG64 __Undefined3; ULONG64 NonPagedDebugInfo; ULONG64 DllBase; ULONG64 EntryPoint; ULONG SizeOfImage; UNICODE_STRING path; UNICODE_STRING name; ULONG Flags; }LDR_DATA, * PLDR_DATA; #else typedef struct _LDR_DATA { LIST_ENTRY listEntry; ULONG unknown1; ULONG unknown2; ULONG unknown3; ULONG unknown4; ULONG unknown5; ULONG unknown6; ULONG unknown7; UNICODE_STRING path; UNICODE_STRING name; ULONG Flags; }LDR_DATA, * PLDR_DATA; #endif

用到的相关函数

复制代码
1
2
3
4
5
6
7
8
9
/* * --------------------------------函数声明 */ UINT64 SearchFeature(UINT64 nAddr, char* pFeature, int nLeng, UINT64 size); UINT64 GetDriverAddressByFeature(LPCWSTR DriverName, PDRIVER_OBJECT pDriverObject, char* pFeature, int nLeng); /* * --------------------------------函数声明 */

详情

复制代码
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
//================================================================== //函数名: GetDriverAddressByFeature //功能:搜索指定内核模块的特征码,并获取该特征码的位置 //输入参数1:DriverName,要搜索的驱动模块名 //输入参数2:pDriverObject,自己的驱动对象 //输入参数3:pFeature,特征码 //输入参数4:nLeng,特征码的长度 //返回值:UINT64,特征码的地址 //================================================================== UINT64 GetDriverAddressByFeature(LPCWSTR DriverName, PDRIVER_OBJECT pDriverObject, char* pFeature, int nLeng) { PLDR_DATA CurrentDllInfo = (PLDR_DATA)pDriverObject->DriverSection; PLDR_DATA DllInfoTemp = CurrentDllInfo; UNICODE_STRING uniDriverName; UINT64 dllBase = 0; UINT64 dllSize = 0; RtlInitUnicodeString(&uniDriverName, DriverName); do { DllInfoTemp = (PLDR_DATA)(DllInfoTemp->listEntry.Flink); //先查询下一个 //wcscmp()会蓝屏,尽量使用内核提供的字符串函数 if (RtlCompareUnicodeString(&uniDriverName,&DllInfoTemp->name,TRUE)==0) { DbgPrint("Driver Module Name=%wsn", DllInfoTemp->name.Buffer); DbgPrint("Driver Module Dllbase=%pn", DllInfoTemp->DllBase); dllBase = DllInfoTemp->DllBase; dllSize = DllInfoTemp->SizeOfImage; } } while (CurrentDllInfo != DllInfoTemp); //遍历到当前驱动LDR_DATA_TABLE_ENTRY地址时,说明查询结束 //没找到目标驱动模块 if (dllBase == 0) return FALSE; return SearchFeature(dllBase, pFeature, nLeng, dllSize); }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//================================================================== //函数名: SearchFeature //描述:内部函数 //================================================================== UINT64 SearchFeature(UINT64 nAddr, char* pFeature, int nLeng, UINT64 size) { char szStatus[256] = ""; INT64 i = size; while (i--) { RtlMoveMemory(szStatus, (char*)nAddr, nLeng); if (RtlCompareMemory(pFeature, szStatus, nLeng) == nLeng) { return nAddr; } nAddr++; } return 0; }

最后

以上就是笨笨饼干最近收集整理的关于KdDisableDebugger()反调试的全部内容,更多相关KdDisableDebugger()反调试内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部