分析一个win64保护驱动

1. bp ObRegisterCallbacks, 下段后,在函数入口处断下,此时查看返回地址。

Breakpoint 0 hit

nt!ObRegisterCallbacks:

fffff800`042d05a0 488bc4          mov    rax,rsp

*** ERROR: Module load completed but symbols could not be loaded for win7.sys

2: kd> dq rsp

fffff880`047d47d8  fffff880`03a7e24a ffffffff`8000074c      //fffff880`03a7e24a  是返回地址

fffff880`047d47e8  00000000`00000001 00000000`0000000e

fffff880`047d47f8  fffffa80`614eb000 fffff800`040cb020

fffff880`047d4808  00000000`00000001 fffff880`03a7e330

fffff880`047d4818  00000000`00000000 00000000`00010100

fffff880`047d4828  00000000`000a0008 fffff880`03a7e670

fffff880`047d4838  00000000`00000000 fffff880`047d4800

fffff880`047d4848  fffff880`047d49c0 00000000`00000000

2: kd> u fffff880`03a7e24a

win7+0x124a:

fffff880`03a7e24a 8bd8            mov    ebx,eax

fffff880`03a7e24c b8010000c0      mov    eax,0C0000001h

fffff880`03a7e251 85db            test    ebx,ebx

fffff880`03a7e253 0f48d8          cmovs  ebx,eax

fffff880`03a7e256 e811000000      call    win7+0x126c (fffff880`03a7e26c)

fffff880`03a7e25b 8bc3            mov    eax,ebx

fffff880`03a7e25d 488b9c2480000000 mov    rbx,qword ptr [rsp+80h]

fffff880`03a7e265 4883c470        add    rsp,70h

根据上述代码,对照win7.sys函数反编译源码: 我们看到尾部的偏移一致。

.text:0000000140001244                call    cs:ObRegisterCallbacks

.text:000000014000124A                mov    ebx, eax

.text:000000014000124C                mov    eax, 0C0000001h

.text:0000000140001251                test    ebx, ebx

.text:0000000140001253                cmovs  ebx, eax

.text:0000000140001256                call    sub_14000126C

.text:000000014000125B                mov    eax, ebx

.text:000000014000125D                mov    rbx, [rsp+78h+arg_0]

.text:0000000140001265                add    rsp, 70h

.text:0000000140001269                pop    rbp

.text:000000014000126A                retn

根据注册回调函数的用法:ObRegisterCallbacks(&obReg, &obHandle);

再看rsp+8,若用堆栈传递参数,这个就应该是第一参数arg0。

2: kd> dq ffffffff`8000074c

ffffffff`8000074c  ????????`???????? ????????`????????

ffffffff`8000075c  ????????`???????? ????????`????????

ffffffff`8000076c  ????????`???????? ????????`????????

ffffffff`8000077c  ????????`???????? ????????`????????

ffffffff`8000078c  ????????`???????? ????????`????????

ffffffff`8000079c  ????????`???????? ????????`????????

ffffffff`800007ac  ????????`???????? ????????`????????

ffffffff`800007bc  ????????`???????? ????????`????????

这说明不是采用堆栈传递参数。而是采用寄存器传递参数。ecx,edx

2: kd> dq ecx

fffff880`047d4820  00000000`00010100 00000000`000a0008

fffff880`047d4830  fffff880`03a7e670 00000000`00000000

fffff880`047d4840  fffff880`047d4800 fffff880`047d49c0

fffff880`047d4850  00000000`00000000 fffff800`0428c9c6

fffff880`047d4860  fffffa80`6192ac60 fffffa80`6192ac60

fffff880`047d4870  ffffffff`80000744 00000000`000007ff

fffff880`047d4880  fffff880`047d49c0 00000000`00000000

fffff880`047d4890  00000000`00000000 00000000`00000000

我们知道其参数第一参数arg0 是一个结构体, 这里面有我们需要的回调函数位置。

typedef struct _OB_CALLBACK_REGISTRATION {

USHORT                    Version;

USHORT                    OperationRegistrationCount;

UNICODE_STRING            Altitude;

PVOID                    RegistrationContext;

OB_OPERATION_REGISTRATION *OperationRegistration;    ///指向下面的结构

}

OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;

00000000`00010100 : 前面的00000000 是填充,用于结构体对齐。 后面的高位  0001  表示OperationRegistrationCount, 低位 0100 表示Version。

00000000`000a0008 : 前面的00000000 是填充,用于结构体对齐。 后面的高位  000a  表示unicode_string中的MaximumLength, 低位 0008 表示Length。

2: kd> dw fffff880`03a7e670  //这个里面存储的是unicode_string中的string。 目前存储的是“2111”

fffff880`03a7e670  0032 0031 0031 0031 0000 0000 0000 0000

