逆向XignCode3驱动程序:分析init初始化函数(part2)

admin 2020年11月15日12:05:50评论155 views字数 13715阅读45分43秒阅读模式

逆向XignCode3驱动程序:分析init初始化函数(part2)

逆向XignCode3驱动程序:分析init初始化函数(part2)

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

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

逆向XignCode3驱动程序:分析init初始化函数(part2)
0x01  概述

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

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

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

逆向XignCode3驱动程序:分析init初始化函数(part2)
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上如何使用此变量,基于此函数,可以确定驱动程序没有调用所有可用方法的列表,并提供某种索引值,可以调用它们。

逆向XignCode3驱动程序:分析init初始化函数(part2)

最终整理的代码片段:

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;

 }

逆向XignCode3驱动程序:分析init初始化函数(part2)
0x03  fn_ObtainKernelFunctions(0x140002A18)

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

逆向XignCode3驱动程序:分析init初始化函数(part2)

这样做可以确保这些函数在运行的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/

逆向XignCode3驱动程序:分析init初始化函数(part2)

逆向XignCode3驱动程序:分析init初始化函数(part2)

本文始发于微信公众号(嘶吼专业版):逆向XignCode3驱动程序:分析init初始化函数(part2)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年11月15日12:05:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   逆向XignCode3驱动程序:分析init初始化函数(part2)http://cn-sec.com/archives/184166.html

发表评论

匿名网友 填写信息