strke23 发表于 2013-8-9 17:32:36

一种无差别的anti-anti双机调试的方法

一种无差别的抗-反双击调试的方法,原创不原创不敢说,也许还有很多人也想到过这种方法
无差别,意思是不针对某.sys,完全只需要修改自己的内核即可实现的。。

思路如下,
Hook KdpStub 到一个我们的函数,暂名 beforeKdpTrap

beforeKdpTrap要做的事情如下

__declspec(naked) beforeKdpTrap() {
__asm {
    pushad
    mov eax, KdDebuggerEnabled
    mov byte ptr ,0x1
    popad
    jmp KdpTrap
}
}

这样做的好处是可以避免通过检测 KiDebugRoutine 来发现调试。

理论上,就算 KdpStub 被校验了,也可以在它的内部找另外一个跳板。

下面是一份win7 32bit 下,针对 Txxsafe.sys 所做的处理。

代码:#include <ntddk.h>
//#include "..\1.h"
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD nUnload;

KIRQL Irql;
PVOID uTesSafeIBase;

PVOID KdpStub;
PVOID KdpTrap;
PVOID KiDebugRoutine;
PVOID KdpSuspendAllBreakpoints;
PVOID KdDisableDebuggerWithLock;

PVOID GetSysRoutineAddress (IN PCWSTR funcName) {
UNICODE_STRING us_fn;
RtlInitUnicodeString(&us_fn,funcName);
return MmGetSystemRoutineAddress(&us_fn);
}

VOID WPOFF() {
__asm {
    cli
    mov eax,cr0
    and eax,not 10000h
    mov cr0,eax
}
}

VOID WPON() {
__asm {
    mov eax,cr0
    or eax,10000h
    mov cr0,eax
    sti
}
}

__declspec(naked) beforeKdpTrap() {
__asm {
    pushad
    mov eax, KdDebuggerEnabled
    mov byte ptr ,0x1
    popad
    jmp KdpTrap
}
}

__declspec(naked) nkKdDisableDebuggerWithLock() {
__asm {
    pushad
    mov eax, KdDebuggerEnabled
    mov byte ptr ,0x0
    popad
    mov edi,edi
    push ebp
    mov ebp,esp
    push ecx
    push KdDisableDebuggerWithLock
    add dword ptr ,0x6
    retn
}
}

VOID LoadImageNotifyRoutine( __in_opt PUNICODE_STRING FullImageName, __in HANDLE ProcessId, __in PIMAGE_INFOImageInfo ) {
if (wcsstr(FullImageName->Buffer, L"TesSafe.sys") && wcsstr(FullImageName->Buffer, L":") ) {
    uTesSafeIBase=ImageInfo->ImageBase;
    __asm {
      int 3
    }
}
}

VOID initialize() {

PVOID *p1;
PVOID f1;

p1 = (ULONG)KdEnableDebugger+3;
f1 = (ULONG)KdEnableDebugger+7+(ULONG)*p1;

p1 = (ULONG)f1+0x7b;
f1 = (ULONG)f1+0x7f+(ULONG)*p1;//KdInitSystem

p1 = (ULONG)f1+0x4c;
KiDebugRoutine=(ULONG)*p1;

p1 = (ULONG)f1+0x50;
KdpStub=(ULONG)*p1;

p1 = (ULONG)f1+0x2ce;
KdpTrap=(ULONG)*p1;


p1 = (ULONG)KdDisableDebugger+3;
f1 = (ULONG)KdDisableDebugger+7+(ULONG)*p1;//KdDisableDebuggerWithLock
KdDisableDebuggerWithLock = f1;
p1 = (ULONG)f1+0x97;
KdpSuspendAllBreakpoints = (ULONG)f1+0x9b+(ULONG)*p1;//KdpSuspendAllBreakpoints


WPOFF();
Irql=KeRaiseIrqlToDpcLevel();
__asm {
    pushad

    mov eax, KdpSuspendAllBreakpoints
    mov byte ptr , 0xc3

    mov eax, KdpStub
    mov byte ptr , 0x68
    mov ebx, beforeKdpTrap
    mov dword ptr , ebx
    mov byte ptr , 0xC3

    mov eax, KdDisableDebuggerWithLock
    mov byte ptr , 0x68
    mov ebx, nkKdDisableDebuggerWithLock
    mov dword ptr , ebx
    mov byte ptr , 0xC3

    popad
}
KeLowerIrql(Irql);
WPON();

PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
}

VOID nUnload(__in struct _DRIVER_OBJECT *DriverObject) {
PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
WPOFF();
Irql=KeRaiseIrqlToDpcLevel();
__asm {
    pushad
    mov eax, KdpStub
    mov byte ptr , 0x8b
    mov byte ptr , 0xff
    mov byte ptr , 0x55
    mov byte ptr , 0x8b
    mov byte ptr , 0xec
    mov byte ptr , 0x53

    mov eax, KdDisableDebuggerWithLock
    mov byte ptr , 0x8b
    mov byte ptr , 0xff
    mov byte ptr , 0x55
    mov byte ptr , 0x8b
    mov byte ptr , 0xec
    mov byte ptr , 0x51
    popad
}
KeLowerIrql(Irql);
WPON();
}

NTSTATUS DriverEntry (__in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath) {
initialize();
DriverObject->DriverUnload = nUnload;
return STATUS_SUCCESS;
}
最后我就说一句,本人所分析的内容完全属于本人自己电脑上cpu、内存中的内容,没有修改任何第三方程序本身的代码()。。。以上提到的某Txxsafe.sys仅用来运行测试。
页: [1]
查看完整版本: 一种无差别的anti-anti双机调试的方法