【Day 17】从二开始的 Anti-Anti-Debug 生活 - Anti-Anti-Debug

环境

  • Windows 10 21H1
  • x64dbg Aug 2 2020, 13:56:14
  • Visual Studio 2019
  • IDA 7.5

前情提要

上上篇【Day 15】从零开始的 Debug 生活 - Debugger 原理介绍了 Debugger 的基本运作原理,上一篇【Day 16】从一开始的 Anti-Debug 生活 - Anti-Debug
介绍针对 Debugger 运作原理的 Anti-Debug 的技巧,所以这一篇当然就要来 Anti-Anti-Debug,这一篇将会是这个 Debugger 系列的最後一篇。

这篇在 64-bit 环境下使用 x64dbg 讲解,会介绍一些常见的 Anti-Anti-Debug 手法,绕过上一篇写的 Anti-Debug 的 POC。

Anti-Anti-Debug

常见的 Anti-Anti-Debug 手法大致有以下几种

  • Patch
  • 在 Debugger 中绕过
  • Hook
  • 写 Debugger Plugin

Patch

把做 Anti-Debug 的部分程序码改掉,例如改成 nop,机械码为 90,或者是把条件判断的 je 改成 jmp 等等。

以上一篇的 Debug Flag 的 Anti-Debug 的 POC 为例,用 IDA 反组译出来如下。可以注意到 call IsDebuggerPresent 之後有个 test eax, eax,这是在判断 IsDebuggerPresent 的回传值是否为 0,如果是 0 就会跳到 loc_140117AE,然後跳出 Not Detect 的讯息框。

所以如果不希望程序侦测到我们有在使用 Debugger,也就是不想让 Detect 的讯息框跳出,就只要把 jz short loc_1400117AEjz 改成 jmp 就可以了。改完後再拿去 x64dbg 执行一次,会发现跳出 Not Detect 的讯息框。
IDA => Edit => Patch program => Assemble

在 Debugger 中绕过

直接在 Debugger 中影响程序流程,可以用 Patch,也可以改暂存器或记忆体,总之就是想办法不被 Anti-Debug 影响到就对了。

直接用 x64dbg 执行,并下断点在 main。

现在按空白键,把 je 改成 jmp,就可以无视 IsDebuggerPresent 的回传值直接绕过 Anti-Debug。

Hook

【Day 09】Hook 的奇妙冒险 - Ring3 Hook 有介绍过 Hook 的原理与实作,我们也可以使用这个技巧来实作 Anti-Debug。以 IsDebuggerPresent 为例,当回传值为 0(FALSE) 时代表没有 Debugger,否则就是正在 Debug。因此我们可以藉由 Hook IsDebuggerPresent,让它无条件回传 0,这样就可以绕过 Anti-Debug 的检查。

POC

程序专案可以参考我的 GitHub zeze-zeze/2021iThome

#include "pch.h"
#include <Windows.h>
#include "MinHook.h"

#pragma comment(lib, "libMinHook.x64.lib")

// IsDebuggerPresent 的函数原型,可以从 MSDN 查到
typedef BOOL(WINAPI* ISDEBUGGERPRESENT)();
ISDEBUGGERPRESENT fpIsDebuggerPresent = NULL;

// 窜改 IsDebuggerPresent 的函数
// 直接 return FALSE,代表没有 Debugger
BOOL WINAPI DetourIsDebuggerPresent() {
    return FALSE;
}

int hook() {
    // Hook IsDebuggerPresent,将它窜改成我们自己定义的函数。
    if (MH_Initialize() != MH_OK) {
        return 1;
    }
    MH_STATUS status = MH_CreateHook(IsDebuggerPresent, &DetourIsDebuggerPresent, reinterpret_cast<LPVOID*>(&fpIsDebuggerPresent));
    if (status != MH_OK) {
        return 1;
    }

    // 启用 Hook
    status = MH_EnableHook(IsDebuggerPresent);
    if (status != MH_OK) {
        return 1;
    }

    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: {
        hook();
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

写 Debugger Plugin

自己写 Debugger Plugin 的好处是弹性较大,不只可以 Patch、Hook,还可以改变 Debugger 处理 Exception 的方式。

这边我推荐一个 x64dbg 的 Anti-Anti-Debugger 工具 ScyllaHide,功能包含 Hook Function、Patch PEB、检查暂存器、检查 Exception 等等,把大多现有的 Anti-Debug 技巧都绕过了。而且到了最近都还有在更新,下图为目前有的功能,

安装方法就下载 Release 的 7z 档案,把里面的 HookLibraryx64.dll、scylla_hide.ini、ScyllaHideX64DBGPlugin.dp64 复制到 x64/plugins 中,x32 的也一样。

使用方法也非常简单,安装完就已经启动了基本的模式,其他还有比较进阶的模式就看个人需求再选择。拿 IsDebuggerPresent 的例子,在 x64dbg 执行档案就不会侦测到有 Debugger,因为 ScyllaHide 已经把 Debug Flag 改掉了。

参考资料


<<:  设定档格式INI + Service的管理工具Systemd简介

>>:  Day 20【ERC-721】They don't know I own this song's non-fungible token

Day29 资安小结 - 红队攻击流程与漏洞

上次我们讲到红队与蓝队,但其实还有紫队跟白队, 先介绍紫队,其实紫队是一个虚拟团队,通过红队与蓝队的...

Free hd venom

https://finchkweb.substack.com/p/finch-2021-hd-ful...

为了转生而点技能~day1:javascript 起手篇(RHS、LHS、语法作用域

本系列是为了转生,为了点技能而解任务的攻略提示,皆无营利、亦非营利取向。 Javascript:属於...

Android Studio初学笔记-Day5-TextView

基本元件介绍-TextView 接下来会开始介绍android studio一些基本的元件,这些元件...

Day30 参加职训(机器学习与资料分析工程师培训班),Tensorflow.keras

今日教学CNN 了解卷积层、池化层、平坦层、丢弃层各层相关系数的设定影响 卷基层: 积层是一组平行的...