概述
NTSTATUS KdDisableDebugger();
剥离内核调试器成功,返回 STATUS_SUCCESS
如果并没有内核调试器,返回STATUS_DEBUGGER_INACTIVE
如果内核调试器处于阻塞状态返回STATUS_ACCESS_DENIED
KdDisableDebugger函数会判断一个全局变量,当系统不是在调试下启动时,该值为1,在调试下启动时该值被置0,且该值只在操作系统启动时被初始化了一次(推测),当该值为0时,KdDisableDebugger会调用相关函数使内核调试器与操作系统分离,该全局变量仅作为一个标识
反调试
#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
用到的相关结构体
#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
用到的相关函数
/*
* --------------------------------函数声明
*/
UINT64 SearchFeature(UINT64 nAddr, char* pFeature, int nLeng, UINT64 size);
UINT64 GetDriverAddressByFeature(LPCWSTR DriverName, PDRIVER_OBJECT pDriverObject, char* pFeature, int nLeng);
/*
* --------------------------------函数声明
*/
详情
//==================================================================
//函数名: 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);
}
//==================================================================
//函数名: 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()反调试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复