逆向XignCode3驱动程序:分析Dispatcher函数(part3)

系统
Dispatcher函数的主要功能是处理I / O请求数据包(IRP),处理来自主要函数代码IRP_MJ_WRITE的任何请求。

逆向XignCode3驱动程序:识别驱动程序入口点(part1)

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

Dispatcher函数的主要功能是处理I / O请求数据包(IRP),处理来自主要函数代码IRP_MJ_WRITE的任何请求。

0x01 概述

1. 了解分派器例程的实现方式。

2. 逆向处理IRP_MJ_WRITE请求的解析方法。

3. 确定驱动程序使用的自定义结构,并在IDA上创建新的本地类型。

4. 通过遍历具有自定义结构的数组,了解驱动程序如何调度不同的硬编码句柄。

逆向Windows相关内容时,必须阅读MS文档。它们提供了许多有用的信息,这些信息会节省很多时间,例如它们使用的结构,参数和代码示例,我会浏览其存储库中可用的示例,并查找相似的代码段。驱动程序开发人员通常会重复使用这些示例中的许多代码,在二进制文件中寻找相似的模式可以为我提供有关上下文和在相似代码段内被调用的函数的大量信息。

在本文的结尾,你将找到有用的链接列表。

0x02 fn_DriverIOCTLDispatcher(0x140004604)

一个驱动程序可以提供多个调度例程,在这种情况下只有一个主要函数。

