逆向XignCode3驱动程序:识别驱动程序入口点(part1)
2020-11-05 12:20:00 Author: www.4hou.com(查看原文) 阅读量:215 收藏

导语:这是逆向XignCode3(XC3)Driver一系列文章中的第一篇,我在2019年初开始进行这项工作,逆向这种驱动程序不仅很有趣,而且还可以学习很多有关Windows Internals的知识。

这是逆向XignCode3(XC3)Driver一系列文章中的第一篇,我在2019年初开始进行这项工作,逆向这种驱动程序不仅很有趣,而且还可以学习很多有关Windows Internals的知识。我将尽可能地简短和准确记录下一些我认为是该驱动程序的有趣代码段或函数片段。

0x01  概述

1. 了解有关DriverEntry的信息

2. 在二进制驱动文件上识别此函数

3. 识别如何创建驱动程序对象

4. 分析已实现的主要函数,尤其是调度程序

5. 检测其他代码。

函数DriverEntry的代码片段:

 _int64 __fastcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 {
  PDRIVER_OBJECT _DriverObject; // rdi
  signed int ntStatus; // ebx
  UNICODE_STRING *v5; // rcx
  char Dest[16]; // [rsp+40h] [rbp-30h]
  UNICODE_STRING DeviceName; // [rsp+50h] [rbp-20h]
  UNICODE_STRING SymbolicLinkName; // [rsp+60h] [rbp-10h]
  PDEVICE_OBJECT DeviceObject; // [rsp+88h] [rbp+18h]
 
  _DriverObject = DriverObject;
  DeviceObject = 0i64;
  if (!RegistryPath->Length || fn_strcat(Dest, RegistryPath) < 0)
   return 0xC0000001i64;
  if (sub_140003A50(&SymbolicLinkName, Dest) < 0)
  {
   Real_Driver_Entry(Dest);
   return 0xC0000001i64;
  }
  if (sub_1400039B0(&DeviceName, Dest) >= 0)
  {
   _DriverObject->DriverUnload = fn_DriverUnloadDispatcher;
   _DriverObject->MajorFunction[0] = fn_DispatchCreate;// IRP_MJ_CREATE
   _DriverObject->MajorFunction[2] = fn_DispatchClose;// IRP_MJ_CLOSE                        
   _DriverObject->MajorFunction[4] = fn_DriverIOCTLDistpacher;// IRP_MJ_WRITE                        
   ntStatus = IoCreateDevice(_DriverObject, 0, &DeviceName, 0x22u, 0, 0, &DeviceObject);
   if (ntStatus < 0)
   {
    Real_Driver_Entry(Dest);
    Real_Driver_Entry(&DeviceName);
    goto LABEL_10;
   }
   DeviceObject->Flags |= 4u;
   _mm_storeu_si128(&xmmword_14000CD78, *Dest);
   _mm_storeu_si128(&::SymbolicLinkName, SymbolicLinkName);
   fn_InitDispatchMethodArray();
   ntStatus = fn_InitRegistrationNotifyAndCallbackRoutines();
   if (ntStatus >= 0)
   {
    ntStatus = fn_ObtainKernelFunctions();
    if (ntStatus >= 0)
    {
     ntStatus = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
     if (ntStatus >= 0)
     {
      ntStatus = 0;
      goto LABEL_18;
     }
     nullsub_1();
    }
    fn_RegisterCreateProcessNotifyRoutine();
    nullsub_1();
   }
   IoDeleteDevice(DeviceObject);
  LABEL_18:
   v5 = &DeviceName;
   goto LABEL_19;
  }
  Real_Driver_Entry(Dest);
  ntStatus = 0xC0000001;
 LABEL_10:
  v5 = &SymbolicLinkName;
 LABEL_19:
  Real_Driver_Entry(v5);
  return ntStatus;
 }

https://github.com/niemand-sec/Reversing-XignCode3-Driver/blob/master/XC3/DriverEntry_reversed.c

0x02  开始分析

获取.sys文件,这些是我使用的文件的哈希值:

· md5:C82DE0BC9A3A08E351B9BFA960F8757A

· sha1:F3AE1406B4CD7D1394DAC529C62BB01F3EB46D4A

· sha256:E7994B56152955835B5025049ABEE651E9C52A6CCAD7E04F2C458C8568967245

我逆向驱动程序时,我通常喜欢从DriverEntry开始。在此函数中,我可以找到一些有趣的细节,这些细节将有助于我识别驱动程序已实现的大多数函数。

IDA Pro和Ghidra通常能够自动检测到此函数,但是有时可能必须手动分析。

“ DriverEntry是驱动程序加载后第一个由驱动程序提供的例程。它负责初始化驱动程序。”

基本上,我需要寻找一个调用IoCreateDevice的函数,这通常在DriverEntry内部完成,并用于创建新的设备对象。这只是做到这一点的一种方法,但是由于IDA为我自动完成了这一步,因此直接进入逆向阶段。

0x03  DriverEntry(0x1400047B8)

下面是通过IDA Pro对DriverEntry进行反编译的代码:

https://github.com/niemand-sec/Reversing-XignCode3-Driver/blob/master/XC3/DriverEntry_original.c

 __int64 __fastcall DriverEntry(PDRIVER_OBJECT DriverObject, _WORD *a2)
 {
  PDRIVER_OBJECT v2; // rdi
  NTSTATUS v4; // ebx
  UNICODE_STRING *v5; // rcx
  __m128i v6; // [rsp+40h] [rbp-30h]
  UNICODE_STRING DeviceName; // [rsp+50h] [rbp-20h]
  UNICODE_STRING SymbolicLinkName; // [rsp+60h] [rbp-10h]
  PDEVICE_OBJECT DeviceObject; // [rsp+88h] [rbp+18h]
 
  v2 = DriverObject;
  DeviceObject = 0i64;
  if (!*a2 || (signed int)sub_140004A58(&v6) < 0)
   return 3221225473i64;
  if ((signed int)sub_140003A50(&SymbolicLinkName, &v6) < 0)
  {
   sub_140004AC0(&v6);
   return 3221225473i64;
  }
  if ((signed int)sub_1400039B0(&DeviceName, &v6) >= 0)
  {
   v2->DriverUnload = (PDRIVER_UNLOAD)sub_140004938;
   v2->MajorFunction[0] = (PDRIVER_DISPATCH)&sub_1400045D0;
   v2->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_140004580;
   v2->MajorFunction[4] = (PDRIVER_DISPATCH)&sub_140004604;
   v4 = IoCreateDevice(v2, 0, &DeviceName, 0x22u, 0, 0, &DeviceObject);
   if (v4 < 0)
   {
    sub_140004AC0(&v6);
    sub_140004AC0(&DeviceName);
    goto LABEL_10;
   }
   DeviceObject->Flags |= 4u;
   _mm_storeu_si128((__m128i *)&xmmword_14000CD78, v6);
   _mm_storeu_si128((__m128i *)&::SymbolicLinkName, (__m128i)SymbolicLinkName);
   sub_1400015F8();
   v4 = sub_140003550(v2);
   if (v4 >= 0)
   {
    v4 = sub_140002A18();
    if (v4 >= 0)
    {
     v4 = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
     if (v4 >= 0)
     {
      v4 = 0;
      goto LABEL_18;
     }
     nullsub_1();
    }
    sub_1400034D8();
    nullsub_1();
   }
   IoDeleteDevice(DeviceObject);
  LABEL_18:
   v5 = &DeviceName;
   goto LABEL_19;
  }
  sub_140004AC0(&v6);
  v4 = -1073741823;
 LABEL_10:
  v5 = &SymbolicLinkName;
 LABEL_19:
  sub_140004AC0(v5);
  return (unsigned int)v4;
 }

下面是对应的汇编代码:

