首页
社区
课程
招聘
[原创]《逆向工程核心原理》——反调试技术
发表于: 2020-12-27 19:33 8973

[原创]《逆向工程核心原理》——反调试技术

2020-12-27 19:33
8973

这本书的反调试技术分成了静态反调试技术、动态反调试技术、高级反调试技术


我只是写下来作为一个笔记提示,其中可能有些写的略微简略,也应不乏谬误,欢迎提出意见,我再将其修缮


静态反调试技术:

A)    PEB结构体可用来进行反调试的四项:

+0x002  BeingDebugged   ;UChar

+0x00c  Ldr        ;Ptr32_RTL_USER_PROCESS_PARAMETERS

+0x018 ProcessHeap  ;Ptr32 Void

+0x068  NtGlobalFlag  ;Uint48

 

1.      BeingDebugged    一个Flag

被调试:1

非调试:0

相关函数:IsDebuggerPresent()           ;获取PEB.BeingDebugged值来判断

破解:将BeingDebugged值置1

2.      Ldr

Ldr指向一个在堆中创建的_PEB_LDR_DATA结构体

而调试进程的时候,未使用的堆内存区域全部填充着0xEEFEEEFE

破解:将0xEEFEEEFE全部用NULL填充

注:XP系统之后不适用

3.      Process Heap

指向HEAP结构体的指针

调试状态:

        此结构体Flags(+0xC)被设置为0x2

        Force Flags(+0x10)被设置为0x0

       相关函数:GetProcessHeap() 获取结构体地址

       注:仅XP系统可用

4.      NtGlobalFlag

调试状态:值为0x70

FLG_HEAP_ENABLE_TAIL_CHECK(0X10)|

FLG_HEAP_ENABLE_FREE_CHECK(0X20)|

FLG_HEAP_VALIDATE_PARAMETERS(0X40)

非调试状态:值为0

破解之法:该值设0

注:将运行中的进程附加到调试器时,NtGlobalFlag值不变

 

附:PEB位置查找方式

1.

FS:[0x30]=address of PEB

2.

FS:[0x18]=address of TEB -> EAX    (FS:[0x0]为TEB偏移0x0处的值)

[EAX+0x30] = address of PEB

这种方法是上一种的扩展形式,看起来比较麻烦

 

B)    NtQueryInformationProcess() API探测调试器技术

第二个参数——枚举类型,指定特定值,函数会将信息设置到第三个参数

ProcessDebugPort       ;+0x7

ProcessDebugObjectHandle      ;+0x1E

ProcessDebugFlags      ;+0x1F

 

以下针对第三个参数:

ProcessDebugPort获取调试端口——调试的时候系统分配进程一个调试端口FFFFFFFF,非调试状态为0

ProcessDebugObjectHandle获取调试对象句柄——如果进程处于调试状态,调试句柄值就存在,非调试状态为NULL

ProcessDebugFlags调试标志——调试状态,为0;非调试状态,为1。

附:

1.函数定义

2. 枚举类型


 

C)    NtQuerySystemInformation()——基于调试环境检测的反调试技术(检测当前OS是否在调试模式下运行)

第一个参数 SYSTEM_INFORMATION_CLASS  SystemInformationClass

SYSTEM_INFORMATION_CLASS是枚举类型

值为SystemKernelDebuggerInformation(0x23)时

第二个参数PVOID  SystemInformation被填入

SYSTEM_KERNEL_DEBUGGER_INFORMATION结构体地址

系统处于调试状态:

SYSTEM_KERNEL_DEBUGGER_INFORMATION.DebuggerEnabled=1

破解:以正常模式启动windows

 

附:

1.SYSTEM_INFORMATION_CLASS枚举类型

2.函数定义

 

D)   NtQueryObject()——调试器调试进程时,系统会创建一个内核调试对象

第二个参数OBJECT_INFORMATION_CLASS  ObjectInformationClass赋予特定值,相关信息会被填入第三个参数PVOID  ObjectInformation

 

arg2:

OBJECT_INFORMATION_CLASS ObjectInformationClass是一个枚举类型,ObjectAllTypesInformation(0x3)获取系统所有对象信息,再从中检测是否存在调试对象。

 

arg3:(when arg2 == 0x3)

ObjectInformation

系统所有对象信息,先将其转换为POBJECT_ALL_INFORMATION类型

OBJECT_ALL_INFORMATION是一个结构体,前面加上一个大写字母P代表指向这个结构体的指针。结构体的第二个成员

OBJECT_TYPE_INFORMATION  ObjectTypeInformation结构体的第一个成员TypeName,当此项为”DebugObject”时,说明正在调试

循环直到结束,如果没有,则不在调试中

 

亦即判断

ObjectInformation->ObjectTypeInformation->TypeName == “DebugObject”

与否

 

破解:

将函数第二个参数从0x3改为0x0,或者钩取对应api函数

 

注意:书中举的例子是ZwQueryObject()而非NtQueryObject()

书中并没有对其作解释,下面是微软给的说法

关于Nt前缀与Zw前缀的区别:

adbK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1L8$3y4K6i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3P5X3S2Q4x3X3c8U0L8W2)9J5c8Y4N6A6L8X3c8G2N6%4y4Q4x3X3c8Z5j5i4u0V1N6$3q4J5k6g2)9J5c8X3c8J5K9i4k6W2M7Y4y4Q4x3V1k6C8k6i4u0F1k6h3I4Q4x3V1k6#2M7$3W2F1k6#2)9J5k6r3&6@1i4K6u0V1j5h3&6V1i4K6u0V1P5Y4N6Q4x3X3c8$3k6i4u0K6K9h3!0F1M7#2)9J5k6r3!0X3i4K6u0V1N6r3S2W2i4K6u0V1L8X3q4@1K9i4k6W2i4K6u0V1M7%4W2K6N6r3g2E0i4K6u0V1M7$3g2J5N6X3W2U0k6i4y4Q4x3X3c8J5L8%4g2@1K9h3&6W2M7H3`.`.

 

附函数定义以及一些结构体:

1.NtQueryObject()函数定义

 

2. SYSTEM_INFORMATION_CLASS枚举类型

 

3. OBJECT_ALL_INFORMATION结构体

 

4. OBJECT_TYPE_INFORMATION结构体

  

 

E)     ZwSetInformationThread()——强制分离调试器

第一个参数ThreadHandle(枚举类型)用来接收当前线程的句柄

第二个参数ThreadInformationClass表示线程信息,当其设置为ThreadHideFromDebugger(0x11)后,调试进程会被分离出来。

非调试状态:该函数没有任何影响

调试状态:调试器终止,停止自身进程

破解:将ThreadInformationClass参数改为0x0

或者钩取此api函数

 

附:

1.ThreadHandle(枚举类型)


[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2020-12-29 00:15 被哈桑编辑 ,原因: 更新反调试技术
收藏
免费 3
支持
分享
最新回复 (2)
雪    币: 24
活跃值: (286)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
很全面,感谢分享
2021-2-3 10:31
0
雪    币: 1243
活跃值: (352)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
2021-4-1 11:39
0
游客
登录 | 注册 方可回帖
返回