过某P之KdEnteredDebugger检测

某p在双机调试时,会检测KdEnteredDebugger是否等于1,如果等于1就重启。

我们的办法是让检测永远检测到0。经过分析,当位置为KdEnteredDebugger+0x20时值是0。我们可以修改指向。只要inline hook IoAllocateMdl 即可

PMDL MyIoAllocateMdl(
	__in_opt PVOID  VirtualAddress,
	__in ULONG  Length,
	__in BOOLEAN  SecondaryBuffer,
	__in BOOLEAN  ChargeQuota,
	__inout_opt PIRP  Irp  OPTIONAL)
{
	PVOID pKdEnteredDebugger = (PVOID)GetKdEnteredDebuggerAddr();
	if (pKdEnteredDebugger == VirtualAddress)
	{
		VirtualAddress = (PVOID)((SIZE_T)pKdEnteredDebugger + 0x20);  //+0x20  是让他读到其他的位置
	}

	return old_IoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
}

  具体代码实现:

#include<NTDDK.H>
#include<windef.h>
#include<ntstatus.h>

BYTE OriginalBytes[5] = {0};
BYTE HookCode[5] = {0xe9,0,0,0,0};//跳转地址
BYTE JmpCode[7] = {0xea,0,0,0,0,0x08,0};//cs模式为1b,内核位08
ULONG  CR0VALUE;
#define kmalloc(_s)    ExAllocatePoolWithTag(NonPagedPool, _s, ‘SYSQ‘)

// 查找KdEnteredDebugger地址
extern SIZE_T KdEnteredDebugger;
SIZE_T GetKdEnteredDebuggerAddr()
{
    return KdEnteredDebugger;
}

// HookIoAllocMdl
typedef PMDL(__stdcall *_MyIoAllocateMdl)(
    _In_opt_     PVOID VirtualAddress,
    _In_         ULONG Length,
    _In_         BOOLEAN SecondaryBuffer,
    _In_         BOOLEAN ChargeQuota,
    _Inout_opt_  PIRP Irp
    );

_MyIoAllocateMdl old_IoAllocateMdl;
PMDL MyIoAllocateMdl(
    __in_opt PVOID  VirtualAddress,
    __in ULONG  Length,
    __in BOOLEAN  SecondaryBuffer,
    __in BOOLEAN  ChargeQuota,
    __inout_opt PIRP  Irp  OPTIONAL)
{
    PVOID pKdEnteredDebugger = (PVOID)GetKdEnteredDebuggerAddr();
    if (pKdEnteredDebugger == VirtualAddress)
    {
        VirtualAddress = (PVOID)((SIZE_T)pKdEnteredDebugger + 0x20);  //+0x20  是让他读到其他的位置
    }

    return old_IoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
}
void hookIoAllocateMdl()
{
    KIRQL Irql;
    DbgPrint("NtIoAllocateMdl] :0x%x",IoAllocateMdl);
    DbgPrint("[MyIoAllocateMdl] :0x%x",MyIoAllocateMdl);  //地址验证
    RtlCopyMemory(OriginalBytes,(BYTE *)IoAllocateMdl,5);
    *(ULONG *)(HookCode+1) = (ULONG)MyIoAllocateMdl - ((ULONG)IoAllocateMdl+5);
    DbgPrint("*(ULONG *)(HookCode+1) = (ULONG)MyIoAllocateMdl - ((ULONG)IoAllocateMdl+5);");
    *(ULONG *)(JmpCode+1) = (ULONG)((BYTE*)IoAllocateMdl +5);
    RtlCopyMemory((BYTE*)old_IoAllocateMdl,OriginalBytes,5);
    RtlCopyMemory((BYTE*)old_IoAllocateMdl+5,JmpCode,7);
    //去除写保护
    _asm
         {
                 push eax

                         mov eax, cr0
                         mov CR0VALUE, eax
                         and eax, 0fffeffffh
                         mov cr0, eax
                         pop eax
         }
         //提升IRQL中断级别
         Irql = KeRaiseIrqlToDpcLevel();
         DbgPrint(" Irql = KeRaiseIrqlToDpcLevel();");
         RtlCopyMemory((BYTE*)IoAllocateMdl,HookCode,5);
          DbgPrint("RtlCopyMemory((BYTE*)IoAllocateMdl,HookCode,5);");
         KeLowerIrql(Irql);

         //开启写保护
         __asm

         {       

                     push eax

                         mov eax, CR0VALUE 

                         mov cr0, eax

                         pop eax

         };
         DbgPrint("已经hook");

}
void myDriverUnload(PDRIVER_OBJECT P)
{

    DbgPrint("已经恢复");
}
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    DbgPrint("开始hook");
    DriverObject->DriverUnload = myDriverUnload;
    old_IoAllocateMdl = (_MyIoAllocateMdl)kmalloc(20);
    memset(old_IoAllocateMdl, 0x90, 20);
    hookIoAllocateMdl();
    return STATUS_SUCCESS;
}
时间: 2024-08-28 21:17:55

过某P之KdEnteredDebugger检测的相关文章

JavaScript数据类型检测