初始化代码段:

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

  1. __int64 __fastcall sub_140004604(__int64 a1, _IRP *a2) 
  2.  _IRP *v2; // rbx 
  3.  unsigned int v3; // esi 
  4.  unsigned int v4; // edi 
  5.  _IRP *v5; // r14 
  6.  __int64 v6; // rax 
  7.  void *v7; // r8 
  8.  __int64 v8; // rcx 
  9.  __int64 *v9; // rdx 
  10.  signed __int64 v10; // rax 
  11.  PMDL MemoryDescriptorList; // [rsp+38h] [rbp-320h] 
  12.  __int64 v13; // [rsp+40h] [rbp-318h] 
  13.  
  14.  v2 = a2; 
  15.  v3 = 0; 
  16.  v4 = -1073741823; 
  17.  if (LODWORD(a2->Tail.Overlay.CurrentStackLocation->Parameters.Others.Argument1) == 0x270) 
  18.  { 
  19.   v5 = a2->AssociatedIrp.MasterIrp; 
  20.   if (*&v5->Type == 0x270 && *(&v5->Size + 1) == 0x345821AB) 
  21.   { 
  22.    fn_DispatchIOCTLMethod(v5, &v13); 
  23.    v6 = sub_140003DBC(*&v5->Flags, 762i64, &MemoryDescriptorList); 
  24.    v7 = v6; 
  25.    if (v6) 
  26.    { 
  27.     v8 = v6; 
  28.     v9 = &v13; 
  29.     v10 = 5i64; 
  30.     do 
  31.     { 
  32.      *v8 = *v9; 
  33.      *(v8 + 16) = *(v9 + 1); 
  34.      *(v8 + 32) = *(v9 + 2); 
  35.      *(v8 + 48) = *(v9 + 3); 
  36.      *(v8 + 64) = *(v9 + 4); 
  37.      *(v8 + 80) = *(v9 + 5); 
  38.      *(v8 + 96) = *(v9 + 6); 
  39.      v8 += 128i64; 
  40.      *(v8 - 16) = *(v9 + 7); 
  41.      v9 += 16; 
  42.      --v10; 
  43.     } while (v10); 
  44.     *v8 = *v9; 
  45.     *(v8 + 16) = *(v9 + 1); 
  46.     *(v8 + 32) = *(v9 + 2); 
  47.     *(v8 + 48) = *(v9 + 3); 
  48.     *(v8 + 64) = *(v9 + 4); 
  49.     *(v8 + 80) = *(v9 + 5); 
  50.     *(v8 + 96) = *(v9 + 6); 
  51.     *(v8 + 112) = v9[14]; 
  52.     *(v8 + 120) = *(v9 + 60); 
  53.     v4 = 0; 
  54.     v3 = 762; 
  55.     sub_140003980(MemoryDescriptorList, v7); 
  56.    } 
  57.   } 
  58.  } 
  59.  v2->IoStatus.Status = v4; 
  60.  v2->IoStatus.Information = v3; 
  61.  IofCompleteRequest(v2, 0); 
  62.  return v4; 

 IDA中的代码段:

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

  1. __int64 __fastcall sub_140004604(__int64 a1, _IRP *a2) 
  2.  _IRP *v2; // rbx 
  3.  unsigned int v3; // esi 
  4.  unsigned int v4; // edi 
  5.  _IRP *v5; // r14 
  6.  __int64 v6; // rax 
  7.  void *v7; // r8 
  8.  __int64 v8; // rcx 
  9.  __int64 *v9; // rdx 
  10.  signed __int64 v10; // rax 
  11.  PMDL MemoryDescriptorList; // [rsp+38h] [rbp-320h] 
  12.  __int64 v13; // [rsp+40h] [rbp-318h] 
  13.  
  14.  v2 = a2; 
  15.  v3 = 0; 
  16.  v4 = -1073741823; 
  17.  if (LODWORD(a2->Tail.Overlay.CurrentStackLocation->Parameters.Others.Argument1) == 0x270) 
  18.  { 
  19.   v5 = a2->AssociatedIrp.MasterIrp; 
  20.   if (*&v5->Type == 0x270 && *(&v5->Size + 1) == 0x345821AB) 
  21.   { 
  22.    fn_DispatchIOCTLMethod(v5, &v13); 
  23.    v6 = sub_140003DBC(*&v5->Flags, 762i64, &MemoryDescriptorList); 
  24.    v7 = v6; 
  25.    if (v6) 
  26.    { 
  27.     v8 = v6; 
  28.     v9 = &v13; 
  29.     v10 = 5i64; 
  30.     do 
  31.     { 
  32.      *v8 = *v9; 
  33.      *(v8 + 16) = *(v9 + 1); 
  34.      *(v8 + 32) = *(v9 + 2); 
  35.      *(v8 + 48) = *(v9 + 3); 
  36.      *(v8 + 64) = *(v9 + 4); 
  37.      *(v8 + 80) = *(v9 + 5); 
  38.      *(v8 + 96) = *(v9 + 6); 
  39.      v8 += 128i64; 
  40.      *(v8 - 16) = *(v9 + 7); 
  41.      v9 += 16; 
  42.      --v10; 
  43.     } while (v10); 
  44.     *v8 = *v9; 
  45.     *(v8 + 16) = *(v9 + 1); 
  46.     *(v8 + 32) = *(v9 + 2); 
  47.     *(v8 + 48) = *(v9 + 3); 
  48.     *(v8 + 64) = *(v9 + 4); 
  49.     *(v8 + 80) = *(v9 + 5); 
  50.     *(v8 + 96) = *(v9 + 6); 
  51.     *(v8 + 112) = v9[14]; 
  52.     *(v8 + 120) = *(v9 + 60); 
  53.     v4 = 0; 
  54.     v3 = 762; 
  55.     sub_140003980(MemoryDescriptorList, v7); 
  56.    } 
  57.   } 
  58.  } 
  59.  v2->IoStatus.Status = v4; 
  60.  v2->IoStatus.Information = v3; 
  61.  IofCompleteRequest(v2, 0); 
  62.  return v4; 

 汇编代码段:

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

  1. .text:0000000140004604 ; =============== S U B R O U T I N E ======================================= 
  2. .text:0000000140004604 
  3. .text:0000000140004604 
  4. .text:0000000140004604 sub_140004604   proc near               ; DATA XREF: DriverEntry+AC↓o 
  5. .text:0000000140004604                                         ; .pdata:000000014000D3D8↓o ... 
  6. .text:0000000140004604 
  7. .text:0000000140004604 var_338         = dword ptr -338h 
  8. .text:0000000140004604 var_334         = dword ptr -334h 
  9. .text:0000000140004604 var_330         = qword ptr -330h 
  10. .text:0000000140004604 var_328         = qword ptr -328h 
  11. .text:0000000140004604 MemoryDescriptorList= qword ptr -320h 
  12. .text:0000000140004604 v13             = qword ptr -318h 
  13. .text:0000000140004604 var_18          = qword ptr -18h 
  14. .text:0000000140004604 var_8           = byte ptr -8 
  15. .text:0000000140004604 arg_0           = qword ptr  8 
  16. .text:0000000140004604 arg_10          = qword ptr  18h 
  17. .text:0000000140004604 arg_18          = qword ptr  20h 
  18. .text:0000000140004604 
  19. .text:0000000140004604 ; __unwind { // __GSHandlerCheck_SEH 
  20. .text:0000000140004604                 mov     [rsp+arg_0], rbx 
  21. .text:0000000140004609                 mov     [rsp+arg_10], rsi 
  22. .text:000000014000460E                 mov     [rsp+arg_18], rdi 
  23. .text:0000000140004613                 push    r14 
  24. .text:0000000140004615                 sub     rsp, 350h 
  25. .text:000000014000461C                 mov     rax, cs:__security_cookie 
  26. .text:0000000140004623                 xor     rax, rsp 
  27. .text:0000000140004626                 mov     [rsp+358h+var_18], rax 
  28. .text:000000014000462E                 mov     rbx, rdx 
  29. .text:0000000140004631                 mov     [rsp+358h+var_328], rdx 
  30. .text:0000000140004636                 mov     rax, [rdx+0B8h] 
  31. .text:000000014000463D                 xor     esi, esi 
  32. .text:000000014000463F                 mov     [rsp+358h+var_338], esi 
  33. .text:0000000140004643                 mov     edi, 0C0000001h 
  34. .text:0000000140004648                 mov     [rsp+358h+var_334], edi 
  35. .text:000000014000464C                 mov     ecx, 270h 
  36. .text:0000000140004651                 cmp     [rax+8], ecx 
  37. .text:0000000140004654                 jnz     loc_140004778 
  38. .text:000000014000465A                 mov     r14, [rdx+18h] 
  39. .text:000000014000465E                 cmp     [r14], ecx 
  40. .text:0000000140004661                 jnz     loc_140004778 
  41. .text:0000000140004667                 cmp     dword ptr [r14+4], 345821ABh 
  42. .text:000000014000466F                 jnz     loc_140004778 
  43. .text:0000000140004675                 lea     rdx, [rsp+358h+v13] ; a2 
  44. .text:000000014000467A                 mov     rcx, r14        ; a1 
  45. .text:000000014000467D                 call    fn_DispatchIOCTLMethod 
  46. .text:0000000140004682                 mov     rcx, [r14+10h] 
  47. .text:0000000140004686                 lea     r8, [rsp+358h+MemoryDescriptorList] 
  48. .text:000000014000468B                 mov     r14d, 2FAh 
  49. .text:0000000140004691                 mov     edx, r14d 
  50. .text:0000000140004694                 call    sub_140003DBC 
  51. .text:0000000140004699                 mov     r8, rax 
  52. .text:000000014000469C                 mov     [rsp+358h+var_330], rax 
  53. .text:00000001400046A1                 test    rax, rax 
  54. .text:00000001400046A4                 jz      loc_140004778 
  55. .text:00000001400046AA 
  56. .text:00000001400046AA loc_1400046AA:                          ; DATA XREF: .rdata:0000000140008A5C↓o 
  57. .text:00000001400046AA ;   __try { // __except at loc_140004759 
  58. .text:00000001400046AA                 mov     rcx, rax 
  59. .text:00000001400046AD                 lea     rdx, [rsp+358h+v13] 
  60. .text:00000001400046B2                 lea     eax, [rsi+5] 
  61. .text:00000001400046B5                 lea     r9d, [rax+7Bh] 
  62. .text:00000001400046B9 
  63. .text:00000001400046B9 loc_1400046B9:                          ; CODE XREF: sub_140004604+FD↓j 
  64. .text:00000001400046B9                 movups  xmm0, xmmword ptr [rdx] 
  65. .text:00000001400046BC                 movups  xmmword ptr [rcx], xmm0 
  66. .text:00000001400046BF                 movups  xmm1, xmmword ptr [rdx+10h] 
  67. .text:00000001400046C3                 movups  xmmword ptr [rcx+10h], xmm1 
  68. .text:00000001400046C7                 movups  xmm0, xmmword ptr [rdx+20h] 
  69. .text:00000001400046CB                 movups  xmmword ptr [rcx+20h], xmm0 
  70. .text:00000001400046CF                 movups  xmm1, xmmword ptr [rdx+30h] 
  71. .text:00000001400046D3                 movups  xmmword ptr [rcx+30h], xmm1 
  72. .text:00000001400046D7                 movups  xmm0, xmmword ptr [rdx+40h] 
  73. .text:00000001400046DB                 movups  xmmword ptr [rcx+40h], xmm0 
  74. .text:00000001400046DF                 movups  xmm1, xmmword ptr [rdx+50h] 
  75. .text:00000001400046E3                 movups  xmmword ptr [rcx+50h], xmm1 
  76. .text:00000001400046E7                 movups  xmm0, xmmword ptr [rdx+60h] 
  77. .text:00000001400046EB                 movups  xmmword ptr [rcx+60h], xmm0 
  78. .text:00000001400046EF                 add     rcx, r9 
  79. .text:00000001400046F2                 movups  xmm1, xmmword ptr [rdx+70h] 
  80. .text:00000001400046F6                 movups  xmmword ptr [rcx-10h], xmm1 
  81. .text:00000001400046FA                 add     rdx, r9 
  82. .text:00000001400046FD                 sub     rax, 1 
  83. .text:0000000140004701                 jnz     short loc_1400046B9 
  84. .text:0000000140004703                 movups  xmm0, xmmword ptr [rdx] 
  85. .text:0000000140004706                 movups  xmmword ptr [rcx], xmm0 
  86. .text:0000000140004709                 movups  xmm1, xmmword ptr [rdx+10h] 
  87. .text:000000014000470D                 movups  xmmword ptr [rcx+10h], xmm1 
  88. .text:0000000140004711                 movups  xmm0, xmmword ptr [rdx+20h] 
  89. .text:0000000140004715                 movups  xmmword ptr [rcx+20h], xmm0 
  90. .text:0000000140004719                 movups  xmm1, xmmword ptr [rdx+30h] 
  91. .text:000000014000471D                 movups  xmmword ptr [rcx+30h], xmm1 
  92. .text:0000000140004721                 movups  xmm0, xmmword ptr [rdx+40h] 
  93. .text:0000000140004725                 movups  xmmword ptr [rcx+40h], xmm0 
  94. .text:0000000140004729                 movups  xmm1, xmmword ptr [rdx+50h] 
  95. .text:000000014000472D                 movups  xmmword ptr [rcx+50h], xmm1 
  96. .text:0000000140004731                 movups  xmm0, xmmword ptr [rdx+60h] 
  97. .text:0000000140004735                 movups  xmmword ptr [rcx+60h], xmm0 
  98. .text:0000000140004739                 mov     rax, [rdx+70h] 
  99. .text:000000014000473D                 mov     [rcx+70h], rax 
  100. .text:0000000140004741                 movzx   eax, word ptr [rdx+78h] 
  101. .text:0000000140004745                 mov     [rcx+78h], ax 
  102. .text:0000000140004749                 mov     edi, esi 
  103. .text:000000014000474B                 mov     [rsp+358h+var_334], esi 
  104. .text:000000014000474F                 mov     esi, r14d 
  105. .text:0000000140004752                 mov     [rsp+358h+var_338], r14d 
  106. .text:0000000140004757                 jmp     short loc_14000476B 
  107. .text:0000000140004757 ;   } // starts at 1400046AA 
  108. .text:0000000140004759 ; --------------------------------------------------------------------------- 
  109. .text:0000000140004759 
  110. .text:0000000140004759 loc_140004759:                          ; DATA XREF: .rdata:0000000140008A5C↓o 
  111. .text:0000000140004759 ;   __except(1) // owned by 1400046AA 
  112. .text:0000000140004759                 mov     esi, [rsp+358h+var_338] 
  113. .text:000000014000475D                 mov     edi, [rsp+358h+var_334] 
  114. .text:0000000140004761                 mov     r8, [rsp+358h+var_330] 
  115. .text:0000000140004766                 mov     rbx, [rsp+358h+var_328] 
  116. .text:000000014000476B 
  117. .text:000000014000476B loc_14000476B:                          ; CODE XREF: sub_140004604+153↑j 
  118. .text:000000014000476B                 mov     rdx, r8         ; BaseAddress 
  119. .text:000000014000476E                 mov     rcx, [rsp+358h+MemoryDescriptorList] ; MemoryDescriptorList 
  120. .text:0000000140004773                 call    sub_140003980 
  121. .text:0000000140004778 
  122. .text:0000000140004778 loc_140004778:                          ; CODE XREF: sub_140004604+50↑j 
  123. .text:0000000140004778                                         ; sub_140004604+5D↑j ... 
  124. .text:0000000140004778                 mov     [rbx+30h], edi 
  125. .text:000000014000477B                 mov     edx, esi 
  126. .text:000000014000477D                 mov     [rbx+38h], rdx 
  127. .text:0000000140004781                 xor     edx, edx        ; PriorityBoost 
  128. .text:0000000140004783                 mov     rcx, rbx        ; Irp 
  129. .text:0000000140004786                 call    cs:IofCompleteRequest 
  130. .text:000000014000478C                 mov     eax, edi 
  131. .text:000000014000478E                 mov     rcx, [rsp+358h+var_18] 
  132. .text:0000000140004796                 xor     rcx, rsp 
  133. .text:0000000140004799                 call    __security_check_cookie 
  134. .text:000000014000479E                 lea     r11, [rsp+358h+var_8] 
  135. .text:00000001400047A6                 mov     rbx, [r11+10h] 
  136. .text:00000001400047AA                 mov     rsi, [r11+20h] 
  137. .text:00000001400047AE                 mov     rdi, [r11+28h] 
  138. .text:00000001400047B2                 mov     rsp, r11 
  139. .text:00000001400047B5                 pop     r14 
  140. .text:00000001400047B7                 retn 
  141. .text:00000001400047B7 ; } // starts at 140004604 
  142. .text:00000001400047B7 sub_140004604   endp 
  143. .text:00000001400047B7 

 可以看到它接收到两个参数,MS文档解释说,IRP_MJ_WRITE调度程序函数接收PDEVICE_OBJECT作为第一个参数,然后接收指向IRP结构的指针。

 在第16行,驱动程序控制输入缓冲区的长度等于0x270,这似乎是唯一可能的长度。

