简单对抗某个驱动的反调试

标 题: 【原创】简单对抗某个驱动的反调试
作 者: ReturnsMe
时 间: 2010-04-18,20:02:11
链 接: http://bbs.pediy.com/showthread.php?t=111236

先声明:
1.  本文纯娱乐,本人并不从事制作非法软件的活动…也请读者不要将本文的技术运用到非法领域,否则一切后果自负。
2.我是菜鸟 ,都是些基本内容。只是看网上很多人搞,又弄的很麻烦,反正自己前两天玩儿了一小下,索性发出来。在ring0搞反反调试似乎已经被某广告鄙视的不行了~所以说我只是娱乐,没有其他目的。我很挫~欢迎批评指正,欢迎交流: http://hi.baidu.com/andriy_aolala/blog
3.  本文参考了一些文章,在文末 一 并感谢

不同游戏的保护驱动版本不太一样,我看的是cf的版本。先用ark初步扫描一下(如果要用xuetr,要先于tp加载,因为它hook了 tessafe.sys同样hook的指令,后启动xuetr导致直接重启),我用我以前写的一个ark扫描了一下。
他的hook如下:
代码:
  IAT   kdcom.dll  KdSendPacket    KdRecivePacket
  Inline NtRead/WriteVirtualMemory KiAttachProcess
  Call hook  NtOpenThread NtOpenProcess 中的ObReferenceObjectByPointer
  此外还有3个Callback,两个系统线程
一、首先要解决内核调试的问题,有Windbg才好继续。
代码:
.text:01001532                 call    ds:KdDisableDebugger
.text:01001538
.text:01001538 loc_1001538:                            ; CODE XREF: .text:01001530j
.text:01001538                 mov     edx, ds:KdDebuggerEnabled
.text:0100153E                 xor     ecx, ecx
.text:01001540                 xor     eax, eax
.text:01001542                 inc     ecx
.text:01001543                 inc     eax
.text:01001544                 lock cmpxchg [edx], ecx
.text:01001548                 test    al, al
.text:0100154A                 jnz     short loc_1001532
.text:0100154C                 retn
Ida里面有这么一段,这不新鲜了,直接注册一个LoadImageNotify,启动前IAT hook KdDisableDebugger 和KdDebuggerEnabled,再inline hook 掉TesSafe.sys 里面hook掉KdSendPacket    KdRecivePacket 的函数,跳转回原函数即可。

至此我们已经可以通过WinDbg调试驱动了。

二、放行OllyIce 和 CE

Tp hook 了一大堆,网上写的都是跳来跳去的绕过,但是即使绕过了也有可能过一段时间提示非法软件,原因不明。。总之这么来很费时间。

于是我在其OpenProcess 的hook函数里面找到
代码:
.text:01001EBD                 call    ds:IoGetCurrentProcess ;得到调用者的eprocess
.text:01001EC3                 mov     [ebp+pEpro], eax
.text:01001EC6                 push    [ebp+pEpro]     ; pEpro
.text:01001EC9                 call    EprocessChk  ;非常关键的比对函数
.text:01001ECE                 movzx   eax, al
.text:01001ED1                 test    eax, eax
.text:01001ED3                 jz      short loc_1001EDA
.text:01001ED5                 jmp     loc_1001FC7  ;返回1的话 直接放行

.text:01001FC7                 mov     eax, off_100A090
.text:01001FCC                 or      ecx, 0FFFFFFFFh
.text:01001FCF                 lock xadd [eax], ecx
.text:01001FD3                 popf
.text:01001FD4                 popa
.text:01001FD5                 mov     esp, ebp
.text:01001FD7                 pop     ebp
.text:01001FD8                 jmp     OringinObReferenobjByPointer 跳回去
我们看看EprocessChk这个函数的伪代码
代码:
char __stdcall EprocessChk(PEPROCESS pEpro)
{
  unsigned int v1; // ecx@2

  if ( pEpro != (PEPROCESS)dword_100AFAC )
  {
    v1 = 0;
    if ( !process_white_num )
      return 0;
    while ( pEpro != (PEPROCESS) process_white_list [v1] )
    {
      ++v1;
      if ( v1 >= process_white_num )
        return 0;
    }
  }
  return 1;
}
process_white_list 是一个全局数组 有0x20个位子,里面存放的是诸如System.exe之类的系统进程eprocess。
代码:
kd> dd tessafe+EEE0
ee1c9ee0  863b57c0 8614cb78 86124598 861109d0
ee1c9ef0  86136da0 860fc3e8 860f6da0 860af510
ee1c9f00  860afda0 85fbada0 00000000 00000000
kd> !process 863b57c0
PROCESS 863b57c0  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 06c28020  ObjectTable: e1001e10  HandleCount: 240.
    Image: System
VadRoot 863b5050 Vads 4 Clone 0 Private 3. Modified 3279. Locked 0.
这个函数在其所有hook函数里面都存在,对方程序对于系统进程的函数调用是全部放行的。
所以,我们就注册一个CreateProcessNotify 把OD和CE加到那个白名单里面~~这样就不用绕hook了。
三、对抗debug port清零
  不熟悉debug port的同学可以去看软件调试,这是eprocess中的一个结构,是调试的关键,对方不停清零将导致OD像傻子一样,我看过的对抗方法有两种