https://github.com/niemand-sec/Reversing-XignCode3-Driver/blob/master/XC3/DriverEntry.asm

 .text:00000001400047B8 ; =============== S U B R O U T I N E =======================================
 .text:00000001400047B8
 .text:00000001400047B8 ; Attributes: bp-based frame
 .text:00000001400047B8
 .text:00000001400047B8 ; __int64 __fastcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 .text:00000001400047B8 DriverEntry     proc near               ; CODE XREF: start+25↓j
 .text:00000001400047B8                                         ; DATA XREF: .pdata:000000014000D3E4↓o ...
 .text:00000001400047B8
 .text:00000001400047B8 DeviceCharacteristics= dword ptr -50h
 .text:00000001400047B8 Exclusive       = byte ptr -48h
 .text:00000001400047B8 DeviceObject    = qword ptr -40h
 .text:00000001400047B8 var_30          = xmmword ptr -30h
 .text:00000001400047B8 DeviceName      = UNICODE_STRING ptr -20h
 .text:00000001400047B8 SymbolicLinkName= UNICODE_STRING ptr -10h
 .text:00000001400047B8 var_s0          = byte ptr  0
 .text:00000001400047B8 arg_0           = qword ptr  10h
 .text:00000001400047B8 arg_8           = qword ptr  18h
 .text:00000001400047B8 arg_10          = qword ptr  20h
 .text:00000001400047B8 arg_18          = qword ptr  28h
 .text:00000001400047B8
 .text:00000001400047B8                 mov     [rsp-8+arg_0], rbx
 .text:00000001400047BD                 mov     [rsp-8+arg_10], rsi
 .text:00000001400047C2                 mov     [rsp-8+arg_18], rdi
 .text:00000001400047C7                 push    rbp
 .text:00000001400047C8                 mov     rbp, rsp
 .text:00000001400047CB                 sub     rsp, 70h
 .text:00000001400047CF                 xor     esi, esi
 .text:00000001400047D1                 mov     rdi, rcx
 .text:00000001400047D4                 mov     [rbp+arg_8], rsi
 .text:00000001400047D8                 cmp     [rdx], si
 .text:00000001400047DB                 jnz     short loc_1400047E7
 .text:00000001400047DD
 .text:00000001400047DD loc_1400047DD:                          ; CODE XREF: DriverEntry+3A↓j
 .text:00000001400047DD                                         ; DriverEntry+56↓j
 .text:00000001400047DD                 mov     eax, 0C0000001h
 .text:00000001400047E2                 jmp     loc_140004922
 .text:00000001400047E7 ; ---------------------------------------------------------------------------
 .text:00000001400047E7
 .text:00000001400047E7 loc_1400047E7:                          ; CODE XREF: DriverEntry+23↑j
 .text:00000001400047E7                 lea     rcx, [rbp+var_30]
 .text:00000001400047EB                 call    sub_140004A58
 .text:00000001400047F0                 test    eax, eax
 .text:00000001400047F2                 js      short loc_1400047DD
 .text:00000001400047F4                 lea     rdx, [rbp+var_30]
 .text:00000001400047F8                 lea     rcx, [rbp+SymbolicLinkName]
 .text:00000001400047FC                 call    sub_140003A50
 .text:0000000140004801                 test    eax, eax
 .text:0000000140004803                 jns     short loc_140004810
 .text:0000000140004805                 lea     rcx, [rbp+var_30]
 .text:0000000140004809                 call    sub_140004AC0
 .text:000000014000480E                 jmp     short loc_1400047DD
 .text:0000000140004810 ; ---------------------------------------------------------------------------
 .text:0000000140004810
 .text:0000000140004810 loc_140004810:                          ; CODE XREF: DriverEntry+4B↑j
 .text:0000000140004810                 lea     rdx, [rbp+var_30]
 .text:0000000140004814                 lea     rcx, [rbp+DeviceName]
 .text:0000000140004818                 call    sub_1400039B0
 .text:000000014000481D                 test    eax, eax
 .text:000000014000481F                 jns     short loc_140004831
 .text:0000000140004821                 lea     rcx, [rbp+var_30]
 .text:0000000140004825                 call    sub_140004AC0
 .text:000000014000482A                 mov     ebx, 0C0000001h
 .text:000000014000482F                 jmp     short loc_1400048A2
 .text:0000000140004831 ; ---------------------------------------------------------------------------
 .text:0000000140004831
 .text:0000000140004831 loc_140004831:                          ; CODE XREF: DriverEntry+67↑j
 .text:0000000140004831                 lea     rax, sub_140004938
 .text:0000000140004838                 mov     r9d, 22h        ; DeviceType
 .text:000000014000483E                 mov     [rdi+68h], rax
 .text:0000000140004842                 lea     r8, [rbp+DeviceName] ; DeviceName
 .text:0000000140004846                 lea     rax, sub_1400045D0
 .text:000000014000484D                 xor     edx, edx        ; DeviceExtensionSize
 .text:000000014000484F                 mov     [rdi+70h], rax
 .text:0000000140004853                 mov     rcx, rdi        ; DriverObject
 .text:0000000140004856                 lea     rax, sub_140004580
 .text:000000014000485D                 mov     [rdi+80h], rax
 .text:0000000140004864                 lea     rax, sub_140004604
 .text:000000014000486B                 mov     [rdi+90h], rax
 .text:0000000140004872                 lea     rax, [rbp+arg_8]
 .text:0000000140004876                 mov     [rsp+70h+DeviceObject], rax ; DeviceObject
 .text:000000014000487B                 mov     [rsp+70h+Exclusive], sil ; Exclusive
 .text:0000000140004880                 mov     [rsp+70h+DeviceCharacteristics], esi ; DeviceCharacteristics
 .text:0000000140004884                 call    cs:IoCreateDevice
 .text:000000014000488A                 mov     ebx, eax
 .text:000000014000488C                 test    eax, eax
 .text:000000014000488E                 jns     short loc_1400048A8
 .text:0000000140004890                 lea     rcx, [rbp+var_30]
 .text:0000000140004894                 call    sub_140004AC0
 .text:0000000140004899                 lea     rcx, [rbp+DeviceName]
 .text:000000014000489D                 call    sub_140004AC0
 .text:00000001400048A2
 .text:00000001400048A2 loc_1400048A2:                          ; CODE XREF: DriverEntry+77↑j
 .text:00000001400048A2                 lea     rcx, [rbp+SymbolicLinkName]
 .text:00000001400048A6                 jmp     short loc_14000491B
 .text:00000001400048A8 ; ---------------------------------------------------------------------------
 .text:00000001400048A8
 .text:00000001400048A8 loc_1400048A8:                          ; CODE XREF: DriverEntry+D6↑j
 .text:00000001400048A8                 mov     rax, [rbp+arg_8]
 .text:00000001400048AC                 or      dword ptr [rax+30h], 4
 .text:00000001400048B0                 movups  xmm0, [rbp+var_30]
 .text:00000001400048B4                 movups  xmm1, xmmword ptr [rbp+SymbolicLinkName.Length]
 .text:00000001400048B8                 movdqu  cs:xmmword_14000CD78, xmm0
 .text:00000001400048C0                 movdqu  xmmword ptr cs:SymbolicLinkName.Length, xmm1
 .text:00000001400048C8                 call    sub_1400015F8
 .text:00000001400048CD                 mov     rcx, rdi
 .text:00000001400048D0                 call    sub_140003550
 .text:00000001400048D5                 mov     ebx, eax
 .text:00000001400048D7                 test    eax, eax
 .text:00000001400048D9                 js      short loc_140004909
 .text:00000001400048DB                 call    sub_140002A18
 .text:00000001400048E0                 mov     ebx, eax
 .text:00000001400048E2                 test    eax, eax
 .text:00000001400048E4                 js      short loc_1400048FF
 .text:00000001400048E6                 lea     rdx, [rbp+DeviceName] ; DeviceName
 .text:00000001400048EA                 lea     rcx, [rbp+SymbolicLinkName] ; SymbolicLinkName
 .text:00000001400048EE                 call    cs:IoCreateSymbolicLink
 .text:00000001400048F4                 mov     ebx, eax
 .text:00000001400048F6                 test    eax, eax
 .text:00000001400048F8                 jns     short loc_140004915
 .text:00000001400048FA                 call    nullsub_1
 .text:00000001400048FF
 .text:00000001400048FF loc_1400048FF:                          ; CODE XREF: DriverEntry+12C↑j
 .text:00000001400048FF                 call    sub_1400034D8
 .text:0000000140004904                 call    nullsub_1
 .text:0000000140004909
 .text:0000000140004909 loc_140004909:                          ; CODE XREF: DriverEntry+121↑j
 .text:0000000140004909                 mov     rcx, [rbp+arg_8] ; DeviceObject
 .text:000000014000490D                 call    cs:IoDeleteDevice
 .text:0000000140004913                 jmp     short loc_140004917
 .text:0000000140004915 ; ---------------------------------------------------------------------------
 .text:0000000140004915
 .text:0000000140004915 loc_140004915:                          ; CODE XREF: DriverEntry+140↑j
 .text:0000000140004915                 mov     ebx, esi
 .text:0000000140004917
 .text:0000000140004917 loc_140004917:                          ; CODE XREF: DriverEntry+15B↑j
 .text:0000000140004917                 lea     rcx, [rbp+DeviceName]
 .text:000000014000491B
 .text:000000014000491B loc_14000491B:                          ; CODE XREF: DriverEntry+EE↑j
 .text:000000014000491B                 call    sub_140004AC0
 .text:0000000140004920                 mov     eax, ebx
 .text:0000000140004922
 .text:0000000140004922 loc_140004922:                          ; CODE XREF: DriverEntry+2A↑j
 .text:0000000140004922                 lea     r11, [rsp+70h+var_s0]
 .text:0000000140004927                 mov     rbx, [r11+10h]
 .text:000000014000492B                 mov     rsi, [r11+20h]
 .text:000000014000492F                 mov     rdi, [r11+28h]
 .text:0000000140004933                 mov     rsp, r11
 .text:0000000140004936                 pop     rbp
 .text:0000000140004937                 retn
 .text:0000000140004937 DriverEntry     endp
 .text:0000000140004937