分析以下行时请小心:

  1. v5 = a2->AssociatedIrp.MasterIrp; 

MasterIrp与Union(结构_IRP)内部的IrpCount和SystemBuffer共享相同的偏移量:

  1. union { 
  2.     struct _IRP     *MasterIrp; 
  3.     __volatile LONG IrpCount; 
  4.     PVOID           SystemBuffer; 
  5.   } AssociatedIrp; 

 在这种情况下,将尝试从IRP请求中检索SystemBuffer,它没有引用MasterIrp指针,我需要修复它。在IDA PRO中,可以通过执行“右键单击->选择并集字段”来轻松完成此操作:


现在我已经确定了输入缓冲区的存储位置,让我看看如何对其进行解析:

  1. v5 = a2->AssociatedIrp.SystemBuffer; 
  2. if ( *(_DWORD *)v5 == 0x270 && *((_DWORD *)v5 + 1) == 0x345821AB ) 
  3. sub_140001E00(v5, &v13); 

 可以看到第一个DWORD预期等于0x270(长度的相同值);然后,下一个DWORD需要具有某种与0x345821AB匹配的Magic值。如果两个条件都满足,则调用函数sub_140001E00来发送第一个参数中的缓冲区,并在第二个参数上引用未知的结构,我决定调用此函数fn_DispatchIOCTLMethod,我将在下一部分中对其进行分析。

