アンチデバッグおよび抗抗デバッグ

アンチデバッグおよび抗抗デバッグ

アンチデバッグは何ですか?抗抗デバッグは何ですか?

静的なアンチデバッギング

  • 特徴:一般的なブロックデバッガ、デバッグだけで試運転の開始時に1回の休憩の後に理由を見つける必要があるかもしれません

  • PEB

    • BeginDebug :デバッグフラグ
    // 通过检查 PEB.BeingDebuged 字段判断是否被调试
    // 可以在目标程序运行之前修改对应的字段为 0 进行反反调试
    bool CheckBeingDebugged()
    {
      __asm 
      {
          ; 获取到 PEB 的内容
          mov eax, fs:[0x30]
          ; 获取 PEB 内偏移为 2 大小为 1 字节的字段
          movzx eax, byte ptr[eax + 2]
      }
    }
    
    
    int main()
    {
      if (CheckBeingDebugged())
          printf("当前处于[被]调试状态\n");
      else
          printf("当前处于[非]调试状态\n");
    
      system("pause");
      return 0;
    }
    // 使用 IsDebuggerPresent 原理同样是判断 PEB.BeingDebuged
    // 通过 HOOK 函数和修改对应字段的方式可以进行反调试
    
    int main()
    {
      if (IsDebuggerPresent())
          printf("当前处于[被]调试状态\n");
      else
          printf("当前处于[非]调试状态\n");
    
      system("pause");
      return 0;
    }
    • Ldr メモリ状態
    • HeapFlagsForce Flags):ヒープの状態
    • NtGlobalFlag :カーネルのグローバルマーク
      • PEB.NtGlobalFlagデバッグ状態にあるときに、デバッグするかどうかを決定PEB.NtGlobalFlagされて格納された0x70、抗-抗デバッグすることができるフラグを変更します
    bool CheckNtGlobalFlag()
    {
      __asm
      {
          ; 获取到 PEB, 保存在 FS :[0x30]
          mov eax, fs : [0x30]
          ;获取到 NtGlobalFlag 字段的内容
          mov eax, [eax + 0x68]
      }
    }
    int main()
    {
      if (CheckNtGlobalFlag())
          printf("当前处于[被]调试状态\n");
      else
          printf("当前处于[非]调试状态\n");
    
      system("pause");
      return 0;
    }
  • TEB

    • StaticUnicodeString :静的バッファ
  • オリジナル API

    • NtQuerySystemInformationProcess()
      • ProcessDebugPort(0x07):デバッグポートを取得します。
      • ProcessDebugObjectHandle(0x1E):ハンドルのデバッグを取得
      • ProcessDebugFlag(0x1F):デバッグフラグを取得します。
    • NtQuerySystemInformation()
      • SystemKernelDeBuggerInformation(0x23):取得システムのデバッグ状態(デュアル
    • NtQueryObject() :横断システムのカーネル
  • 攻撃デバッガ

    • NtSetInformationThread()
      • ThreadHideFormDebugger(0x11)
  • 検査工程を開きます

    • SetDebugPrivilege プロセスがデバッグ権限を持っているかどうかをチェック➡️
  • 使用するTLSコールバック関数を

  • 通常の使用API

    • 親プロセスをチェック
      • プロセスが正常に開いている場合、それは親プロセスである必要がありExplorer.exe、それは、リソースマネージャであるとの判断がされていない場合は、あなたは参照を提供するために、テストすることができます。
    bool CheckParentProcess()
    {
    
      struct PROCESS_BASIC_INFORMATION {
          ULONG ExitStatus;           // 进程返回码
          PPEB  PebBaseAddress;       // PEB 地址
          ULONG AffinityMask;         // CPU 亲和性掩码
          LONG  BasePriority;         // 基本优先级
          ULONG UniqueProcessId;      // 本进程PID
          ULONG InheritedFromUniqueProcessId; // 父进程PID
      }stcProcInfo;
    
      // 查询到目标进程的对应信息,主要是 父进程 ID
      NtQueryInformationProcess(
          GetCurrentProcess(), 
          ProcessBasicInformation, 
          &stcProcInfo,
          sizeof(stcProcInfo), 
          NULL);
    
      // 查询资源管理器对应的 PID
      DWORD ExplorerPID = 0;
      DWORD CurrentPID = stcProcInfo.InheritedFromUniqueProcessId;
      GetWindowThreadProcessId(FindWindow(L"Progman", NULL), &ExplorerPID);
    
      // 比对两个 PID 的值,相同就OK,不同就可能被调试
      return ExplorerPID == CurrentPID ? false : true;
    }
    
    
    int main()
    {
      if (CheckParentProcess())
          printf("当前处于[被]调试状态\n");
      else
          printf("当前处于[非]调试状态\n");
    
      system("pause");
      return 0;
    }
    • ウィンドウ名をチェック
      • 原則は、対応するウィンドウの名前が存在して検索し、ウィンドウクラスまたはウィンドウを通じて、デバッガやその他の分析ツールをチェックすることです。【欠点は通常固定されていないウィンドウの名前であり、非常に不便チェック]
      • また、デバッガやその他のツールは、プロセスを横断によって存在するかどうかを確認することができます。【欠点は、exeファイル名の名前を変更することにより、プロセスを変更することができることです]
    int main()
    {
      if (FindWindow(NULL, L"OllyDbg"))
          printf("存在调试器\n");
      else
          printf("没检测到调试器\n");
    
      return 0;
    }
    • プロセス名を確認してください
      • 原理は、クエリであるEPROCESSあなたがすることはできませんので、関連分野の構造R3変更R0データを、私たちができるだけでHOOK
    bool CheckProcessDebugPort() 
    {
      int nDebugPort = 0;
      NtQueryInformationProcess(
          GetCurrentProcess(),    // 目标进程句柄
          ProcessDebugPort,       // 查询信息类型(7)
          &nDebugPort,            // 输出查询信息
          sizeof(nDebugPort),     // 查询类型大小
          NULL);                  // 实际返回数据大小
    
      // 如果返回的是 -1 ,那么就被调试了
      return nDebugPort == 0xFFFFFFFF ? true : false;
    }
    
    
    int main()
    {
      if (CheckProcessDebugPort())
          printf("当前处于[被]调试状态\n");
      else
          printf("当前处于[非]调试状态\n");
    
      system("pause");
      return 0;
    }
    • ファイル名やファイルパスをチェック
    • レジストリチェッカー
    • ...

ダイナミックアンチデバッギング

  • 特徴:デバッグを必要と頻繁にトリガすることができ、デバッグプロセスにおける一般的なブロックデバッガデバッグのプロセスに目を保ちます
  • 使用SEH
    • 異常な
    • ブレークポイント
    • SetUnhandleedExceptionFilter()
  • タイム・チェック
  • シングルステップの検査
  • パッチをチェック
  • ファンファンのコンパイル
  • コードを盗みます
  • ページの保護
  • シェル
  • 仮想マシン

OllyDbgプラグインの作成

  1. どのように通常存在するプラグイン?

通常でDLL道の存在が、拡張子が変更されることがあり

  1. プラグインアプリケーションをすべて検索するには?

すべてのプラグインは、特定のパスに保護されなければなりません

  1. あなたは、アプリケーションがその要件を満たしているか知っていますか?
  • プラグインその機能を説明するために、情報を名前を指定し提供しなければならない、プラグインはまた、機能によって、特定の機能を提供する必要があるの名前に対応

おすすめ

転載: www.cnblogs.com/TJTO/p/11374003.html