DriverEntry会接收两个参数:_DRIVER_OBJECT指针和带有注册表路径的PUNICODE_STRING。因此,我可以更改这两个变量的名称和类型。

需要考虑的是,默认情况下,IDA Pro上不提供逆向时需要的许多结构类型。因此,我可以通过以下方式将它们导入:“文件->加载文件->解析C头文件…”。

回到代码中,我对SymbolicLinkName和DeviceName进行了一些验证,没有发现什么有意思的地方,他们只是在设置所需的字符串:

 _DriverObject = DriverObject;
 DeviceObject = 0i64;
 if (!RegistryPath->Length || fn_strcat(Dest, RegistryPath) < 0)
  return 0xC0000001i64;
 if (sub_140003A50(&SymbolicLinkName, Dest) < 0)
 {
  Real_Driver_Entry(Dest);
  return 0xC0000001i64;
 }

DriverEntry需要进行一些特殊处理的解释在这里,看看他们在调用IoCreateDevice之前是如何做到的:

 _DriverObject->DriverUnload = fn_DriverUnloadDispatcher;
 _DriverObject->MajorFunction[0] = fn_DispatchCreate;// IRP_MJ_CREATE
 _DriverObject->MajorFunction[2] = fn_DispatchClose;// IRP_MJ_CLOSE                        
 _DriverObject->MajorFunction[4] = fn_DriverIOCTLDispatcher;// IRP_MJ_WRITE                        
 ntStatus = IoCreateDevice(_DriverObject, 0, &DeviceName, 0x22u, 0, 0, &DeviceObject);