重命名变量后,可以得出结论,输入缓冲区的结构将如下所示:

  1. struct DrvInputBuffer 
  2.  { 
  3.    _DWORD Size;                           // Offset 0x0 
  4.    _DWORD MagicNumber;                    // Offset 0x4 
  5.    _BYTE gap8[8];                         // Offset 0x8 
  6.    void *pvoid10;                         // Offset 0x10 
  7.  }; 

 由于尚未分析所有调度方法,但是我想提供对输入缓冲区的完整分析,因此我将展示Driver正在使用的完整结构。

最终结构如下所示:

  1. struct DrvInputBuffer 
  2.   _DWORD Size;                           // Offset 0x0 
  3.   _DWORD MagicNumber;                    // Offset 0x4 
  4.   _DWORD RequestId;                      // Offset 0x8 
  5.   _DWORD FnIndex;                        // Offset 0xc 
  6.   void *pvoid10;                         // Offset 0x10 
  7.   unsigned __int8 buffer[600];           // Offset 0x18 
  8. }; 

 此函数还可以执行其他操作,但是现在让我忽略它们。

0x03 fn_DispatchIOCTLMethod(0x140001E00)


可以在这里找到代码,这个函数很小,将看到正确设置类型并重命名后,一切变得更加清晰。

我需要做的第一件事是将先前定义的结构DrvInputBuffer添加到IDA Pro。在“本地类型”子视图上,可以执行“右键单击->插入”,你可以在其中复制粘贴结构定义:


下一步,通过执行“右键单击变量->转换为结构*”,将第一个参数重命名为该结构的指针。

将得到如下内容:

  1. __int64 __fastcall fn_DispatchIOCTLMethod(DrvInputBuffer *a1, __int64 a2) 
  2.   int v2; // er8 
  3.  
  4.   v2 = 0; 
  5.   if ( !dword_14000A240 ) 
  6.     return 3221225473i64; 
  7.   while ( dword_140009E40[4 * v2] != a1->FnIndex ) 
  8.   { 
  9.     if ( ++v2 >= dword_14000A240 ) 
  10.       return 3221225473i64; 
  11.   } 
  12.   return (*&dword_140009E40[4 * v2 + 2])(a1, a2); 

 如果你已阅读以前的文章,则可以识别dword_14000A240,在分析fn_InitDispatchMethodArray时,我在第二篇文章中重命名了此变量:FunctionCount**。

dword_140009E40发生了相同的情况,在同一帖子上将其重命名为IOCTLFunctionArray,它是一个包含多个DispatcherStruct结构的数组:

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

 基于此,我可以确定以下行为:首先,应用程序通过将FunctionsCount和NULL 进行比较来验证IOCTLFunctionArray是否已初始化。然后,在while循环中进行迭代,将每个元素的索引值与DWORD在输入缓冲区的偏移量0xC(在结构上定义为FnIndex)进行比较,它们增加计数器,直到达到存储在FunctionsCount中的最大值。

