首页
社区
课程
招聘
[旧帖] [求助]inline hook NtSetValueKey 蓝屏 0.00雪花
发表于: 2011-7-21 10:57 1277

[旧帖] [求助]inline hook NtSetValueKey 蓝屏 0.00雪花

2011-7-21 10:57
1277
//保存原先开头的5个自己
BYTE reg_ZwSetValueKeyOldAddress[7]={0};
//jmp新的函数地址
BYTE reg_ZwSetValueKeyNewAddress[5]={0xe9,0,0,0,0};
BYTE reg_ZwSetValueKeyJmpAddress[7]={0xea,0,0,0,0,0x08,0};

//去除内存保护
VOID UnProtected()
{
        _asm{
                push eax
                        mov eax,cr0
                        and eax,not 10000h
                        mov cr0,eax
                        pop eax
        }
};

//恢复内存保护
VOID Protected()
{
        _asm{  
                push eax
                        mov eax,cr0
                        or eax,10000h
                        mov cr0,eax
                        pop eax
        }
};

//SDT结构体
typedef struct ServiceDescriptorTable {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTable;
        unsigned int NumberOfServices;
        unsigned int *ParamTableBase;
}ServiceDescriptorTable,*PServiceDescriptorTable;

//获得SSDT函数地址
#define GetSSDTFuncAddress(_func) KeServiceDescriptorTable->ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]

typedef NTSTATUS  (*PNtSetValueKey)(                                                IN HANDLE KeyHandle,
        IN PUNICODE_STRING ValueName,
        IN ULONG TitleIndex,
        IN ULONG Type,
        IN PVOID Data,
        IN ULONG DataSize
        );

NTSTATUS  JmpZwSetValueKey(
                IN HANDLE KeyHandle,
        IN PUNICODE_STRING ValueName,
        IN ULONG TitleIndex,
        IN ULONG Type,
        IN PVOID Data,
        IN ULONG DataSize
        );

NTSTATUS  NewZwSetValueKey(
        IN HANDLE KeyHandle,
        IN PUNICODE_STRING ValueName,
        IN ULONG TitleIndex,
        IN ULONG Type,
        IN PVOID Data,
        IN ULONG DataSize
         );

PNtSetValueKey NtSetValueKey = NULL;

