zoukankan      html  css  js  c++  java
  • WinDbg调试流程的学习及对TP反调试的探索

    基础知识推荐阅读《软件调试》的第十八章 内核调试引擎

    我在里直接总结一下内核调试引擎的几个关键标志位,也是TP进行反调试检测的关键位。

    KdPitchDebugger : Boolean 用来表示是否显示的抑制内核调试, 当启动项中包含 /NODEBUG选项时,这个变量会被置为 TRUE

    KdDebuggerEnabled : Boolean 用来表示内核调试是否被启用。当启动项中包含 /DEBUG 或者/ DEBUGPORT 而且不包含/NODEBUG时,这个变量置为TRUE

    kiDebugRoutine : 函数指针类型 ,用来记录内核调试引擎的异常处理回调函数,当内核调试引擎活动时,指向KdpTrap函数,否则指向KdpStub函数

    KdpBreakpointTable : 结构体数组类型,用来记录代码断点。每一个元素为BREAKPOINT_ENTRY结构,用来描述一个断点,包括断点地址。

    然后开始动手,打开Windbg,调试虚拟机(Win7 x86 sp1) Ctrl+Break 断下来,输入k 命令观察断点的栈回溯,观察到最后的几个函数:

    KeUpdateRunTime-->àKdCheckForDebugBreak--->àRtlpBreakWithStatusInstruction.  

    用ida 反汇编查看KeUpdateRunTime函数,看到对KdDebuggerEnabled标识位的检测,如果为0则直接返回,不对KdCheckForDebugBreak函数进行调用。

    然后继续反汇编KdCheckForDebugBreak函数,可以看到最KdDebuggerEnabled和 KdPitchDebugger的检测

    可以看到调用了KdPollBreakIn() 函数,我们继续跟进kdPollBreakIn()函数,可以看到主要也是对KdPitchDebugger和KdDebuggerEnabled的检测,如果为0就直接退出,返回0

    接着跟入DbgBreakPointWithStatus() 函数可以发现并没有做什么处理,直接向下执行RtlpBreakWithStatusInstruction()   可以看到我们的int 3 ,俗称CC断点

    对KdDebuggerEnabled进行检测的函数有:

    KdUpdateRunTime

    KdCheckForDebugBreak

    kdPollBreakIn

    对KdPitchDubbger进行检测的函数:

    KdCheckForDebugBreak

    KdPollBreakIn

     大致的思路如下:

    我们要做的就是把这几个全局变量置换成未调试时的状态,但是在Windows自己的调试引擎中检测的几个全局变量替换成我们自己的全局变量,而且对于TP的TenSa**.sys可以查看导入表,存在IoAllocMdl(),猜测TP对于几个全局变量的访问应该是采用MDL的方式来访问,可以考虑hook掉 IoAllocMdl这个函数,让他检测到其他地方。

    然后就是针对TP不停的调用KdDisableDebugger来反调试的问题,直接hook掉KdDisableDebugger,让其直接返回。

    还有处理关于kiDebugRoutine 的问题,当内核调试引擎处于活动的时候,KiDebugRoutine这个函数指针是指向的KdpTrap,来处理我们调试是产生的异常,当我们将KiDebugRoutine指向了KdpStub之后,可以绕过对KiDebugRoutine的检测,但是内核调试引擎来处理我们触发的异常时,调用的不是KdpTrap,而变成了KdpStub,很显然不能继续进项调试,所以我们还需要做的一项工作就是hook KdpTrap,让他跳转到KdpTrap,这个内核引擎可以正常工作,也可以绕过TP的检测。

    下面可以利用WinDbg对这个手动对这几个全局变量进行简单的处理。

    kd> dd KdPitchDebugger
    80546efc  00000000 00000000 00000000 00000000
    
    kd> dd KdDebuggerEnabled
    8054d4c1  01000001 00000000 00000000 01000000
    
    kd> dd kiDebugRoutine
    80553f04  80661a06 00000000 7c92e4a8 7c92e45c
    
    
    kd> u 80661a06 
    nt!KdpTrap:
    80661a06 8bff            mov      edi,edi
    80661a08 55              push     ebp
    80661a09 8bec            mov     ebp,esp
    80661a0b 51              push     ecx
    80661a0c 51              push     ecx
    80661a0d 8b4510          mov     eax,dword ptr [ebp+10h]
    80661a10 813803000080    cmp     dword ptr [eax],80000003h
    80661a16 56              push     esi
    先将KdPitchDebugger 置为1
    kd> ed KdPitchDebugger 1
    
    kd> dd KdPitchDebugger
    80546efc  00000001 00000000 00000000 00000000
    
    然后设置KiDebugRoutine 指向的指针 从KdpTrap 改成 KdpStub 
    kd> dd KiDebugRoutine
    80553f04  80661a06 00000000 7c92e4a8 7c92e45c
    
    kd> u 80661a06 
    nt!KdpTrap:
    80661a06 8bff            mov     edi,edi
    80661a08 55              push    ebp
    80661a09 8bec            mov     ebp,esp
    80661a0b 51              push    ecx
    80661a0c 51              push    ecx
    80661a0d 8b4510          mov     eax,dword ptr [ebp+10h]
    80661a10 813803000080    cmp     dword ptr [eax],80000003h
    80661a16 56              push    esi
    
    
    kd> u KdpStub
    nt!KdpStub:
    804f7c76 8bff            mov     edi,edi
    804f7c78 55              push    ebp
    804f7c79 8bec            mov     ebp,esp
    804f7c7b 8b4510          mov     eax,dword ptr [ebp+10h]
    804f7c7e 813803000080    cmp     dword ptr [eax],80000003h
    804f7c84 7525            jne     nt!KdpStub+0x35 (804f7cab)
    804f7c86 83781000        cmp     dword ptr [eax+10h],0
    804f7c8a 761f            jbe     nt!KdpStub+0x35 (804f7cab)
    
    
    kd> ed KiDebugRoutine 804f7c76
    kd> dd KiDebugRoutine
    80553f04  804f7c76 00000000 7c92e4a8 7c92e45c
    
    最后恢复KdDebuggerEnabled 为 0
    kd> ed KdDebuggerEnabled 0
    

    现在会发生什么,对,就是WinDbg接受不到调试消息包了,就是因为KdDebuggerEnabled 置为0 了,内核调试引擎在关键校验的地方不通过,不发送调试信息。

    然后就是代码上的问题,完成上诉的功能就可以达到双机调试TP了。下面放出代码,就是按照上诉的思路来解决的,因为一些函数的定位和关键值的确定都是采用的针对的Win 7 Ultimate x86 sp1硬编码,如果想过其他的系统就要改改硬编码了,而且TP经常的更新,掌握了原理才是正道,强烈推荐《软件调试》这本书。

    #ifndef CXX_TPWDG_H
    #define CXX_TPWDG_H
    
    
    #include <ntifs.h>
    #include <devioctl.h>
    #include <ntimage.h>
    
    #define kmalloc(_s)    ExAllocatePoolWithTag(NonPagedPool, _s, 'Lanren')
    #define OP_NONE 0x00
    #define OP_MODRM 0x01
    #define OP_DATA_I8 0x02
    #define OP_DATA_I16 0x04
    #define OP_DATA_I32 0x08
    #define OP_DATA_PRE66_67 0x10
    #define OP_WORD 0x20
    #define OP_REL32 0x40
    #define SystemModuleInformation 11
    
    typedef unsigned char BYTE;
    typedef BYTE *PBYTE;
    
    typedef struct _SYSTEM_MODULE_INFORMATION//系统模块信息
    {
        ULONG Reserved[2];
        ULONG Base;
        ULONG Size;
        ULONG Flags;
        USHORT Index;
        USHORT Unknown;
        USHORT LoadCount;
        USHORT ModuleNameOffset;
        CHAR ImageName[256];
    } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
    
    typedef struct _tagSysModuleList//模块链结构
    {
        ULONG ulCount;
        SYSTEM_MODULE_INFORMATION smi[1];
    }MODULES, *PMODULES;
    
    
    NTSTATUS __stdcall ZwQuerySystemInformation(
        ULONG_PTR SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength
        );
    
    typedef PMDL(__stdcall *_MyIoAllocateMdl)(
        PVOID VirtualAddress,
        ULONG Length,
        BOOLEAN SecondaryBuffer,
        BOOLEAN ChargeQuota,
        PIRP Irp
        );
    
    
    SIZE_T GetKdEnteredDebuggerAddr();
    
    PMDL MyIoAllocateMdl(PVOID VirtualAddress,ULONG Length,
        BOOLEAN SecondaryBuffer,BOOLEAN ChargeQuota,
        PIRP Irp
        );
    
    unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode);
    unsigned long GetPatchSize(void *Proc, unsigned long dwNeedSize);
    VOID WpOffAndToDpcLevel();
    VOID WpOn();
    VOID WritableClose();
    VOID InlineHookEngine(ULONG uHookPoint, ULONG uNewFuncAddr);
    
    VOID UnInlineHookEngine(ULONG uHookPoint, char* pCode, ULONG uLength);
    NTSTATUS WriteKernelMemory(PVOID Address, ULONG Size, PVOID InBuffer);
    void Hook(PVOID Func, PVOID New_Func, PVOID Proxy_Func);
    void UnHook(PVOID Func, PVOID Proxy_Func);
    void HookIoAllocMdl(BOOLEAN bEnble);
    VOID LoadImageRoutine(
        IN PUNICODE_STRING FullImageName,
        IN HANDLE ProcessId,//where image is mapped
        IN PIMAGE_INFO ImageInfo
        );
    ULONG FindCharacteristicCode(ULONG uAddr, char* pCode, ULONG uLength);
    VOID GetKdpStubAddr(ULONG uStartSearchAddr);
    VOID GetKdpTrapAddr(ULONG uStartSearchAddr);
    VOID GetKdDebuggerEnabledAddr(ULONG uStartSearchAddr);
    ULONG GetFuncAddrFromName(IN PCWSTR FunctionName);
    VOID DriverUnload(PDRIVER_OBJECT pDriverObject);
    void WPOFF();
    void WPON();
    PVOID GetFuncAddress(LPWSTR lpFuncName);
    ULONG_PTR GetKeUpdateSystemTimeAddr();
    ULONG_PTR GetKdCheckForDebugBreak();
    ULONG_PTR GetKdDebuggerEnabled_1();
    ULONG_PTR GetKdDebuggerEnabled_2();
    ULONG_PTR GetKdDebuggerEnabled_3();
    ULONG_PTR GetKdDebuggerEnabled_4();
    ULONG_PTR GetKdPitchDebugger_1();
    ULONG_PTR GetKdPitchDebugger_2();
    void MoveGlobal();
    void RecoverGlobal();
    
    #endif    
    
    
    
    
    
    
    //全局变量
    static KIRQL OldIrql;
    ULONG ulKdpStub, ulKdpTrap;
    ULONG ulKdDisableDebugger;
    ULONG ulKdDisableDebuggerWithLock;
    ULONG ulKdInitSystem;
    ULONG ulKiDebugRoutine;
    ULONG ulKeEnterKernelDebugger;
    ULONG ulKdDebuggerEnabled;
    extern SIZE_T KdEnteredDebugger;
    _MyIoAllocateMdl OldIoAllocateMdl;
    UCHAR OpcodeFlags[256] = 
    {
        OP_MODRM,                      // 00
        OP_MODRM,                      // 01
        OP_MODRM,                      // 02
        OP_MODRM,                      // 03
        OP_DATA_I8,                    // 04
        OP_DATA_PRE66_67,              // 05
        OP_NONE,                       // 06
        OP_NONE,                       // 07
        OP_MODRM,                      // 08
        OP_MODRM,                      // 09
        OP_MODRM,                      // 0A
        OP_MODRM,                      // 0B
        OP_DATA_I8,                    // 0C
        OP_DATA_PRE66_67,              // 0D
        OP_NONE,                       // 0E
        OP_NONE,                       // 0F
        OP_MODRM,                      // 10
        OP_MODRM,                      // 11
        OP_MODRM,                      // 12
        OP_MODRM,                      // 13
        OP_DATA_I8,                    // 14
        OP_DATA_PRE66_67,              // 15
        OP_NONE,                       // 16
        OP_NONE,                       // 17
        OP_MODRM,                      // 18
        OP_MODRM,                      // 19
        OP_MODRM,                      // 1A
        OP_MODRM,                      // 1B
        OP_DATA_I8,                    // 1C
        OP_DATA_PRE66_67,              // 1D
        OP_NONE,                       // 1E
        OP_NONE,                       // 1F
        OP_MODRM,                      // 20
        OP_MODRM,                      // 21
        OP_MODRM,                      // 22
        OP_MODRM,                      // 23
        OP_DATA_I8,                    // 24
        OP_DATA_PRE66_67,              // 25
        OP_NONE,                       // 26
        OP_NONE,                       // 27
        OP_MODRM,                      // 28
        OP_MODRM,                      // 29
        OP_MODRM,                      // 2A
        OP_MODRM,                      // 2B
        OP_DATA_I8,                    // 2C
        OP_DATA_PRE66_67,              // 2D
        OP_NONE,                       // 2E
        OP_NONE,                       // 2F
        OP_MODRM,                      // 30
        OP_MODRM,                      // 31
        OP_MODRM,                      // 32
        OP_MODRM,                      // 33
        OP_DATA_I8,                    // 34
        OP_DATA_PRE66_67,              // 35
        OP_NONE,                       // 36
        OP_NONE,                       // 37
        OP_MODRM,                      // 38
        OP_MODRM,                      // 39
        OP_MODRM,                      // 3A
        OP_MODRM,                      // 3B
        OP_DATA_I8,                    // 3C
        OP_DATA_PRE66_67,              // 3D
        OP_NONE,                       // 3E
        OP_NONE,                       // 3F
        OP_NONE,                       // 40
        OP_NONE,                       // 41
        OP_NONE,                       // 42
        OP_NONE,                       // 43
        OP_NONE,                       // 44
        OP_NONE,                       // 45
        OP_NONE,                       // 46
        OP_NONE,                       // 47
        OP_NONE,                       // 48
        OP_NONE,                       // 49
        OP_NONE,                       // 4A
        OP_NONE,                       // 4B
        OP_NONE,                       // 4C
        OP_NONE,                       // 4D
        OP_NONE,                       // 4E
        OP_NONE,                       // 4F
        OP_NONE,                       // 50
        OP_NONE,                       // 51
        OP_NONE,                       // 52
        OP_NONE,                       // 53
        OP_NONE,                       // 54
        OP_NONE,                       // 55
        OP_NONE,                       // 56
        OP_NONE,                       // 57
        OP_NONE,                       // 58
        OP_NONE,                       // 59
        OP_NONE,                       // 5A
        OP_NONE,                       // 5B
        OP_NONE,                       // 5C
        OP_NONE,                       // 5D
        OP_NONE,                       // 5E
        OP_NONE,                       // 5F
        OP_NONE,                       // 60
        OP_NONE,                       // 61
        OP_MODRM,                      // 62
        OP_MODRM,                      // 63
        OP_NONE,                       // 64
        OP_NONE,                       // 65
        OP_NONE,                       // 66
        OP_NONE,                       // 67
        OP_DATA_PRE66_67,              // 68
        OP_MODRM | OP_DATA_PRE66_67,   // 69
        OP_DATA_I8,                    // 6A
        OP_MODRM | OP_DATA_I8,         // 6B
        OP_NONE,                       // 6C
        OP_NONE,                       // 6D
        OP_NONE,                       // 6E
        OP_NONE,                       // 6F
        OP_DATA_I8,                    // 70
        OP_DATA_I8,                    // 71
        OP_DATA_I8,                    // 72
        OP_DATA_I8,                    // 73
        OP_DATA_I8,                    // 74
        OP_DATA_I8,                    // 75
        OP_DATA_I8,                    // 76
        OP_DATA_I8,                    // 77
        OP_DATA_I8,                    // 78
        OP_DATA_I8,                    // 79
        OP_DATA_I8,                    // 7A
        OP_DATA_I8,                    // 7B
        OP_DATA_I8,                    // 7C
        OP_DATA_I8,                    // 7D
        OP_DATA_I8,                    // 7E
        OP_DATA_I8,                    // 7F
        OP_MODRM | OP_DATA_I8,         // 80
        OP_MODRM | OP_DATA_PRE66_67,   // 81
        OP_MODRM | OP_DATA_I8,         // 82
        OP_MODRM | OP_DATA_I8,         // 83
        OP_MODRM,                      // 84
        OP_MODRM,                      // 85
        OP_MODRM,                      // 86
        OP_MODRM,                      // 87
        OP_MODRM,                      // 88
        OP_MODRM,                      // 89
        OP_MODRM,                      // 8A
        OP_MODRM,                      // 8B
        OP_MODRM,                      // 8C
        OP_MODRM,                      // 8D
        OP_MODRM,                      // 8E
        OP_MODRM,                      // 8F
        OP_NONE,                       // 90
        OP_NONE,                       // 91
        OP_NONE,                       // 92
        OP_NONE,                       // 93
        OP_NONE,                       // 94
        OP_NONE,                       // 95
        OP_NONE,                       // 96
        OP_NONE,                       // 97
        OP_NONE,                       // 98
        OP_NONE,                       // 99
        OP_DATA_I16 | OP_DATA_PRE66_67,// 9A
        OP_NONE,                       // 9B
        OP_NONE,                       // 9C
        OP_NONE,                       // 9D
        OP_NONE,                       // 9E
        OP_NONE,                       // 9F
        OP_DATA_PRE66_67,              // A0
        OP_DATA_PRE66_67,              // A1
        OP_DATA_PRE66_67,              // A2
        OP_DATA_PRE66_67,              // A3
        OP_NONE,                       // A4
        OP_NONE,                       // A5
        OP_NONE,                       // A6
        OP_NONE,                       // A7
        OP_DATA_I8,                    // A8
        OP_DATA_PRE66_67,              // A9
        OP_NONE,                       // AA
        OP_NONE,                       // AB
        OP_NONE,                       // AC
        OP_NONE,                       // AD
        OP_NONE,                       // AE
        OP_NONE,                       // AF
        OP_DATA_I8,                    // B0
        OP_DATA_I8,                    // B1
        OP_DATA_I8,                    // B2
        OP_DATA_I8,                    // B3
        OP_DATA_I8,                    // B4
        OP_DATA_I8,                    // B5
        OP_DATA_I8,                    // B6
        OP_DATA_I8,                    // B7
        OP_DATA_PRE66_67,              // B8
        OP_DATA_PRE66_67,              // B9
        OP_DATA_PRE66_67,              // BA
        OP_DATA_PRE66_67,              // BB
        OP_DATA_PRE66_67,              // BC
        OP_DATA_PRE66_67,              // BD
        OP_DATA_PRE66_67,              // BE
        OP_DATA_PRE66_67,              // BF
        OP_MODRM | OP_DATA_I8,         // C0
        OP_MODRM | OP_DATA_I8,         // C1
        OP_DATA_I16,                   // C2
        OP_NONE,                       // C3
        OP_MODRM,                      // C4
        OP_MODRM,                      // C5
        OP_MODRM   | OP_DATA_I8,       // C6
        OP_MODRM   | OP_DATA_PRE66_67, // C7
        OP_DATA_I8 | OP_DATA_I16,      // C8
        OP_NONE,                       // C9
        OP_DATA_I16,                   // CA
        OP_NONE,                       // CB
        OP_NONE,                       // CC
        OP_DATA_I8,                    // CD
        OP_NONE,                       // CE
        OP_NONE,                       // CF
        OP_MODRM,                      // D0
        OP_MODRM,                      // D1
        OP_MODRM,                      // D2
        OP_MODRM,                      // D3
        OP_DATA_I8,                    // D4
        OP_DATA_I8,                    // D5
        OP_NONE,                       // D6
        OP_NONE,                       // D7
        OP_WORD,                       // D8
        OP_WORD,                       // D9
        OP_WORD,                       // DA
        OP_WORD,                       // DB
        OP_WORD,                       // DC
        OP_WORD,                       // DD
        OP_WORD,                       // DE
        OP_WORD,                       // DF
        OP_DATA_I8,                    // E0
        OP_DATA_I8,                    // E1
        OP_DATA_I8,                    // E2
        OP_DATA_I8,                    // E3
        OP_DATA_I8,                    // E4
        OP_DATA_I8,                    // E5
        OP_DATA_I8,                    // E6
        OP_DATA_I8,                    // E7
        OP_DATA_PRE66_67 | OP_REL32,   // E8
        OP_DATA_PRE66_67 | OP_REL32,   // E9
        OP_DATA_I16 | OP_DATA_PRE66_67,// EA
        OP_DATA_I8,                    // EB
        OP_NONE,                       // EC
        OP_NONE,                       // ED
        OP_NONE,                       // EE
        OP_NONE,                       // EF
        OP_NONE,                       // F0
        OP_NONE,                       // F1
        OP_NONE,                       // F2
        OP_NONE,                       // F3
        OP_NONE,                       // F4
        OP_NONE,                       // F5
        OP_MODRM,                      // F6
        OP_MODRM,                      // F7
        OP_NONE,                       // F8
        OP_NONE,                       // F9
        OP_NONE,                       // FA
        OP_NONE,                       // FB
        OP_NONE,                       // FC
        OP_NONE,                       // FD
        OP_MODRM,                      // FE
        OP_MODRM | OP_REL32            // FF
    };
    
    UCHAR OpcodeFlagsExt[256] =
    {
        OP_MODRM,                      // 00
        OP_MODRM,                      // 01
        OP_MODRM,                      // 02
        OP_MODRM,                      // 03
        OP_NONE,                       // 04
        OP_NONE,                       // 05
        OP_NONE,                       // 06
        OP_NONE,                       // 07
        OP_NONE,                       // 08
        OP_NONE,                       // 09
        OP_NONE,                       // 0A
        OP_NONE,                       // 0B
        OP_NONE,                       // 0C
        OP_MODRM,                      // 0D
        OP_NONE,                       // 0E
        OP_MODRM | OP_DATA_I8,         // 0F
        OP_MODRM,                      // 10
        OP_MODRM,                      // 11
        OP_MODRM,                      // 12
        OP_MODRM,                      // 13
        OP_MODRM,                      // 14
        OP_MODRM,                      // 15
        OP_MODRM,                      // 16
        OP_MODRM,                      // 17
        OP_MODRM,                      // 18
        OP_NONE,                       // 19
        OP_NONE,                       // 1A
        OP_NONE,                       // 1B
        OP_NONE,                       // 1C
        OP_NONE,                       // 1D
        OP_NONE,                       // 1E
        OP_NONE,                       // 1F
        OP_MODRM,                      // 20
        OP_MODRM,                      // 21
        OP_MODRM,                      // 22
        OP_MODRM,                      // 23
        OP_MODRM,                      // 24
        OP_NONE,                       // 25
        OP_MODRM,                      // 26
        OP_NONE,                       // 27
        OP_MODRM,                      // 28
        OP_MODRM,                      // 29
        OP_MODRM,                      // 2A
        OP_MODRM,                      // 2B
        OP_MODRM,                      // 2C
        OP_MODRM,                      // 2D
        OP_MODRM,                      // 2E
        OP_MODRM,                      // 2F
        OP_NONE,                       // 30
        OP_NONE,                       // 31
        OP_NONE,                       // 32
        OP_NONE,                       // 33
        OP_NONE,                       // 34
        OP_NONE,                       // 35
        OP_NONE,                       // 36
        OP_NONE,                       // 37
        OP_NONE,                       // 38
        OP_NONE,                       // 39
        OP_NONE,                       // 3A
        OP_NONE,                       // 3B
        OP_NONE,                       // 3C
        OP_NONE,                       // 3D
        OP_NONE,                       // 3E
        OP_NONE,                       // 3F
        OP_MODRM,                      // 40
        OP_MODRM,                      // 41
        OP_MODRM,                      // 42
        OP_MODRM,                      // 43
        OP_MODRM,                      // 44
        OP_MODRM,                      // 45
        OP_MODRM,                      // 46
        OP_MODRM,                      // 47
        OP_MODRM,                      // 48
        OP_MODRM,                      // 49
        OP_MODRM,                      // 4A
        OP_MODRM,                      // 4B
        OP_MODRM,                      // 4C
        OP_MODRM,                      // 4D
        OP_MODRM,                      // 4E
        OP_MODRM,                      // 4F
        OP_MODRM,                      // 50
        OP_MODRM,                      // 51
        OP_MODRM,                      // 52
        OP_MODRM,                      // 53
        OP_MODRM,                      // 54
        OP_MODRM,                      // 55
        OP_MODRM,                      // 56
        OP_MODRM,                      // 57
        OP_MODRM,                      // 58
        OP_MODRM,                      // 59
        OP_MODRM,                      // 5A
        OP_MODRM,                      // 5B
        OP_MODRM,                      // 5C
        OP_MODRM,                      // 5D
        OP_MODRM,                      // 5E
        OP_MODRM,                      // 5F
        OP_MODRM,                      // 60
        OP_MODRM,                      // 61
        OP_MODRM,                      // 62
        OP_MODRM,                      // 63
        OP_MODRM,                      // 64
        OP_MODRM,                      // 65
        OP_MODRM,                      // 66
        OP_MODRM,                      // 67
        OP_MODRM,                      // 68
        OP_MODRM,                      // 69
        OP_MODRM,                      // 6A
        OP_MODRM,                      // 6B
        OP_MODRM,                      // 6C
        OP_MODRM,                      // 6D
        OP_MODRM,                      // 6E
        OP_MODRM,                      // 6F
        OP_MODRM | OP_DATA_I8,         // 70
        OP_MODRM | OP_DATA_I8,         // 71
        OP_MODRM | OP_DATA_I8,         // 72
        OP_MODRM | OP_DATA_I8,         // 73
        OP_MODRM,                      // 74
        OP_MODRM,                      // 75
        OP_MODRM,                      // 76
        OP_NONE,                       // 77
        OP_NONE,                       // 78
        OP_NONE,                       // 79
        OP_NONE,                       // 7A
        OP_NONE,                       // 7B
        OP_MODRM,                      // 7C
        OP_MODRM,                      // 7D
        OP_MODRM,                      // 7E
        OP_MODRM,                      // 7F
        OP_DATA_PRE66_67 | OP_REL32,   // 80
        OP_DATA_PRE66_67 | OP_REL32,   // 81
        OP_DATA_PRE66_67 | OP_REL32,   // 82
        OP_DATA_PRE66_67 | OP_REL32,   // 83
        OP_DATA_PRE66_67 | OP_REL32,   // 84
        OP_DATA_PRE66_67 | OP_REL32,   // 85
        OP_DATA_PRE66_67 | OP_REL32,   // 86
        OP_DATA_PRE66_67 | OP_REL32,   // 87
        OP_DATA_PRE66_67 | OP_REL32,   // 88
        OP_DATA_PRE66_67 | OP_REL32,   // 89
        OP_DATA_PRE66_67 | OP_REL32,   // 8A
        OP_DATA_PRE66_67 | OP_REL32,   // 8B
        OP_DATA_PRE66_67 | OP_REL32,   // 8C
        OP_DATA_PRE66_67 | OP_REL32,   // 8D
        OP_DATA_PRE66_67 | OP_REL32,   // 8E
        OP_DATA_PRE66_67 | OP_REL32,   // 8F
        OP_MODRM,                      // 90
        OP_MODRM,                      // 91
        OP_MODRM,                      // 92
        OP_MODRM,                      // 93
        OP_MODRM,                      // 94
        OP_MODRM,                      // 95
        OP_MODRM,                      // 96
        OP_MODRM,                      // 97
        OP_MODRM,                      // 98
        OP_MODRM,                      // 99
        OP_MODRM,                      // 9A
        OP_MODRM,                      // 9B
        OP_MODRM,                      // 9C
        OP_MODRM,                      // 9D
        OP_MODRM,                      // 9E
        OP_MODRM,                      // 9F
        OP_NONE,                       // A0
        OP_NONE,                       // A1
        OP_NONE,                       // A2
        OP_MODRM,                      // A3
        OP_MODRM | OP_DATA_I8,         // A4
        OP_MODRM,                      // A5
        OP_NONE,                       // A6
        OP_NONE,                       // A7
        OP_NONE,                       // A8
        OP_NONE,                       // A9
        OP_NONE,                       // AA
        OP_MODRM,                      // AB
        OP_MODRM | OP_DATA_I8,         // AC
        OP_MODRM,                      // AD
        OP_MODRM,                      // AE
        OP_MODRM,                      // AF
        OP_MODRM,                      // B0
        OP_MODRM,                      // B1
        OP_MODRM,                      // B2
        OP_MODRM,                      // B3
        OP_MODRM,                      // B4
        OP_MODRM,                      // B5
        OP_MODRM,                      // B6
        OP_MODRM,                      // B7
        OP_NONE,                       // B8
        OP_NONE,                       // B9
        OP_MODRM | OP_DATA_I8,         // BA
        OP_MODRM,                      // BB
        OP_MODRM,                      // BC
        OP_MODRM,                      // BD
        OP_MODRM,                      // BE
        OP_MODRM,                      // BF
        OP_MODRM,                      // C0
        OP_MODRM,                      // C1
        OP_MODRM | OP_DATA_I8,         // C2
        OP_MODRM,                      // C3
        OP_MODRM | OP_DATA_I8,         // C4
        OP_MODRM | OP_DATA_I8,         // C5
        OP_MODRM | OP_DATA_I8,         // C6 
        OP_MODRM,                      // C7
        OP_NONE,                       // C8
        OP_NONE,                       // C9
        OP_NONE,                       // CA
        OP_NONE,                       // CB
        OP_NONE,                       // CC
        OP_NONE,                       // CD
        OP_NONE,                       // CE
        OP_NONE,                       // CF
        OP_MODRM,                      // D0
        OP_MODRM,                      // D1
        OP_MODRM,                      // D2
        OP_MODRM,                      // D3
        OP_MODRM,                      // D4
        OP_MODRM,                      // D5
        OP_MODRM,                      // D6
        OP_MODRM,                      // D7
        OP_MODRM,                      // D8
        OP_MODRM,                      // D9
        OP_MODRM,                      // DA
        OP_MODRM,                      // DB
        OP_MODRM,                      // DC
        OP_MODRM,                      // DD
        OP_MODRM,                      // DE
        OP_MODRM,                      // DF
        OP_MODRM,                      // E0
        OP_MODRM,                      // E1
        OP_MODRM,                      // E2
        OP_MODRM,                      // E3
        OP_MODRM,                      // E4
        OP_MODRM,                      // E5
        OP_MODRM,                      // E6
        OP_MODRM,                      // E7
        OP_MODRM,                      // E8
        OP_MODRM,                      // E9
        OP_MODRM,                      // EA
        OP_MODRM,                      // EB
        OP_MODRM,                      // EC
        OP_MODRM,                      // ED
        OP_MODRM,                      // EE
        OP_MODRM,                      // EF
        OP_MODRM,                      // F0
        OP_MODRM,                      // F1
        OP_MODRM,                      // F2
        OP_MODRM,                      // F3
        OP_MODRM,                      // F4
        OP_MODRM,                      // F5
        OP_MODRM,                      // F6
        OP_MODRM,                      // F7 
        OP_MODRM,                      // F8
        OP_MODRM,                      // F9
        OP_MODRM,                      // FA
        OP_MODRM,                      // FB
        OP_MODRM,                      // FC
        OP_MODRM,                      // FD
        OP_MODRM,                      // FE
        OP_NONE                        // FF
    };
    
    
    //1. KeUpdateSystemTime
    //
    //nt!KeUpdateSystemTime + 0x417:
    //84096d65 33c9            xor     ecx, ecx
    //84096d67 8d542420        lea     edx, [esp + 20h]
    //
    //nt!KeUpdateSystemTime + 0x41d :
    //84096d6b 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0        <--ul_KdDebuggerEnabled_1
    //84096d72 7464            je      nt!KeUpdateSystemTime + 0x48a (84096dd8)
    //
    //
    //2. KeUpdateRunTime
    //
    //nt!KeUpdateRunTime + 0x149:
    //840970c2 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0        <--ul_KdDebuggerEnabled_2
    //840970c9 7412            je      nt!KeUpdateRunTime + 0x164 (840970dd)
    //
    //3. KdCheckForDebugBreak
    //
    //kd > uf kdcheckfordebugbreak
    //nt!KdCheckForDebugBreak:
    //840970e9 803d275d148400  cmp     byte ptr[nt!KdPitchDebugger(84145d27)], 0        <--ul_KdPitchDebugger_1
    //840970f0 7519            jne     nt!KdCheckForDebugBreak + 0x22 (8409710b)
    //
    //nt!KdCheckForDebugBreak + 0x9 :
    //840970f2 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0        <--ul_KdDebuggerEnabled_3
    //840970f9 7410            je      nt!KdCheckForDebugBreak + 0x22 (8409710b)
    //
    //
    //4. KdPollBreakIn
    //
    //kd > uf KdPollBreakIn
    //nt!KdPollBreakIn:
    //8409711f 8bff            mov     edi, edi
    //84097121 55              push    ebp
    //84097122 8bec            mov     ebp, esp
    //84097124 51              push    ecx
    //84097125 53              push    ebx
    //84097126 33db            xor     ebx, ebx
    //84097128 381d275d1484    cmp     byte ptr[nt!KdPitchDebugger(84145d27)], bl        <--ul_KdPitchDebugger_2
    //8409712e 7407            je      nt!KdPollBreakIn + 0x18 (84097137)
    //
    //nt!KdPollBreakIn + 0x11:
    //84097130 32c0            xor     al, al
    //84097132 e9d2000000      jmp     nt!KdPollBreakIn + 0xea (84097209)
    //
    //nt!KdPollBreakIn + 0x18 :
    //84097137 885dff          mov     byte ptr[ebp - 1], bl
    //8409713a 381d2c1d1884    cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], bl        <--ul_KdDebuggerEnabled_4
    //84097140 0f84c0000000    je      nt!KdPollBreakIn + 0xe7 (84097206)
    
    
    
    ULONG_PTR ul_KeUpdateSystemTimeAssist;
    ULONG_PTR ul_KeUpdateSystemTime;
    ULONG_PTR ul_KeUpdateRunTime;
    ULONG_PTR ul_KdCheckForDebugBreak;
    ULONG_PTR ul_KdPollBreakIn;
    
    //顺序按照上面注释的顺序
    ULONG_PTR ul_KdDebuggerEnabled_1;
    ULONG_PTR ul_KdDebuggerEnabled_2;
    ULONG_PTR ul_KdDebuggerEnabled_3;
    ULONG_PTR ul_KdDebuggerEnabled_4;
    
    ULONG_PTR ul_KdPitchDebugger_1;
    ULONG_PTR ul_KdPitchDebugger_2;
    
    
    
    //用来保存原来内核变量地址
    ULONG_PTR ul_oldKdDebuggerEnabled;
    ULONG_PTR ul_oldKdPitchDebugger;
    
    //自己定义的全局变量
    BOOLEAN bool_myKdDebuggerEnabled = TRUE;
    BOOLEAN bool_myKdPitchDebugger = FALSE;
    
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
    {
        NTSTATUS status;
        //转移内核变量
        MoveGlobal();
        //注册回调
        status = PsSetLoadImageNotifyRoutine(LoadImageRoutine);
        if (!NT_SUCCESS(status))
        {
            return status;
        }
        KdPrint(("注册回调函数成功!
    "));
        HookIoAllocMdl(TRUE);
        //获得KdDisableDebugger地址
        ulKdDisableDebugger = GetFuncAddrFromName(L"KdDisableDebugger");
        KdPrint(("ulKdDisableDebugger: 0x%08X
    ", ulKdDisableDebugger));
        //计算KdDisableDebuggerWithLock地址
        ulKdDisableDebuggerWithLock = (ulKdDisableDebugger + 2) + *(ULONG*)(ulKdDisableDebugger + 3) + 5;
        KdPrint(("ulKdDisableDebuggerWithLock: 0x%08X
    ",  ulKdDisableDebuggerWithLock));
        ulKeEnterKernelDebugger = GetFuncAddrFromName(L"KeEnterKernelDebugger");
        KdPrint(("ulKeEnterKernelDebugger: 0x%08X
    ", ulKeEnterKernelDebugger));
        //函数内部搜索特征码
        GetKdpStubAddr(ulKdDisableDebuggerWithLock);
        GetKdpTrapAddr(ulKeEnterKernelDebugger);
        //Hook KdpStub头部直接跳转到KdpTrap
        InlineHookEngine(ulKdpStub, ulKdpTrap);
        GetKdDebuggerEnabledAddr(ulKeEnterKernelDebugger);
        //改写KdDisableDebugger头部直接返回
        WritableOpen();
        __asm
        {
            pushad
            pushfd
            mov eax, ulKdDisableDebugger
            mov byte ptr ds:[eax], 0x90//nop
            mov byte ptr ds:[eax + 0x1], 0xc3//ret
            popfd
            popad
        }
    
        //改写KdDebuggerEnabled为0
        __asm
        {
            pushad
            pushfd
            mov eax, ulKdDebuggerEnabled
            mov dword ptr ds:[eax], 0x0
            popfd
            popad
        }
        WritableClose();
    
        pDriverObject->DriverUnload = DriverUnload;
    
        return STATUS_SUCCESS;
    }
    
    
    SIZE_T GetKdEnteredDebuggerAddr()
    {
        return KdEnteredDebugger;
    }
    
    PMDL MyIoAllocateMdl(
        PVOID VirtualAddress,
        ULONG Length,
        BOOLEAN SecondaryBuffer,
        BOOLEAN ChargeQuota,
        PIRP Irp
        )
    {
        PVOID pKdEnteredDebugger;
        pKdEnteredDebugger = (PVOID)GetKdEnteredDebuggerAddr();
    
        if (pKdEnteredDebugger == VirtualAddress)
        {
            VirtualAddress = (PVOID)((SIZE_T)pKdEnteredDebugger + 0x4);//+0x4是让它读到其他的位置
        }
    
        return OldIoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
    }
    
    
    unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode)
    {
        PUCHAR cPtr;
        UCHAR Flags;
        BOOLEAN PFX66, PFX67;
        BOOLEAN SibPresent;
        UCHAR iMod, iRM, iReg;
        UCHAR OffsetSize, Add;
        UCHAR Opcode;
    
        OffsetSize = 0;
        PFX66 = FALSE;
        PFX67 = FALSE;
        cPtr = (PUCHAR)Code;
    
        while ((*cPtr == 0x2E) || (*cPtr == 0x3E) || (*cPtr == 0x36) ||
            (*cPtr == 0x26) || (*cPtr == 0x64) || (*cPtr == 0x65) || 
            (*cPtr == 0xF0) || (*cPtr == 0xF2) || (*cPtr == 0xF3) ||
            (*cPtr == 0x66) || (*cPtr == 0x67)) 
        {
            if (*cPtr == 0x66) PFX66 = TRUE;
            if (*cPtr == 0x67) PFX67 = TRUE;
            cPtr++;
            if (cPtr > (PUCHAR)Code + 16) return 0; 
        }
        Opcode = *cPtr;
        if (pOpcode) *pOpcode = cPtr; 
        if (*cPtr == 0x0F)
        {
            cPtr++;
            Flags = OpcodeFlagsExt[*cPtr];
        } else 
        {
            Flags = OpcodeFlags[Opcode];
            if (Opcode >= 0xA0 && Opcode <= 0xA3) PFX66 = PFX67;
        }
        cPtr++;
        if (Flags & OP_WORD) cPtr++;    
        if (Flags & OP_MODRM)
        {
            iMod = *cPtr >> 6;
            iReg = (*cPtr & 0x38) >> 3;  
            iRM  = *cPtr &  7;
            cPtr++;
    
            if ((Opcode == 0xF6) && !iReg) Flags |= OP_DATA_I8;    
            if ((Opcode == 0xF7) && !iReg) Flags |= OP_DATA_PRE66_67; 
    
            SibPresent = !PFX67 & (iRM == 4);
            switch (iMod)
            {
            case 0: 
                if ( PFX67 && (iRM == 6)) OffsetSize = 2;
                if (!PFX67 && (iRM == 5)) OffsetSize = 4; 
                break;
            case 1: OffsetSize = 1;
                break; 
            case 2: if (PFX67) OffsetSize = 2; else OffsetSize = 4;
                break;
            case 3: SibPresent = FALSE;
            }
            if (SibPresent)
            {
                if (((*cPtr & 7) == 5) && ( (!iMod) || (iMod == 2) )) OffsetSize = 4;
                cPtr++;
            }
            cPtr = (PUCHAR)(ULONG)cPtr + OffsetSize;
        }
    
        if (Flags & OP_DATA_I8) cPtr ++;
        if (Flags & OP_DATA_I16) cPtr += 2;
        if (Flags & OP_DATA_I32) cPtr += 4;
        if (PFX66) Add = 2;
        else Add = 4;
        if (Flags & OP_DATA_PRE66_67) cPtr += Add;
        return (ULONG)cPtr - (ULONG)Code;
    }
    
    unsigned long GetPatchSize(void *Proc, unsigned long dwNeedSize)
    {
        ULONG Length;
        PUCHAR pOpcode;
        ULONG PatchSize = 0;
    
        do
        {
            Length = SizeOfCode(Proc, &pOpcode);
            if ((Length == 1) && (*pOpcode == 0xC3)) break;
            if ((Length == 3) && (*pOpcode == 0xC2)) break;
            Proc = (PVOID)((ULONG)Proc + Length);
    
            PatchSize += Length;
            if (PatchSize >= dwNeedSize)
            {
                break;
            }
    
        } while (Length);
    
        return PatchSize;
    }
    
    VOID WpOffAndToDpcLevel()
    {
        OldIrql = KeRaiseIrqlToDpcLevel();
        __asm
        {
            cli
            push eax
            mov eax, cr0
            and eax, 0FFFEFFFFh
            mov cr0, eax
            pop eax
        }
    }
    
    VOID WpOn()
    {
        __asm
        {
            push eax
            mov eax, cr0
            or eax, 10000h
            mov cr0, eax
            pop eax
            sti
        }
        KeLowerIrql(OldIrql);
    }
    
    VOID WritableOpen()
    {
        __asm
        {
            cli
            mov eax, cr0
            and eax, not 0x10000
            mov cr0, eax
        }
    }
    
    VOID WritableClose()
    {
        __asm
        {
            mov eax, cr0
            or eax, 0x10000
            mov cr0, eax
            sti
        }
    }
    
    VOID InlineHookEngine(ULONG uHookPoint, ULONG uNewFuncAddr)
    {
        ULONG uJmp = uNewFuncAddr - uHookPoint - 5;
    
        WritableOpen();
    
        __asm
        {
            mov eax, uHookPoint
            mov byte ptr ds:[eax], 0xe9
            mov ebx, uJmp
            mov dword ptr ds:[eax + 0x1], ebx
        }
    
        WritableClose();
    }
    
    VOID UnInlineHookEngine(ULONG uHookPoint, char* pCode, ULONG uLength)
    {
        WritableOpen();
    
        RtlCopyMemory((char*)uHookPoint, pCode, uLength);
    
        WritableClose();
    }
    
    NTSTATUS WriteKernelMemory(PVOID Address, ULONG Size, PVOID InBuffer)
    {
        NTSTATUS st = STATUS_UNSUCCESSFUL;
        PMDL pMdl = 0;
        PVOID pAddress = 0;
        KSPIN_LOCK spinlock;
        KIRQL oldirql;
    
        if (!Address) return st;
        pMdl = IoAllocateMdl(Address, Size, FALSE, FALSE, 0);
        if (pMdl)
        {
            MmBuildMdlForNonPagedPool(pMdl);
            pAddress = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);
            KdPrint(("pAddress: 0x%08x
    ", pAddress));
            if (pAddress)
            {
                __try
                {
                    KeInitializeSpinLock(&spinlock);
                    KeAcquireSpinLock(&spinlock, &oldirql);
                    WpOffAndToDpcLevel();
                    RtlCopyMemory(pAddress, InBuffer, Size);
                    WpOn();
                    KeReleaseSpinLock(&spinlock, oldirql);
                    st = STATUS_SUCCESS;
                }
                __except (EXCEPTION_EXECUTE_HANDLER)
                {
                }
            }
            IoFreeMdl(pMdl);
        }
        return st;
    }
    
    void Hook(PVOID Func, PVOID New_Func, PVOID Proxy_Func)
    {
        ULONG PatchSize;
        BYTE g_HookCode[5] = {0xe9, 0, 0, 0, 0};//相对跳转
        BYTE Jmp_Orig_Code[7] = {0xea, 0, 0, 0, 0, 0x08, 0x00};//绝对地址跳转
        PatchSize = GetPatchSize(Func, 5);//获得要Patch的字节数 
        //构造Proxy_Func
        memcpy((PBYTE)Proxy_Func, (PBYTE)Func, PatchSize);//实现原函数头
        *((PULONG)(Jmp_Orig_Code + 1)) = (ULONG)((PBYTE)Func + PatchSize);//原函数+N地址
        memcpy((PBYTE)Proxy_Func + PatchSize, Jmp_Orig_Code, 7);//绝对地址跳转
        *((ULONG*)(g_HookCode + 1)) = (ULONG)New_Func - (ULONG)Func - 5;//计算JMP地址
        WriteKernelMemory(Func, 5, g_HookCode);
    }
    
    //UnHook函数
    void UnHook(PVOID Func, PVOID Proxy_Func)
    {
        WriteKernelMemory(Func, 5, Proxy_Func);
    }
    
    void HookIoAllocMdl(BOOLEAN bEnble)
    {
        if (bEnble == TRUE)
        {
            OldIoAllocateMdl = kmalloc(20);
            memset(OldIoAllocateMdl, 0x90, 20);
            Hook(IoAllocateMdl, MyIoAllocateMdl, (PVOID)OldIoAllocateMdl);
            DbgPrint("IoAllocateMdl hooked!
    ");
        }
        else
        {
            UnHook(IoAllocateMdl, OldIoAllocateMdl);
            ExFreePool(OldIoAllocateMdl);
            DbgPrint("IoAllocateMdl unhooked!
    ");
        }
    }
    
    //模块加载回调函数例程
    VOID LoadImageRoutine(
        IN PUNICODE_STRING FullImageName,
        IN HANDLE ProcessId,//where image is mapped
        IN PIMAGE_INFO ImageInfo
        )
    {
        UNREFERENCED_PARAMETER(ProcessId);
        if (wcsstr(FullImageName->Buffer, L"TesSafe.sys") != NULL)
        {
            KdPrint(("TesSafe.sys Loaded!
    "));
            KdPrint(("TesSafe.sys ImageBase: 0x%08X
    ", (ULONG)ImageInfo->ImageBase));
            KdPrint(("TesSafe.sys ImageSize: 0x%08X
    ", (ULONG)ImageInfo->ImageSize));
            KdPrint(("断点命令: ba e 1 0x%08X
    ", (ULONG)ImageInfo->ImageBase));
    
            //KdBreakPoint();
        }
        return;
    }
    
    ULONG FindCharacteristicCode(ULONG uAddr, char* pCode, ULONG uLength)
    {
        char szTemp[256];
        ULONG i = 5000;
    
        while(i --)
        {
            RtlMoveMemory(szTemp, (char*)uAddr, uLength);
    
            if (RtlCompareMemory(pCode, szTemp, uLength) == uLength)
            {
                return uAddr;
            }
    
            uAddr ++;
        }
    
        return 0;
    }
    
    VOID GetKdpStubAddr(ULONG uStartSearchAddr)
    {
        /*
        kd> u KdDisableDebugger
        nt!KdDisableDebugger:
        83f32846 6a01            push    1
        83f32848 e806ffffff      call    nt!KdDisableDebuggerWithLock (83f32753)
        83f3284d c3              ret
    
        kd> 
        nt!KdDisableDebuggerWithLock+0x68:
        83f1b7bb 8b0d6c89fa83    mov     ecx,dword ptr [nt!KeNumberProcessors (83fa896c)]
        83f1b7c1 33c0            xor     eax,eax
        83f1b7c3 85c9            test    ecx,ecx
        83f1b7c5 761a            jbe     nt!KdDisableDebuggerWithLock+0x8e (83f1b7e1)
        83f1b7c7 8b0c85c088fa83  mov     ecx,dword ptr nt!KiProcessorBlock (83fa88c0)[eax*4]
        83f1b7ce 389908030000    cmp     byte ptr [ecx+308h],bl
        83f1b7d4 7551            jne     nt!KdDisableDebuggerWithLock+0xd4 (83f1b827)
        83f1b7d6 8b0d6c89fa83    mov     ecx,dword ptr [nt!KeNumberProcessors (83fa896c)]
        kd> 
        nt!KdDisableDebuggerWithLock+0x89:
        83f1b7dc 40              inc     eax
        83f1b7dd 3bc1            cmp     eax,ecx
        83f1b7df 72e6            jb      nt!KdDisableDebuggerWithLock+0x74 (83f1b7c7)
        83f1b7e1 381d2c3dfa83    cmp     byte ptr [nt!KdDebuggerEnabled (83fa3d2c)],bl
        83f1b7e7 741b            je      nt!KdDisableDebuggerWithLock+0xb1 (83f1b804)
        83f1b7e9 e8021a2500      call    nt!KdpSuspendAllBreakpoints (8416d1f0)
        83f1b7ee 881d2c3dfa83    mov     byte ptr [nt!KdDebuggerEnabled (83fa3d2c)],bl
        83f1b7f4 c705bc89fa83afb9f183 mov dword ptr [nt!KiDebugRoutine (83fa89bc)],offset nt!KdpStub (83f1b9af)
        */
    
        ULONG ulTemp;
        char code[4] = {(char)0x40, (char)0x3b, (char)0xc1, (char)0x72};
    
        ulTemp = FindCharacteristicCode(uStartSearchAddr, code, 4) + 0x1e;
    
        if (!MmIsAddressValid((PVOID)ulTemp))
        {
            KdPrint(("ulTemp is invalid!
    "));
            return;
        }
    
        ulKdpStub = *(ULONG*)ulTemp;
    
        KdPrint(("ulKdpStub: 0x%08X
    ", ulKdpStub));
    }
    
    VOID GetKdpTrapAddr(ULONG uStartSearchAddr)
    {
        /*
        kd> 
        nt!KeEnterKernelDebugger+0x2f:
        83f2efc0 8731            xchg    esi,dword ptr [ecx]
        83f2efc2 85f6            test    esi,esi
        83f2efc4 7507            jne     nt!KeEnterKernelDebugger+0x3c (83f2efcd)
        83f2efc6 50              push    eax
        83f2efc7 50              push    eax
        83f2efc8 e83dc12400      call    nt!KdInitSystem (8417b10a)
        83f2efcd 6a05            push    5
        83f2efcf e893f0ffff      call    nt!KiBugCheckDebugBreak (83f2e067)
    
        kd> 
        nt!KdInitSystem+0x285:
        8417b38f 99              cdq
        8417b390 a3109cf783      mov     dword ptr [nt!KdVersionBlock+0x10 (83f79c10)],eax
        8417b395 8915149cf783    mov     dword ptr [nt!KdVersionBlock+0x14 (83f79c14)],edx
        8417b39b c644241101      mov     byte ptr [esp+11h],1
        8417b3a0 a1109cf783      mov     eax,dword ptr [nt!KdVersionBlock+0x10 (83f79c10)]
        8417b3a5 33f6            xor     esi,esi
        8417b3a7 807c241100      cmp     byte ptr [esp+11h],0
        8417b3ac a3409cf783      mov     dword ptr [nt!KdDebuggerDataBlock+0x18 (83f79c40)],eax
        kd> 
        nt!KdInitSystem+0x2a7:
        8417b3b1 8935449cf783    mov     dword ptr [nt!KdDebuggerDataBlock+0x1c (83f79c44)],esi
        8417b3b7 0f8428010000    je      nt!KdInitSystem+0x3db (8417b4e5)
        8417b3bd 53              push    ebx
        8417b3be e8977acdff      call    nt!KdDebuggerInitialize0 (83e52e5a)
        8417b3c3 85c0            test    eax,eax
        8417b3c5 0f8c1a010000    jl      nt!KdInitSystem+0x3db (8417b4e5)
        8417b3cb 803d18801c8400  cmp     byte ptr [nt!KdpDebuggerStructuresInitialized (841c8018)],0
        8417b3d2 c705bc99fb83f2c41784 mov dword ptr [nt!KiDebugRoutine (83fb99bc)],offset nt!KdpTrap (8417c4f2)
        */
        ULONG uTemp;
        char code1[3] = {(char)0x50, (char)0x50, (char)0xe8};
        char code2[3] = {(char)0x85, (char)0xc0, (char)0x0f};
    
        uTemp = FindCharacteristicCode(uStartSearchAddr, code1, 3) + 2;
    
        if (!MmIsAddressValid((PVOID)uTemp))
        {
            KdPrint(("uTemp is invalid!
    "));
            return;
        }
    
        ulKdInitSystem = uTemp + *(ULONG*)(uTemp + 1) + 5;
        KdPrint(("ulKdInitSystem: 0x%08X
    ", ulKdInitSystem));
    
        uTemp = FindCharacteristicCode(ulKdInitSystem + 0x285, code2, 3);
        ulKdpTrap = *(ULONG*)(uTemp + 0x15);
        KdPrint(("ulKdpTrap: 0x%08X
    ", ulKdpTrap));
    }
    
    VOID GetKdDebuggerEnabledAddr(ULONG uStartSearchAddr)
    {
        /*
        kd> u
        nt!KeEnterKernelDebugger+0xd:
        83ee2f9e 8935fcc1f383    mov     dword ptr [nt!KiHardwareTrigger (83f3c1fc)],esi
        83ee2fa4 e8dbd9f9ff      call    nt!KeDisableInterrupts (83e80984)
        83ee2fa9 33c0            xor     eax,eax
        83ee2fab 38052c8df683    cmp     byte ptr [nt!KdDebuggerEnabled (83f68d2c)],al
        83ee2fb1 751a            jne     nt!KeEnterKernelDebugger+0x3c (83ee2fcd)
        83ee2fb3 380527cdf283    cmp     byte ptr [nt!KdPitchDebugger (83f2cd27)],al
        83ee2fb9 7512            jne     nt!KeEnterKernelDebugger+0x3c (83ee2fcd)
        83ee2fbb b980c1f383      mov     ecx,offset nt!KiBugCheckDriver+0x4 (83f3c180)
        */
    
        ULONG ulTemp;
        char code[3] = {(char)0x33, (char)0xc0, (char)0x38};
    
        ulTemp = FindCharacteristicCode(uStartSearchAddr, code, 3);
    
        ulKdDebuggerEnabled = *(ULONG*)(ulTemp + 4);
        KdPrint(("ulKdDebuggerEnabled: 0x%08X
    ", ulKdDebuggerEnabled));
    }
    
    ULONG GetFuncAddrFromName(IN PCWSTR FunctionName)
    {
        UNICODE_STRING FuncName;
        RtlInitUnicodeString(&FuncName, FunctionName);
        return (ULONG)MmGetSystemRoutineAddress(&FuncName);
    }
    
    VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
    {
        //KdpStub头部5个字节
        char code[5] = {(char)0x8b, (char)0xff, (char)0x55, (char)0x8b, (char)0xec};
    
        //恢复内核变量
        RecoverGlobal();
    
        //删除回调
        PsRemoveLoadImageNotifyRoutine(LoadImageRoutine);
        HookIoAllocMdl(FALSE);
    
        //恢复KdpStub头部
        UnInlineHookEngine(ulKdpStub, code, 5);
    
        //恢复KdDisableDebugger头部
        WritableOpen();
        __asm
        {
            pushad
            pushfd
            mov eax, ulKdDisableDebugger
            mov byte ptr ds:[eax], 0x6a
            mov byte ptr ds:[eax + 0x1], 0x01
            popfd
            popad
        }
    
        //改写KdDebuggerEnabled为1
        __asm
        {
            pushad
            pushfd
            mov eax, ulKdDebuggerEnabled
            mov dword ptr ds:[eax], 0x1
            popfd
            popad
        }
        WritableClose();
    }
    
    
    //查找函数地址
    PVOID GetFuncAddress(LPWSTR lpFuncName)
    {
        PVOID pFuncName;
        UNICODE_STRING usFuncName;
    
        RtlInitUnicodeString(&usFuncName, lpFuncName);
        KdPrint(("%wZ
    ", &usFuncName));
        pFuncName = MmGetSystemRoutineAddress(&usFuncName);
    
        return pFuncName;
    }
    
    void WPOFF()
    {
        //选择性编译,是给编译器看的
    #ifdef _WIN64
        _disable();
        __writecr0(__readcr0() & (~(0x10000)));
    #else
        __asm
        {
            CLI;
            MOV EAX, CR0;
            AND EAX, NOT 10000H;
            MOV CR0, EAX;
        }
    #endif
    }
    
    void WPON()
    {
    #ifdef _WIN64
        __writecr0(__readcr0() ^ 0x10000);
        _enable();
    #else
        __asm
        {
            MOV EAX, CR0;
            OR EAX, 10000H;
            MOV CR0, EAX;
            STI;
        }
    #endif
    }
    
    
    
    ULONG_PTR GetKeUpdateSystemTimeAddr()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KeUpdateSystemTimeAssist;
        ULONG_PTR retAddress;
        for (i = 0; i < 100; i++)
        {
            if (*(pStart + i) == 0xe8 &&
                *(pStart + i + 5) == 0xfa)
            {
                retAddress = *(ULONG_PTR*)(pStart + i + 1) + (ULONG_PTR)(pStart + i) + 5;
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdCheckForDebugBreak()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KeUpdateRunTime;
        ULONG_PTR retAddress;
        for (i = 0x100; i < 0x200; i++)
        {
            if (*(pStart + i) == 0xe8 &&
                *(pStart + i + 5) == 0x5f)
            {
                retAddress = *(ULONG_PTR*)(pStart + i + 1) + (ULONG_PTR)(pStart + i) + 5;
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdDebuggerEnabled_1()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KeUpdateSystemTime;
        ULONG_PTR retAddress;
        for (i = 0x400; i < 0x500; i++)
        {
            if (*(pStart + i) == 0x80 &&
                *(pStart + i + 1) == 0x3d &&
                *(pStart + i + 7) == 0x74 &&
                *(pStart + i + 8) == 0x64)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdDebuggerEnabled_2()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KeUpdateRunTime;
        ULONG_PTR retAddress;
        for (i = 0x100; i < 0x200; i++)
        {
            if (*(pStart + i) == 0x80 &&
                *(pStart + i + 1) == 0x3d &&
                *(pStart + i + 7) == 0x74 &&
                *(pStart + i + 8) == 0x12)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdDebuggerEnabled_3()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KdCheckForDebugBreak;
        ULONG_PTR retAddress;
        for (i = 0; i < 100; i++)
        {
            if (*(pStart + i) == 0x80 &&
                *(pStart + i + 1) == 0x3d &&
                *(pStart + i + 7) == 0x74 &&
                *(pStart + i + 8) == 0x10)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdDebuggerEnabled_4()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KdPollBreakIn;
        ULONG_PTR retAddress;
        for (i = 0; i < 50; i++)
        {
            if (*(pStart + i) == 0x38 &&
                *(pStart + i + 1) == 0x1d &&
                *(pStart + i + 6) == 0x0f &&
                *(pStart + i + 7) == 0x84)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdPitchDebugger_1()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KdCheckForDebugBreak;
        ULONG_PTR retAddress;
        for (i = 0; i < 100; i++)
        {
            if (*(pStart + i) == 0x80 &&
                *(pStart + i + 1) == 0x3d &&
                *(pStart + i + 7) == 0x75 &&
                *(pStart + i + 8) == 0x19)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    ULONG_PTR GetKdPitchDebugger_2()
    {
        ULONG i;
        PUCHAR pStart = (PUCHAR)ul_KdPollBreakIn;
        ULONG_PTR retAddress;
        for (i = 0; i < 100; i++)
        {
            if (*(pStart + i) == 0x38 &&
                *(pStart + i + 1) == 0x1d &&
                *(pStart + i + 6) == 0x74 &&
                *(pStart + i + 7) == 0x07)
            {
                retAddress = (ULONG_PTR)(pStart + i + 2);
                return retAddress;
            }
        }
        return 0;
    }
    
    //转移内核变量函数
    void MoveGlobal()
    {
        ul_KeUpdateSystemTimeAssist = (ULONG_PTR)GetFuncAddress(L"KeUpdateSystemTime");
        ul_KeUpdateSystemTime = GetKeUpdateSystemTimeAddr();
        ul_KdDebuggerEnabled_1 = GetKdDebuggerEnabled_1();
    
        ul_KeUpdateRunTime = (ULONG_PTR)GetFuncAddress(L"KeUpdateRunTime");
        ul_KdDebuggerEnabled_2 = GetKdDebuggerEnabled_2();
    
    
        ul_KdCheckForDebugBreak = GetKdCheckForDebugBreak();
    
        ul_KdDebuggerEnabled_3 = GetKdDebuggerEnabled_3();
        ul_KdPitchDebugger_1 = GetKdPitchDebugger_1();
    
    
        ul_KdPollBreakIn = (ULONG_PTR)GetFuncAddress(L"KdPollBreakIn");
        ul_KdDebuggerEnabled_4 = GetKdDebuggerEnabled_4();
    
        ul_KdPitchDebugger_2 = GetKdPitchDebugger_2();
    
        //保存原始内核变量
        ul_oldKdDebuggerEnabled = *(ULONG_PTR*)ul_KdDebuggerEnabled_1;
        ul_oldKdPitchDebugger = *(ULONG_PTR*)ul_KdPitchDebugger_1;
    
        WPOFF();
        //开始转移内核变量
        *(ULONG_PTR*)ul_KdDebuggerEnabled_1 = (ULONG_PTR)&bool_myKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_2 = (ULONG_PTR)&bool_myKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_3 = (ULONG_PTR)&bool_myKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_4 = (ULONG_PTR)&bool_myKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdPitchDebugger_1 = (ULONG_PTR)&bool_myKdPitchDebugger;
        *(ULONG_PTR*)ul_KdPitchDebugger_2 = (ULONG_PTR)&bool_myKdPitchDebugger;
        WPON();
    
        KdPrint(("内核变量转移完成
    "));
    }
    
    //恢复转移的内核变量
    void RecoverGlobal()
    {
        //恢复原来内核变量
        WPOFF();
        *(ULONG_PTR*)ul_KdDebuggerEnabled_1 = ul_oldKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_2 = ul_oldKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_3 = ul_oldKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdDebuggerEnabled_4 = ul_oldKdDebuggerEnabled;
        *(ULONG_PTR*)ul_KdPitchDebugger_1 = ul_oldKdPitchDebugger;
        *(ULONG_PTR*)ul_KdPitchDebugger_2 = ul_oldKdPitchDebugger;
        WPON();
        KdPrint(("内核变量恢复完成
    "));
    }
  • 相关阅读:
    你了解RTOS吗?
    [转] git rebase 详解
    MinGW vs MinGW-W64及其它
    【转】Video Rendering with 8-Bit YUV Formats
    Ubuntu假死
    渐进增强和优雅降级的区别
    JavaScript 插件的学习
    菜单的制作
    生活
    小组学习情况
  • 原文地址:https://www.cnblogs.com/lanrenxinxin/p/4378218.html
Copyright © 2011-2022 走看看