如果索引之间匹配,则调用存储在DispatcherStruct-> FnPtr中的函数;否则,将调用该函数。发送fn_DispatchIOCTLMethod的相同两个参数:SystemBuffer和对一个未知结构的引用。

最终函数:

  1. __int64 __fastcall fn_DispatchIOCTLMethod(DrvInputBuffer *SystemBuffer, DrvOutputBuffer *a2) 
  2.   int counter; // er8 
  3.  
  4.   counter = 0; 
  5.   if ( !FunctionsCount ) 
  6.     return 0xC0000001i64; 
  7.   while ( IOCTLFunctionArray[counter].Index != SystemBuffer->FnIndex ) 
  8.   { 
  9.     if ( ++counter >= FunctionsCount ) 
  10.       return 0xC0000001i64; 
  11.   } 
  12.   return (IOCTLFunctionArray[counter].FnPtr)(SystemBuffer, a2); 

 0x04 参考信息

  •  https://docs.microsoft.com/zh-cn/windows-hardware/drivers/kernel/writing-dispatch-routines
  •  https://docs.microsoft.com/zh-CN/windows-hardware/drivers/kernel/handling-irps
  •  https://github.com/microsoft/Windows-driver-samples
  •  https://docs.microsoft.com/zh-CN/windows-hardware/drivers/ddi/wdm/ns-wdm-_irp

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

 

责任编辑:姜华 来源: 嘶吼网
相关推荐

2020-11-13 10:06:47

XignCode3

2009-07-20 18:01:38

Oracle JDBC

2009-07-06 18:17:46

JDBC驱动程序

2017-09-14 14:27:40

2010-01-07 13:27:22

Linux驱动程序

2009-08-12 18:20:39

C#事件驱动程序

2011-01-10 18:21:38

linux编写程序

2017-03-03 08:40:32

2021-12-06 07:47:36

Linux 驱动程序Linux 系统

2011-01-06 16:29:08

linuxtasklet机制

2009-09-04 10:10:33

Visual Basi

2022-03-08 09:25:52

数据库系统MongoDB

2009-06-15 14:18:00

netbeans配置JDBC驱动程序

2019-10-22 15:40:34

Windows 10驱动程序Windows

2013-10-31 16:29:10

Linux内核

2009-12-07 09:39:04

Linux设备驱动硬件通信

2021-11-29 07:55:45

Linux GPIO Linux 系统

2010-04-19 10:28:43

Unix操作系统

2019-03-27 13:20:31

Windows 10更新驱动程序

2009-07-03 16:48:05

Windows CE
点赞
收藏

51CTO技术栈公众号