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

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

2020-12-27 19:33
8724

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


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


静态反调试技术:

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前缀的区别:

https://docs.microsoft.com/zh-cn/windows-hardware/drivers/kernel/using-nt-and-zw-versions-of-the-native-system-services-routines

 

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

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(枚举类型)


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

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