1、  改内核函数DbgkXXX 系列函数中debug port相对于eprocess的偏移值 ,这个工作量太大,受不了。
2、  V大发的 重新编译WRK改eprocess结构。。这个倒是很通用啊~
其实对方程序想清零,也要有偏移,在xp中,0xbc是一个特殊的数字,IDA里面直接ATL+I …找到了3~4处,其中一处就是tp程序初始化硬编码。
代码:
char __stdcall IniHardCode(int a1)
{
  int v1; // eax@3

  if ( dword_100A050 == 5 )  //这是版本号
  {
    if ( !dword_100A054 )
    {
      v1 = a1;
。。。。。。
      return 1;
    }
    if ( dword_100A054 == 1 )
    {
      v1 = a1;
      *(_DWORD *)(a1 + 4) = 0xBCu;  //这个值就是dbgport的偏移了
。。。。。。
这个函数的参数是一个申请的内存变量地址,保存在全局变量里,我们等其加载完毕后找到这块内存,修改0xbc为0x78(exit time的值),之后就让它丫清零去吧。
四、最后的疑问
1、至此,windbg可正常使用,OD 可附加可下断,但tufuzi 在其文章中说他会检查硬件断点,所以要hook NtGetContextThread,但我下断这里没见有程序调用。。我下完硬件断点也没见对方有什么反抗。。奇怪啊奇怪
2、虽然CE被加进了白名单,但是会报非法模块,不知其检测机制,驱动里确实找到了教主说的黑名单(名字一遍,特征值一遍),但是两个黑名单自始至终全是零,搞得我以为没有,但是检测函数是实实在在存在的,crc table也存在。我晕啊。
对反调试作者的建议:把你的CV多加一点。。别暴露这么多。。
### 反调试对抗技术的实现方法与原理 反调试技术的核心目标是检测和阻止调试器对程序的分析,从而保护软件免受逆向工程攻击。以下是几种常见的反调试技术及其实现原理: #### 1. 调试器检测 通过检查特定的系统状态或行为,可以判断是否正在运行调试器。例如: - **IsDebuggerPresent**:Windows API 提供了一个简单的函数 `IsDebuggerPresent` 来检测当前进程是否被调试[^1]。 - **异常处理机制**:通过触发特定异常并观察其处理方式,可以间接判断是否存在调试器。调试器通常会改变异常处理流程[^3]。 #### 2. 时间测量 利用计时器检测调试器的存在。调试器在单步执行或断点命中时会显著增加指令执行时间。可以通过以下方法实现: - **RDTSC 指令**:读取处理器的时间戳计数器(TSC),比较两次调用之间的时间差。如果时间过长,则可能有调试器介入[^3]。 - **循环计时**:使用高精度计时器测量简单代码块的执行时间,超出预期范围则触发警报[^4]。 #### 3. 内存完整性保护 通过定期检查关键内存区域的一致性,防止调试器修改内存内容。例如: - **AntiDump 配置**:通过配置文件启用内存完整性检查,如 `[AntiDump] Enable = True`,并设置检查间隔和加密密钥[^3]。 - **动态内存校验**:在运行时对重要数据结构进行哈希计算,并与预定义值对比,确保未被篡改。 #### 4. 硬件断点检测 硬件断点通常依赖于 CPU 的调试寄存器(DR0-DR7)。可以通过以下方法检测这些寄存器的状态: - **直接读取调试寄存器**:通过汇编指令访问调试寄存器,检查是否存在非法值[^3]。 - **模拟调试行为**:尝试设置硬件断点并观察其效果,与预期结果不符则表明存在调试器。 #### 5. 虚拟化逃逸 现代反调试技术还涉及虚拟化环境检测,以防止恶意用户通过虚拟机分析程序。例如: - **嵌套虚拟化检测**:通过检查 CPU 特定标志位或异常行为,判断是否运行在虚拟化环境中[^2]。 - **指令集随机化**:动态生成和执行加密的机器码,增加静态分析难度[^3]。 #### 6. HOOK 技术 HOOK 是一种拦截和修改系统调用或消息传递的技术,广泛应用于反调试领域。其实现原理包括: - **API HOOK**:通过替换目标函数的入口地址,插入自定义逻辑。例如,HOOK `NtQueryInformationProcess` 函数以隐藏调试标志[^4]。 - **Inline HOOK**:修改目标函数的前几条指令,跳转到自定义代码段,完成后恢复原始执行流[^4]。 ### 示例代码 以下是一个简单的 RDTSC 计时检测示例: ```c #include <stdio.h> #include <intrin.h> int main() { __int64 start = __rdtsc(); for (int i = 0; i < 1000000; i++); // 循环耗时操作 __int64 end = __rdtsc(); printf("Time taken: %I64d ticks\n", end - start); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值