//在这里InlineHook
VOID reg_inlineHook()
{

        //赋值前面定义的数组
        KIRQL Irql;
    KSPIN_LOCK SDTSpinLock;

        __try
        {
                KeAcquireSpinLock (&SDTSpinLock, &Irql);

                NtSetValueKey = (PNtSetValueKey)GetSSDTFuncAddress(ZwSetValueKey);

                //保存函数前7个字节内容
                RtlCopyMemory(reg_ZwSetValueKeyOldAddress,(PBYTE)NtSetValueKey,7);

                //保存新函数五个字节之后偏移
                *(PULONG)(reg_ZwSetValueKeyNewAddress+1)=(ULONG)NewZwSetValueKey-((ULONG)NtSetValueKey + 5);

                //开始inline hook
                //关闭内存写保护
                UnProtected();

                //函数开头五个字节写JMP

                RtlCopyMemory((PBYTE)NtSetValueKey,reg_ZwSetValueKeyNewAddress,5);
        *(PULONG)(reg_ZwSetValueKeyJmpAddress+1) =(ULONG)((PBYTE)NtSetValueKey + 7);
                RtlCopyMemory((PBYTE)JmpZwSetValueKey, reg_ZwSetValueKeyOldAddress, 7);
                RtlCopyMemory((PBYTE)JmpZwSetValueKey + 7, reg_ZwSetValueKeyJmpAddress, 7);

                //开启内存写保护
                Protected();

                KeReleaseSpinLock (&SDTSpinLock, Irql);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {

        }
}

//恢复
VOID reg_unInlineHook()
{

        //赋值前面定义的数组
        KIRQL Irql;
        KSPIN_LOCK SDTSpinLock;

        __try
        {

                KeAcquireSpinLock (&SDTSpinLock, &Irql);
                //关闭写保护
                UnProtected();

                //用原先保存的地址覆盖前7个字节
                RtlCopyMemory((PBYTE)NtSetValueKey,reg_ZwSetValueKeyOldAddress,7);
               
                //开启写保护
                Protected();

                KeReleaseSpinLock (&SDTSpinLock, Irql);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {

        }
}

__declspec(naked) NTSTATUS JmpZwSetValueKey
(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
)
{
        __asm
        {
                _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
        }
}

NTSTATUS  NewZwSetValueKey(
                                                   IN HANDLE KeyHandle,
                                                   IN PUNICODE_STRING ValueName,
                                                   IN ULONG TitleIndex,
                                                   IN ULONG Type,
                                                   IN PVOID Data,
                                                   IN ULONG DataSize
                                                 )
{
        __try
        {
                               DbgPrint("进来了!");
                //返回
                return JmpZwSetValueKey(
                        KeyHandle,
                        ValueName,
                        TitleIndex,
                        Type,
                        Data,
                        DataSize
                        );
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                return STATUS_UNSUCCESSFUL;
        }
}

上面就是代码了,钩子能安装,安装后不会蓝屏,但是就是感觉没有进入JmpZwSetValueKey,
新建注册表键值,总是提示失败;还有就是恢复钩子后,等几十秒,就莫名其妙的蓝屏了。

下面是windbg的报错信息:

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS (ce)
A driver unloaded without cancelling timers, DPCs, worker threads, etc.
The broken driver's name is displayed on the screen.
Arguments:
Arg1: b1c587a1, memory referenced
Arg2: 00000000, value 0 = read operation, 1 = write operation
Arg3: b1c587a1, If non-zero, the instruction address which referenced the bad memory
        address.
Arg4: 00000000, Mm internal code.

Debugging Details:
------------------

READ_ADDRESS:  b1c587a1

FAULTING_IP:
Deianeira+37a1
b1c587a1 ??              ???

DEFAULT_BUCKET_ID:  DRIVER_FAULT

BUGCHECK_STR:  0xCE

PROCESS_NAME:  winlogon.exe

TRAP_FRAME:  b20c342c -- (.trap 0xffffffffb20c342c)
ErrCode = 00000000
eax=c0000034 ebx=8056f2ee ecx=8056c3df edx=53c00001 esi=b20c35f8 edi=b20c3554
eip=b1c587a1 esp=b20c34a0 ebp=b20c34e0 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
<Unloaded_Test.sys>+0x37a1:
b1c587a1 ??              ???
Resetting default scope

IP_MODULE_UNLOADED:
Test+37a1
b1c587a1 ??              ???

LAST_CONTROL_TRANSFER:  from 804f8bad to 80528c0c

FAILED_INSTRUCTION_ADDRESS:
Test+37a1
b1c587a1 ??              ???

请大大们给个帮助。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
2
内核的东西还没有接触= =
等高手前来吧
2011-7-21 11:06
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
请各路大侠给点帮助啊
2011-7-22 15:56
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
ZwSetValueKey没看过代码呀,你观其指令前7字节是完整的结束,第8字节 是新指令的开始么?
另外没见你写入JMP指令呀。。。

还有:
//保存函数前7个字节内容
    RtlCopyMemory(reg_ZwSetValueKeyOldAddress,(PBYTE)NtSetValueKey,7);

    //保存新函数五个字节之后偏移
    *(PULONG)(reg_ZwSetValueKeyNewAddress+1)=(ULONG)NewZwSetValueKey-((ULONG)NtSetValueKey + 5);
这是什么逻辑呢?感觉像是在哪复制的呀。。。就是头用的牛的,胳膊用的马的,而腿又用的羊的?
2011-7-28 10:06
0
游客
登录 | 注册 方可回帖
返回
//