反调试技术(1)_各种标志

总之就是记录各种用于防止反调试的字段,感觉没啥用。

参考、摘抄自:https://ctf-wiki.org/reverse/windows/anti-debug

NtGlobalFlag

概念解释

在 32 位机器上, NtGlobalFlag字段位于PEB(进程环境块)0x68的偏移处, 64 位机器则是在偏移0xBC位置. 该字段的默认值为 0,当调试器运行时,该字段有时会被更改(不一定)。

1
2
3
FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)

程序中可能会对该字段进行检测,若不为00就直接跳转到being_debugged

注:NtGlobalFlag的那 3 个标志位只有当程序是由调试器创建, 而非由调试器附加上去的进程时, 才会被设置.

检测方式 (32位)

注:fs寄存器指向当前活动线程的TEB

image-20220304165757871

1
2
3
4
5
mov eax, fs:[30h] ;Process Environment Block()
mov al, [eax+68h] ;NtGlobalFlag
and al, 70h
cmp al, 70h
je being_debugged

更改初值(并不知道有啥用)

注册表计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session ManagerGlobalFlag的值会替换进行NtGlobalFlag字段。(重启后生效)

image-20220304164126021

绕过方法

  • 手动修改标志位的值 (FLG_HEAP_ENABLE_TAIL_CHECK, FLG_HEAP_ENABLE_FREE_CHECK, FLG_HEAP_VALIDATE_PARAMETERS)
  • 在 Ollydbg 中使用hide-debug插件
  • 在 Windbg 禁用调试堆的方式启动程序 (windbg -hd program.exe)

示例(32位):

1
2
3
4
5
6
7
mov eax, large fs:30h   ; PEB struct loaded into EAX
mov eax, [eax+68h] ; NtGlobalFlag (offset 0x68 relative to PEB) saved to EAX
sub eax, 70h ; Value 0x70 corresponds to all flags on (FLG_HEAP_ENABLE_TAIL_CHECK, FLG_HEAP_ENABLE_FREE_CHECK, FLG_HEAP_VALIDATE_PARAMETERS)
mov [ebp+var_1828], eax
cmp [ebp+var_1828], 0 ; Check whether 3 debug flags were on (result of substraction should be 0 if debugged)
jnz short loc_4035B5 ; No debugger, program continues...
call s_selfDelete ; ...else, malware deleted

断在mov eax, [eax+68h]处,使用CommandLine插件用dump fs:[30]+0x68dump 出NtGlobalFlag的内容:

Manually-set-peb-ntglobalflag.png

右键选择Binary->Fill with 00's将值0x70替换为0x00即可。

Heap Flags

Heap flags包含有两个与NtGlobalFlag一起初始化的标志: FlagsForceFlags。改字段的值与调试器和Windows的版本都有关。

  • Flags 字段:
    • 在 32 位 Windows NT, Windows 2000 和 Windows XP 中, Flags位于堆的0x0C偏移处. 在 32 位 Windows Vista 及更新的系统中, 它位于0x40偏移处.
    • 在 64 位 Windows XP 中, Flags字段位于堆的0x14偏移处, 而在 64 位 Windows Vista 及更新的系统中, 它则是位于0x70偏移处.
  • ForceFlags 字段:
    • 在 32 位 Windows NT, Windows 2000 和 Windows XP 中, ForceFlags位于堆的0x10偏移处. 在 32 位 Windows Vista 及更新的系统中, 它位于0x44偏移处.
    • 在 64 位 Windows XP 中, ForceFlags字段位于堆的0x18偏移处, 而在 64 位 Windows Vista 及更新的系统中, 它则是位于0x74偏移处.

总之呢,在各种情况下会有各种的取值,具体的需要根据情况而定。

The Heap

https://ctf-wiki.org/reverse/windows/anti-debug/the-heap/

看不太懂,复杂,目前先不记录。

总之就是,在某些字段成立时,用特定的字段填写在堆的尾部,不知道是怎么做到的,迷惑。。

  • 如果设置了HEAP_TAIL_CHECKING_ENABLED标志 (见Heap Flags节), 那么在 32 位 windows 中就会在分配的堆块尾部附加 2 个0xABABABAB(64 位环境就是 4 个).
  • 如果设置了HEAP_FREE_CHECKING_ENABLED(见Heap Flags节) 标志, 那么当需要额外的字节来填充堆块尾部时, 就会使用0xFEEEFEEE(或一部分) 来填充