我重命名了一些变量和函数来描述它们的主要作用,解释一下如何轻松识别它们:

在这里,我可以看到Windows上所有可用的IRP主要函数代码。在上一段代码中,仅实现了0、2和4:

· IRP_MJ_CREATE 0x00

· IRP_MJ_CLOSE 0x02

· IRP_MJ_WRITE 0x04

完整列表如下:

 /// IRP Major Codes
 
 #define IRP_MJ_CREATE 0x00
 #define IRP_MJ_CREATE_NAMED_PIPE 0x01
 #define IRP_MJ_CLOSE 0x02
 #define IRP_MJ_READ 0x03
 #define IRP_MJ_WRITE 0x04
 #define IRP_MJ_QUERY_INFORMATION 0x05
 #define IRP_MJ_SET_INFORMATION 0x06
 #define IRP_MJ_QUERY_EA 0x07
 #define IRP_MJ_SET_EA 0x08
 #define IRP_MJ_FLUSH_BUFFERS 0x09
 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
 #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
 #define IRP_MJ_DIRECTORY_CONTROL 0x0c
 #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
 #define IRP_MJ_DEVICE_CONTROL 0x0e
 #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
 #define IRP_MJ_SHUTDOWN 0x10
 #define IRP_MJ_LOCK_CONTROL 0x11
 #define IRP_MJ_CLEANUP 0x12
 #define IRP_MJ_CREATE_MAILSLOT 0x13
 #define IRP_MJ_QUERY_SECURITY 0x14
 #define IRP_MJ_SET_SECURITY 0x15
 #define IRP_MJ_POWER 0x16
 #define IRP_MJ_SYSTEM_CONTROL 0x17
 #define IRP_MJ_DEVICE_CHANGE 0x18
 #define IRP_MJ_QUERY_QUOTA 0x19
 #define IRP_MJ_SET_QUOTA 0x1a
 #define IRP_MJ_PNP 0x1b
 #define IRP_MJ_MAXIMUM_FUNCTION 0x1b