一.JavaScript 数据类型 1.基本数据类型(6种) Undefined Null Boolean Number String Symbol (ES6新增) 2.引用数据类型: Object 二.数据类型检测 1. typeof 可以检测除null 外的基本类型.null 和所有对象的typeof都是"object", 不能用于检测用户自定义类型. 比如Date, RegExp, Array, DOM Element的类型都是"object". var s

Android App退出检测

app的退出检测是很难的,但是获取app“要退出”的状态就容易多了,退出的瞬间并不是真的退出了,ActivityManager要销毁activity,也需要一些时间和资源的. 先见下面的运行效果:  gif做的比价粗啊, 两个activity的界面就不介绍了,主要是在APP启动的时候开启一个服务,application代码如下: public class MyApplication extends Application { @Override public void onCreate() {

状态检测防火墙原理

状态检测防火墙原理 防火墙发展到今天,虽然不断有新的技术产生,但从网络协议分层的角度,仍然可以归为以下三类: 1.包过滤防火墙: 2.基于状态检测技术(Stateful-inspection)的防火墙: 3.应用层防火墙 这三类防火墙都是向前兼容的,即基于状态检测的防火墙也有一般包过滤防火墙的功能,而基于应用层的防火墙也包括前两种防火墙的功能.由于<<浅>>文已讲了第一类防火墙,在这里我就讲讲基于状态检测技术的防火墙的实现原理. 为什么会有基于状态检测的防火墙呢?这就要先看看第一类

unity 射线检测

unity中射线检测时非常实用也经常实用的一种手段.下面讲解一下射线检测问题. 1)Ray 根据射线端点和射线的方向定义一条射线 Ray ray= new Ray(transform.position, transform.forward); 定义一个包含射线投射信息的变量RaycastHit hit,并进行射线检测Physics.SphereCast RaycastHit hit; if(Physics.SphereCast(ray,1f,out hit)) { if(hit.distance

检测和整理索引碎片

索引碎片的检测和整理 存储数据是为了查找数据,存储结构影响数据查找的性能.对无序数据进行查找,最快的查找算法是哈希查找:对有序数据进行查找,最快的查找算法是平衡树查找.在传统的关系型数据库中,聚集索引和非聚集索引都是平衡树(B-Tree)类型的存储结构,用于顺序存储数据,便于实现数据的快速查找.除了提升数据查找的性能之外,索引还能减少硬盘IO和内存消耗.通常情况下,硬盘IO是查找性能的瓶颈,由于索引是数据表的列的子集,这意味着,索引只存储部分列的数据,占用的硬盘空间比全部列少了很多,因此,数据库

检测某个方法是否属于某个类中--解析php函数method_exists()与is_callable()的区别

php函数method_exists() 与is_callable()的区别在哪?在php面相对象设计过程中,往往我们需要在调用某一个方法是否属于某一个类的时候做出判断,常用的方法有 method_exists()和is_callable() 相比之下,is_callable()函数要高级一些,它接受字符串变量形式的方法名作为 第一个参数,如果类方法存在并且可以调用,则返回true.如果要检测类中的方法是否能被调用,可以给函数传递一个数组而不是类的方法名作为参数.数组必须包含对象或类名,以将其作

多维活体检测,让人脸识别更安全

今年的315晚会提到人脸识别领域的安全风险,主持人用现场合成的视频通过了活体检测和人脸验证,因此人脸识别的安全性引起大众关注.对于活体检测的安全隐患,腾讯优图团队一直保持高度关注,并依托多年积累的技术能力和业务运营经验,已经对人脸识别技术手段进行过多次安全升级,让人脸识别更安全. 一.目前人脸识别常见攻击手段有什么? 1 .纸片翻拍,通过打印用户的照片进行攻击: 2. 屏幕翻拍,一些3D建模技术可以驱动用户的单张照片或视频做出系统要求的摇头.张嘴.眨眼等动作: 3. 用户戴面具: 二.如何应对人

汽车检测SIFT+BOW+SVM

整个执行过程如下:1)获取一个训练数据集. 2)创建BOW训练器并获得视觉词汇. 3)采用词汇训练SVM. 4)尝试对测试图像的图像金字塔采用滑动宽口进行检测. 5)对重叠的矩形使用非极大抑制. 6)输出结果. 该项目的结构如下: |-----car_detector|       |--detector.py| |--__init__.py| |--non_maximum.py| |--pyramid.py| |--sliding_window.py|-----car_sliding_wind

元素相交检测

最近做一个项目,其中涉及到了一个相交检测的功能,现在分享出来共勉 首先先谈一谈满足什么样的条件,才能算两个元素是相交,下面是一个示意图: Ax1是元素A的起点在x轴上的投影,Ax2是元素A的终点在x轴上的投影,Ay1是元素A的起点在y轴上的投影,Ay2是元素A的终点在y轴上的投影 Bx1是元素B的起点在x轴上的投影,Bx2是元素B的终点在x轴上的投影,By1是元素B的起点在y轴上的投影,By2是元素B的终点在y轴上的投影 当元素A和元素B在y轴和x轴的投影同时相交时,元素A和元素B才相交 元素A