逆向XignCode3驱动程序:分析init初始化函数(part2)
2020-11-13 10:42:50 Author: www.4hou.com(查看原文) 阅读量:265 收藏

导语:在第1部分中,我确定了驱动程序的Dispatcher函数以及两个正在初始化驱动程序的某些变量的函数(**fn_InitDispatchMethodArray**和**fn_ObtainKernelFunctions**)。 逆向这两个函数,分析一下它们的功能,这会帮助我了解在此驱动程序上实现的Dispatcher函数。

image.png

第1部分中,我确定了驱动程序的Dispatcher函数以及两个正在初始化驱动程序的某些变量的函数(fn_InitDispatchMethodArray和fn_ObtainKernelFunctions)。

逆向这两个函数,分析一下它们的功能,这会帮助我了解在此驱动程序上实现的Dispatcher函数。

0x01  概述

1. 该驱动程序的一些基本初始化机制

2. 确定用于索引和存储所有可用方法的自定义结构。

3. 确定函数地址在内存中的位置,例如ObRegisterCallbacks。

0x02  fn_InitDispatchMethodArray(0x1400015F8)

该函数的代码片段:

 __int64 sub_1400015F8()
 {
  __int64 result; // rax
 
  memset(&dword_140009E40, 0, 0x400ui64);
  dword_140009E40 = 774;
  qword_140009E48 = (__int64)sub_140001058;
  qword_140009E58 = (__int64)sub_14000101C;
  qword_140009E68 = (__int64)sub_140001CC8;
  qword_140009E78 = (__int64)sub_140001BFC;
  qword_140009E88 = (__int64)sub_140001DC0;
  qword_140009E98 = (__int64)sub_140001B50;
  qword_140009EA8 = (__int64)sub_140001C3C;
  qword_140009EB8 = (__int64)sub_140001D04;
  qword_140009EC8 = (__int64)sub_14000137C;
  qword_140009ED8 = (__int64)sub_14000191C;
  qword_140009EE8 = (__int64)sub_140001340;
  qword_140009EF8 = (__int64)sub_140001A58;
  qword_140009F08 = (__int64)sub_1400019A4;
  qword_140009F18 = (__int64)sub_140001224;
  qword_140009F28 = (__int64)sub_14000187C;
  qword_140009F38 = (__int64)sub_140001488;
  qword_140009F48 = (__int64)sub_140001548;
  qword_140009F58 = (__int64)sub_1400013B8;
  qword_140009F68 = (__int64)sub_140001264;
  qword_140009F78 = (__int64)sub_14000150C;
  qword_140009F88 = (__int64)sub_140001174;
  qword_140009F98 = (__int64)sub_1400015CC;
  qword_140009FA8 = (__int64)sub_14000107C;
  qword_140009FB8 = (__int64)sub_140001D4C;
  qword_140009FC8 = (__int64)sub_140001D88;
  result = 0i64;
  dword_140009E50 = 775;
  dword_140009E60 = 776;
  dword_140009E70 = 777;
  dword_140009E80 = 778;
  dword_140009E90 = 779;
  dword_140009EA0 = 790;
  dword_140009EB0 = 782;
  dword_140009EC0 = 783;
  dword_140009ED0 = 785;
  dword_140009EE0 = 786;
  dword_140009EF0 = 787;
  dword_140009F00 = 788;
  dword_140009F10 = 789;
  dword_140009F20 = 791;
  dword_140009F30 = 792;
  dword_140009F40 = 793;
  dword_140009F50 = 794;
  dword_140009F60 = 796;
  dword_140009F70 = 797;
  dword_140009F80 = 798;
  dword_140009F90 = 799;
  dword_140009FA0 = 800;
  dword_140009FB0 = 801;
  dword_140009FC0 = 802;
  dword_14000A240 = 25;
  return result;
 }