IRP_MJ_CREATE和IRP_MJ_CLOSE只是通用函数,有趣的是IRP_MJ_WRITE将处理来自用户模式的请求,并在fn_DriverIOCTLDispatcher上实现。我将在另一篇文章中解释此函数如何工作以及如何分派每个IRP请求。

现在,我只专注于分析DriverEntry调用的函数。

在对所调用函数的内部行为进行一些分析之后,可以看到以下代码:

 fn_InitDispatchMethodArray();
 ntStatus = fn_InitRegistrationNotifyAndCallbackRoutines();
 if (ntStatus >= 0)
 {
  ntStatus = fn_ObtainKernelFunctions();
  if (ntStatus >= 0)
  {
   ntStatus = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
   if (ntStatus >= 0)
   {
    ntStatus = 0;
    goto LABEL_18;
   }
   nullsub_1();
  }
  fn_RegisterCreateProcessNotifyRoutine();
  nullsub_1();
 }

一些有趣的函数名字:

· fn_InitDispatchMethodArray

· fn_InitRegistrationNotifyAndCallbackRoutines

· fn_ObtainKernelFunctions

· fn_RegisterCreateProcessNotifyRoutine

这些名称是否正确,取决于我稍后在逆向过程中发现的内容。正如我提到的,大部分工作是在几个月前完成的,有时,逆向需要做很多猜测,因此我需要开始想象每个函数可能会做什么,并给它们命名,以便我可以描绘出每个函数的作用。

该名称基于我对这些函数的推断。我将在后面的文章中深入了解它们。

我可以根据它们的作用将它们基本上分为两组。注册某种回调的函数;fn_InitRegistrationNotifyAndCallbackRoutines和fn_RegisterCreateProcessNotifyRoutine。并具有驱动程序运行所需的基本信息的函数;fn_InitDispatchMethodArray和fn_ObtainKernelFunctions。

本文翻译自:https://niemand.com.ar/2020/01/08/reversing-xigncode3-driver-part-1-identifying-the-driver-entry-point/如若转载,请注明原文地址:


文章来源: https://www.4hou.com/posts/v9nX
如有侵权请联系:admin#unsafe.sh