fffff880`03a7e680  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e690  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e6a0  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e6b0  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e6c0  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e6d0  0000 0000 0000 0000 0000 0000 0000 0000

fffff880`03a7e6e0  0000 0000 0000 0000 0000 0000 0000 0000

字符串内容与源码对应:

.text:00000001400011BC                mov    [rsp+arg_0], rbx

.text:00000001400011C1                push    rbp

.text:00000001400011C2                mov    rbp, rsp

.text:00000001400011C5                sub    rsp, 70h

.text:00000001400011C9                mov    rax, [rcx+28h]

.text:00000001400011CD                xor    edx, edx

.text:00000001400011CF                lea    rcx, [rbp-30h]

.text:00000001400011D3                or      dword ptr [rax+68h], 20h

.text:00000001400011D7                lea    r8d, [rdx+28h]

.text:00000001400011DB                call    sub_1400010A0

.text:00000001400011E0                call    cs:ObGetFilterVersion

.text:00000001400011E6                and    qword ptr [rbp-18h], 0

.text:00000001400011EB                lea    rdx, SourceString ; "2111"              /////字符串

.text:00000001400011F2                lea    rcx, [rbp-28h]  ; DestinationString

.text:00000001400011F6                mov    ebx, 1

.text:00000001400011FB                mov    [rbp-30h], ax

.text:00000001400011FF                mov    [rbp-2Eh], bx

.text:0000000140001203                call    cs:RtlInitUnicodeString

00000000`00000000 对应着RegistrationContext

fffff880`047d4800 对应着OperationRegistration  指向下面的结构体:

typedef struct _OB_OPERATION_REGISTRATION {

POBJECT_TYPE                *ObjectType;

OB_OPERATION                Operations;

POB_PRE_OPERATION_CALLBACK  PreOperation;      ///指向回调函数。

POB_POST_OPERATION_CALLBACK PostOperation;

} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;

2: kd> dq fffff880`047d4800

fffff880`047d4800  fffff800`040cb020 00000000`00000001

fffff880`047d4810  fffff880`03a7e330 00000000`00000000

fffff880`047d4820  00000000`00010100 00000000`000a0008

fffff880`047d4830  fffff880`03a7e670 00000000`00000000

fffff880`047d4840  fffff880`047d4800 fffff880`047d49c0

fffff880`047d4850  00000000`00000000 fffff800`0428c9c6

fffff880`047d4860  fffffa80`6192ac60 fffffa80`6192ac60

fffff880`047d4870  ffffffff`80000744 00000000`000007ff

对照结构体,我们看到:

fffff800`040cb020 对应着 ObjectType

00000000`00000001 对应着 Operations    OB_OPERATION_HANDLE_CREATE

fffff880`03a7e330 对应着 PreOperation

00000000`00000000 对应着 PostOperation

2: kd> u fffff880`03a7e330

win7+0x1330:

fffff880`03a7e330 48895c2408      mov    qword ptr [rsp+8],rbx

fffff880`03a7e335 48896c2418      mov    qword ptr [rsp+18h],rbp

fffff880`03a7e33a 4889742420      mov    qword ptr [rsp+20h],rsi

fffff880`03a7e33f 57              push    rdi

fffff880`03a7e340 4883ec40        sub    rsp,40h

fffff880`03a7e344 488b05b51c0000  mov    rax,qword ptr [win7+0x3000 (fffff880`03a80000)]

fffff880`03a7e34b 4833c4          xor    rax,rsp

fffff880`03a7e34e 4889442430      mov    qword ptr [rsp+30h],rax

再看进程回调函数

.text:0000000140001330 PreProcessCall  proc near              ; DATA XREF: sub_140001190+A2�o

.text:0000000140001330                                        ; .pdata:0000000140004054�o

.text:0000000140001330

.text:0000000140001330 Str1            = byte ptr -28h

.text:0000000140001330 var_18          = qword ptr -18h

.text:0000000140001330 arg_0          = qword ptr  8

.text:0000000140001330 arg_10          = qword ptr  18h

.text:0000000140001330 arg_18          = qword ptr  20h

.text:0000000140001330

.text:0000000140001330                mov    [rsp+arg_0], rbx

.text:0000000140001335                mov    [rsp+arg_10], rbp

.text:000000014000133A                mov    [rsp+arg_18], rsi

.text:000000014000133F                push    rdi

.text:0000000140001340                sub    rsp, 40h

.text:0000000140001344                mov    rax, cs:__security_cookie

.text:000000014000134B                xor    rax, rsp

.text:000000014000134E                mov    [rsp+48h+var_18], rax

两者确认,完全一致。

你可能感兴趣的:(分析一个win64保护驱动)