汇编代码段:

 .text:00000001400015F8 ; =============== S U B R O U T I N E =======================================
 .text:00000001400015F8
 .text:00000001400015F8
 .text:00000001400015F8 sub_1400015F8   proc near               ; CODE XREF: DriverEntry+110↓p
 .text:00000001400015F8                                         ; DATA XREF: .pdata:000000014000D084↓o
 .text:00000001400015F8                 sub     rsp, 28h
 .text:00000001400015FC                 xor     edx, edx        ; Val
 .text:00000001400015FE                 lea     rcx, dword_140009E40 ; Dst
 .text:0000000140001605                 mov     r8d, 400h       ; Size
 .text:000000014000160B                 call    memset
 .text:0000000140001610                 lea     rax, sub_140001058
 .text:0000000140001617                 mov     cs:dword_140009E40, 306h
 .text:0000000140001621                 mov     cs:qword_140009E48, rax
 .text:0000000140001628                 lea     rax, sub_14000101C
 .text:000000014000162F                 mov     cs:qword_140009E58, rax
 .text:0000000140001636                 lea     rax, sub_140001CC8
 .text:000000014000163D                 mov     cs:qword_140009E68, rax
 .text:0000000140001644                 lea     rax, sub_140001BFC
 .text:000000014000164B                 mov     cs:qword_140009E78, rax
 .text:0000000140001652                 lea     rax, sub_140001DC0
 .text:0000000140001659                 mov     cs:qword_140009E88, rax
 .text:0000000140001660                 lea     rax, sub_140001B50
 .text:0000000140001667                 mov     cs:qword_140009E98, rax
 .text:000000014000166E                 lea     rax, sub_140001C3C
 .text:0000000140001675                 mov     cs:qword_140009EA8, rax
 .text:000000014000167C                 lea     rax, sub_140001D04
 .text:0000000140001683                 mov     cs:qword_140009EB8, rax
 .text:000000014000168A                 lea     rax, sub_14000137C
 .text:0000000140001691                 mov     cs:qword_140009EC8, rax
 .text:0000000140001698                 lea     rax, sub_14000191C
 .text:000000014000169F                 mov     cs:qword_140009ED8, rax
 .text:00000001400016A6                 lea     rax, sub_140001340
 .text:00000001400016AD                 mov     cs:qword_140009EE8, rax
 .text:00000001400016B4                 lea     rax, sub_140001A58
 .text:00000001400016BB                 mov     cs:qword_140009EF8, rax
 .text:00000001400016C2                 lea     rax, sub_1400019A4
 .text:00000001400016C9                 mov     cs:qword_140009F08, rax
 .text:00000001400016D0                 lea     rax, sub_140001224
 .text:00000001400016D7                 mov     cs:qword_140009F18, rax
 .text:00000001400016DE                 lea     rax, sub_14000187C
 .text:00000001400016E5                 mov     cs:qword_140009F28, rax
 .text:00000001400016EC                 lea     rax, sub_140001488
 .text:00000001400016F3                 mov     cs:qword_140009F38, rax
 .text:00000001400016FA                 lea     rax, sub_140001548
 .text:0000000140001701                 mov     cs:qword_140009F48, rax
 .text:0000000140001708                 lea     rax, sub_1400013B8
 .text:000000014000170F                 mov     cs:qword_140009F58, rax
 .text:0000000140001716                 lea     rax, sub_140001264
 .text:000000014000171D                 mov     cs:qword_140009F68, rax
 .text:0000000140001724                 lea     rax, sub_14000150C
 .text:000000014000172B                 mov     cs:qword_140009F78, rax
 .text:0000000140001732                 lea     rax, sub_140001174
 .text:0000000140001739                 mov     cs:qword_140009F88, rax
 .text:0000000140001740                 lea     rax, sub_1400015CC
 .text:0000000140001747                 mov     cs:qword_140009F98, rax
 .text:000000014000174E                 lea     rax, sub_14000107C
 .text:0000000140001755                 mov     cs:qword_140009FA8, rax
 .text:000000014000175C                 lea     rax, sub_140001D4C
 .text:0000000140001763                 mov     cs:qword_140009FB8, rax
 .text:000000014000176A                 lea     rax, sub_140001D88
 .text:0000000140001771                 mov     cs:qword_140009FC8, rax
 .text:0000000140001778                 xor     eax, eax
 .text:000000014000177A                 mov     cs:dword_140009E50, 307h
 .text:0000000140001784                 mov     cs:dword_140009E60, 308h
 .text:000000014000178E                 mov     cs:dword_140009E70, 309h
 .text:0000000140001798                 mov     cs:dword_140009E80, 30Ah
 .text:00000001400017A2                 mov     cs:dword_140009E90, 30Bh
 .text:00000001400017AC                 mov     cs:dword_140009EA0, 316h
 .text:00000001400017B6                 mov     cs:dword_140009EB0, 30Eh
 .text:00000001400017C0                 mov     cs:dword_140009EC0, 30Fh
 .text:00000001400017CA                 mov     cs:dword_140009ED0, 311h
 .text:00000001400017D4                 mov     cs:dword_140009EE0, 312h
 .text:00000001400017DE                 mov     cs:dword_140009EF0, 313h
 .text:00000001400017E8                 mov     cs:dword_140009F00, 314h
 .text:00000001400017F2                 mov     cs:dword_140009F10, 315h
 .text:00000001400017FC                 mov     cs:dword_140009F20, 317h
 .text:0000000140001806                 mov     cs:dword_140009F30, 318h
 .text:0000000140001810                 mov     cs:dword_140009F40, 319h
 .text:000000014000181A                 mov     cs:dword_140009F50, 31Ah
 .text:0000000140001824                 mov     cs:dword_140009F60, 31Ch
 .text:000000014000182E                 mov     cs:dword_140009F70, 31Dh
 .text:0000000140001838                 mov     cs:dword_140009F80, 31Eh
 .text:0000000140001842                 mov     cs:dword_140009F90, 31Fh
 .text:000000014000184C                 mov     cs:dword_140009FA0, 320h
 .text:0000000140001856                 mov     cs:dword_140009FB0, 321h
 .text:0000000140001860                 mov     cs:dword_140009FC0, 322h
 .text:000000014000186A                 mov     cs:dword_14000A240, 19h
 .text:0000000140001874                 add     rsp, 28h
 .text:0000000140001878                 retn
 .text:0000000140001878 sub_1400015F8   endp
 .text:0000000140001878

还原后的代码:

 __int64 fn_InitDispatchMethodArray()
 {
  __int64 result; // rax
 
  memset(IOCTLFunctionArray, 0, 0x400ui64);
  IOCTLFunctionArray[0].Index = 774;            // 9E40
  IOCTLFunctionArray[0].FnPtr = sub_140001058;
  IOCTLFunctionArray[1].FnPtr = sub_14000101C;
  IOCTLFunctionArray[2].FnPtr = sub_140001CC8;
  IOCTLFunctionArray[3].FnPtr = sub_140001BFC;
  IOCTLFunctionArray[4].FnPtr = sub_140001DC0;
  IOCTLFunctionArray[5].FnPtr = sub_140001B50;
  IOCTLFunctionArray[6].FnPtr = sub_140001C3C;
  IOCTLFunctionArray[7].FnPtr = sub_140001D04;
  IOCTLFunctionArray[8].FnPtr = sub_14000137C;
  IOCTLFunctionArray[9].FnPtr = sub_14000191C;
  IOCTLFunctionArray[10].FnPtr = sub_140001340;
  IOCTLFunctionArray[11].FnPtr = sub_140001A58;
  IOCTLFunctionArray[12].FnPtr = sub_1400019A4;
  IOCTLFunctionArray[13].FnPtr = sub_140001224;
  IOCTLFunctionArray[14].FnPtr = sub_14000187C;
  IOCTLFunctionArray[15].FnPtr = sub_140001488;
  IOCTLFunctionArray[16].FnPtr = sub_140001548;
  IOCTLFunctionArray[17].FnPtr = sub_1400013B8;
  IOCTLFunctionArray[18].FnPtr = fn_ReadFileContent_;
  IOCTLFunctionArray[19].FnPtr = fn_IOCTL_ValidatePidPEB;
  IOCTLFunctionArray[20].FnPtr = fn_IOCTL_ControlCallbackRoutines;
  IOCTLFunctionArray[21].FnPtr = sub_1400015CC;
  IOCTLFunctionArray[22].FnPtr = sub_14000107C;
  IOCTLFunctionArray[23].FnPtr = sub_140001D4C; // CR0
  IOCTLFunctionArray[24].FnPtr = sub_140001D88;
  result = 0i64;
  IOCTLFunctionArray[1].Index = 775;
  IOCTLFunctionArray[2].Index = 776;
  IOCTLFunctionArray[3].Index = 777;
  IOCTLFunctionArray[4].Index = 778;
  IOCTLFunctionArray[5].Index = 779;
  IOCTLFunctionArray[6].Index = 790;
  IOCTLFunctionArray[7].Index = 782;
  IOCTLFunctionArray[8].Index = 783;
  IOCTLFunctionArray[9].Index = 785;
  IOCTLFunctionArray[10].Index = 786;
  IOCTLFunctionArray[11].Index = 787;
  IOCTLFunctionArray[12].Index = 788;
  IOCTLFunctionArray[13].Index = 789;
  IOCTLFunctionArray[14].Index = 791;
  IOCTLFunctionArray[15].Index = 792;
  IOCTLFunctionArray[16].Index = 793;
  IOCTLFunctionArray[17].Index = 794;
  IOCTLFunctionArray[18].Index = 796;
  IOCTLFunctionArray[19].Index = 797;
  IOCTLFunctionArray[20].Index = 798;
  IOCTLFunctionArray[21].Index = 799;
  IOCTLFunctionArray[22].Index = 800;
  IOCTLFunctionArray[23].Index = 801;
  IOCTLFunctionArray[24].Index = 802;
  FunctionsCount = 0x19;
  return result;
 }

可以在此函数中看到正在初始化的自定义结构:

 .text:0000000140001617                 mov     cs:dword_140009E40, 306h
 .text:0000000140001621                 mov     cs:qword_140009E48, rax
 .text:0000000140001628                 lea     rax, sub_14000101C
 .text:000000014000162F                 mov     cs:qword_140009E58, rax
 .text:0000000140001636                 lea     rax, sub_140001CC8
 .text:000000014000163D                 mov     cs:qword_140009E68, rax

上面的汇编代码中,可以看到它们首先将int值分配给特定的内存地址,然后再移动8个字节将指针写入函数,我将这种结构称为IOCTLFunctionArray,该数组将在调度请求时发挥重要作用。

结构如下所示:

 typedef struct DispatcherStruct  {
     int Index;
     char padding[4];
     PVOID FnPtr;
 };

在IDA Pro中:

 00000000 DispatcherStruct struc ; (sizeof=0x10, mappedto_424)
 00000000                                         ; XREF: .data:_IOCTLFunctionArray/r
 00000000 Index           dd ?                    ; XREF: fn_InitDispatchMethodArray+1F/t
 00000004 padding         db 4 dup(?)
 00000008 FnPtr           dq ?
 00000010 DispatcherStruct ends

此函数重复了25次,所以称其为array,它们在数组中存储相同结构25次。

将dword_14000A240重命名为FunctionsCount的变量:

 .text:000000014000186A                 mov     cs:FunctionsCount , 19h

之后将看到在Dispatcher上如何使用此变量,基于此函数,可以确定驱动程序没有调用所有可用方法的列表,并提供某种索引值,可以调用它们。

image.png

最终整理的代码片段:

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

 __int64 fn_InitDispatchMethodArray()
 {
  __int64 result; // rax
 
  memset(IOCTLFunctionArray, 0, 0x400ui64);
  IOCTLFunctionArray[0].Index = 774;            // 9E40
  IOCTLFunctionArray[0].FnPtr = sub_140001058;
  IOCTLFunctionArray[1].FnPtr = sub_14000101C;
  IOCTLFunctionArray[2].FnPtr = sub_140001CC8;
  IOCTLFunctionArray[3].FnPtr = sub_140001BFC;
  IOCTLFunctionArray[4].FnPtr = sub_140001DC0;
  IOCTLFunctionArray[5].FnPtr = sub_140001B50;
  IOCTLFunctionArray[6].FnPtr = sub_140001C3C;
  IOCTLFunctionArray[7].FnPtr = sub_140001D04;
  IOCTLFunctionArray[8].FnPtr = sub_14000137C;
  IOCTLFunctionArray[9].FnPtr = sub_14000191C;
  IOCTLFunctionArray[10].FnPtr = sub_140001340;
  IOCTLFunctionArray[11].FnPtr = sub_140001A58;
  IOCTLFunctionArray[12].FnPtr = sub_1400019A4;
  IOCTLFunctionArray[13].FnPtr = sub_140001224;
  IOCTLFunctionArray[14].FnPtr = sub_14000187C;
  IOCTLFunctionArray[15].FnPtr = sub_140001488;
  IOCTLFunctionArray[16].FnPtr = sub_140001548;
  IOCTLFunctionArray[17].FnPtr = sub_1400013B8;
  IOCTLFunctionArray[18].FnPtr = fn_ReadFileContent_;
  IOCTLFunctionArray[19].FnPtr = fn_IOCTL_ValidatePidPEB;
  IOCTLFunctionArray[20].FnPtr = fn_IOCTL_ControlCallbackRoutines;
  IOCTLFunctionArray[21].FnPtr = sub_1400015CC;
  IOCTLFunctionArray[22].FnPtr = sub_14000107C;
  IOCTLFunctionArray[23].FnPtr = sub_140001D4C; // CR0
  IOCTLFunctionArray[24].FnPtr = sub_140001D88;
  result = 0i64;
  IOCTLFunctionArray[1].Index = 775;
  IOCTLFunctionArray[2].Index = 776;
  IOCTLFunctionArray[3].Index = 777;
  IOCTLFunctionArray[4].Index = 778;
  IOCTLFunctionArray[5].Index = 779;
  IOCTLFunctionArray[6].Index = 790;
  IOCTLFunctionArray[7].Index = 782;
  IOCTLFunctionArray[8].Index = 783;
  IOCTLFunctionArray[9].Index = 785;
  IOCTLFunctionArray[10].Index = 786;
  IOCTLFunctionArray[11].Index = 787;
  IOCTLFunctionArray[12].Index = 788;
  IOCTLFunctionArray[13].Index = 789;
  IOCTLFunctionArray[14].Index = 791;
  IOCTLFunctionArray[15].Index = 792;
  IOCTLFunctionArray[16].Index = 793;
  IOCTLFunctionArray[17].Index = 794;
  IOCTLFunctionArray[18].Index = 796;
  IOCTLFunctionArray[19].Index = 797;
  IOCTLFunctionArray[20].Index = 798;
  IOCTLFunctionArray[21].Index = 799;
  IOCTLFunctionArray[22].Index = 800;
  IOCTLFunctionArray[23].Index = 801;
  IOCTLFunctionArray[24].Index = 802;
  FunctionsCount = 0x19;
  return result;
 }

0x03  fn_ObtainKernelFunctions(0x140002A18)

下面的函数很简单,为了继续进行初始化,驱动程序需要一些特定例程的地址:

image.png

这样做可以确保这些函数在运行的Windows版本上可用,并获得指向它们的指针,只需要将它们存储在一个变量中,然后通过将其转换为属性函数定义来使用它们来调用这些例程。

也可以在汇编函数中发现:

 .text:0000000140002A1C                 lea     rdx, SourceString ; "ObGetFilterVersion"
 .text:0000000140002A23                 lea     rcx, [rsp+38h+DestinationString] ; DestinationString
 .text:0000000140002A28                 call    cs:RtlInitUnicodeString
 .text:0000000140002A2E                 lea     rcx, [rsp+38h+DestinationString] ; SystemRoutineName
 .text:0000000140002A33                 call    cs:MmGetSystemRoutineAddress
 .text:0000000140002A39                 lea     rdx, aObregistercall ; "ObRegisterCallbacks"
 .text:0000000140002A40                 mov     cs:qword_14000A288, rax
 .text:0000000140002A47                 lea     rcx, [rsp+38h+DestinationString] ; DestinationString
 .text:0000000140002A4C                 call    cs:RtlInitUnicodeString
 .text:0000000140002A52                 lea     rcx, [rsp+38h+DestinationString] ; SystemRoutineName
 .text:0000000140002A57                 call    cs:MmGetSystemRoutineAddress

本文翻译自:https://niemand.com.ar/2020/01/16/reversing-xigncode3-driver-part-2-analyzing-init-functions/如若转载,请注明原文地址:


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