CTF-ウィキbin.exe

、実質的にロジック次の主な機能:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  FILE *v3; // eax
  HANDLE v4; // eax
  int v11; // [esp+C4h] [ebp-A8h]
  DWORD v12; // [esp+D4h] [ebp-98h]
  LPCSTR lpFileName; // [esp+D8h] [ebp-94h]
  BOOL pbDebuggerPresent; // [esp+DCh] [ebp-90h]
  int v15; // [esp+E0h] [ebp-8Ch]
  int v16; // [esp+E4h] [ebp-88h]
  int i; // [esp+E8h] [ebp-84h]
  int v18; // [esp+ECh] [ebp-80h]
  int v19; // [esp+F0h] [ebp-7Ch]
  char v20[4]; // [esp+F8h] [ebp-74h]
  int v21; // [esp+108h] [ebp-64h]
  char v22; // [esp+10Ch] [ebp-60h]
  char v23; // [esp+10Dh] [ebp-5Fh]
  CPPEH_RECORD ms_exc; // [esp+154h] [ebp-18h]

  v22 = 0;
  memset(&v23, 0, 0x3Fu);
  v21 = 1;
  printf("Input password >");
  v3 = (FILE *)sub_40223D();
  fgets(&v22, 64, v3);
  strcpy(v20, "I have a pen.");
  v21 = strncmp(&v22, v20, 0xDu);
  if ( !v21 )
  {
    puts("Your password is correct.");
    if ( IsDebuggerPresent() == 1 )             // API反调试
    {
      puts("But detected debugger!");
      exit(1);
    }
    if ( sub_401120() == 0x70 )                 // 检测NtGloabalFlag
    {
      puts("But detected NtGlobalFlag!");
      exit(1);
    }
    v4 = GetCurrentProcess();
    CheckRemoteDebuggerPresent(v4, &pbDebuggerPresent);
    if ( pbDebuggerPresent )                    // API反调试
    {
      printf("But detected remotedebug.\n");
      exit(1);
    }
    v12 = GetTickCount();                       // 返回启动到现在的毫秒数
    for ( i = 0; i == 100; ++i )                // sleep 100毫秒
      Sleep(1u);                                // 时间差检测
    v15 = 1000;
    if ( GetTickCount() - v12 > 1000 )          // 时间差大于1000 则明显存在调试
    {
      printf("But detected debug.\n");
      exit(1);
    }
    lpFileName = "\\\\.\\Global\\ProcmonDebugLogger";
    if ( CreateFileA("\\\\.\\Global\\ProcmonDebugLogger", 0x80000000, 7u, 0, 3u, 0x80u, 0) != (HANDLE)-1 )// 检测程序ProcessMonitor
                                                // 3代表仅在文件存在时打开,如果不存在打开失败返回2
    {
      printf("But detect %s.\n", &lpFileName);
      exit(1);
    }
    v11 = sub_401130();
    if ( v11 == 1 )
    {
      printf("But detected Ollydbg.\n");
      exit(1);
    }
    if ( v11 == 2 )
    {
      printf("But detected ImmunityDebugger.\n");
      exit(1);
    }
    if ( v11 == 3 )
    {
      printf("But detected IDA.\n");
      exit(1);
    }
    if ( v11 == 4 )
    {
      printf("But detected WireShark.\n");
      exit(1);
    }
    if ( sub_401240() == 1 )                    // 这是 VMware 的一个 "后门"I/O 端口, 0x5658 = "VX". 如果程序在 VMware 内运行, 
                                                // 
                                                // 程序使用In指令通过0x5658端口读取数据时, EBX寄存器的值就会变为0x564D5868(0x564D5868 == "VMXh")
    {
      printf("But detected VMware.\n");
      exit(1);
    }
    v16 = 1;
    v19 = 1;
    v18 = 1 / 0;                                // 触发异常
    ms_exc.registration.TryLevel = -2;          // 解除异常
    printf("But detected Debugged.\n");
    exit(1);
  }
  printf("password is wrong.\n");
  return 0;
}

実質的にプログラムロジックは、入力私はペンを持っている。カラム検出プログラム番号、最後のトリガー例外の後。

デバッギング

1.IsDebuggerPresent()

strongOD効果がバイパスされるので、

2.NtGloabalFlag検出

strongOD直接的な影響バイパス

3.CheckRemoteDebuggerPresent()

バイパスにそれらを修正するジャンプ

4.時間差検出器

前記検出されたブレークポイントは、GetTickCount関数を使用してデバッグする場合。

5.ProcessMonitor検出

ここでは、デバイスファイルを検出\\。\グローバル\ ProcmonDebugLogger ProcessMonitorを検出することにより、

6.プロセス名検出

すべてのプロセスのスナップショットを取得するには、関数CreateToolhelp32snapshot(2,0)を使用して、今度の試合で

7.VMWARE検出

VMwareのI / Oポート、0x5658 =「VX」に「バックドア」である。プログラムはVMware社を実行している場合は、データポートを読んで0x5658が使用するプログラム命令、値が0x564D5868(EBXレジスタ0x564D5868に変更されます== "VMXh")

8.例外のデバッグ

まず、この異常を引き起こすために試運転

IMG

その後KiUserExceptionDispatcherブレークポイントは、これまで実行します。入力した後RtlDispatchException(異常な分布関数)

IMG

VEH-> SEH-> ZWcontinueのための異常なプロセスの呼び出し

IMG

関数呼び出しVEH、プログラムにF7工程の後とVEHを呼び出すことはありません。ダウンする続行。機能ミーツRtlpExecuteHandlerForExceptionは、内部ここで関数にSEH単一のステップを実行し

IMG

再入力した後ExcuteHandler2

IMG

その後、4019F0として関数呼び出しECXに入るの逆アセンブルは機能に従う、と私たち

int __cdecl _except_handler4(PEXCEPTION_RECORD ExceptionRecord, PVOID TargetFrame, int a3)
{
  PVOID v3; // ebx
  int *v4; // esi
  int v5; // eax
  char *v6; // edi
  int v7; // ecx
  int v8; // ecx
  int v9; // ecx
  int *v10; // eax
  int v11; // eax
  int v12; // eax
  int v13; // ecx
  int v14; // ecx
  _DWORD *v16; // eax
  int v17; // ecx
  int v18; // ecx
  PEXCEPTION_RECORD v19; // [esp+Ch] [ebp-18h]
  int v20; // [esp+10h] [ebp-14h]
  int *v21; // [esp+14h] [ebp-10h]
  int v22; // [esp+18h] [ebp-Ch]
  int v23; // [esp+1Ch] [ebp-8h]
  char v24; // [esp+23h] [ebp-1h]

  v3 = TargetFrame;
  v4 = (int *)(__security_cookie ^ *((_DWORD *)TargetFrame + 2));
  v5 = *v4;
  v24 = 0;
  v22 = 1;
  v6 = (char *)TargetFrame + 16;
  if ( v5 != -2 )
    v7 = *(_DWORD *)&v6[v5] ^ (unsigned int)&v6[v4[1]];
  v8 = *(_DWORD *)&v6[v4[2]] ^ (unsigned int)&v6[v4[3]];
  if ( ExceptionRecord->ExceptionFlags & 0x66 )
  {
LABEL_25:
    if ( *((_DWORD *)v3 + 3) == -2 )
      return v22;
    _EH4_LocalUnwind(v6, &__security_cookie);
  }
  else
  {
    *((_DWORD *)TargetFrame - 1) = &v19;
    v3 = (PVOID)*((_DWORD *)TargetFrame + 3);
    v19 = ExceptionRecord;
    v20 = a3;
    if ( v3 == (PVOID)-2 )
      return v22;
    do
    {
      v9 = v4[3 * (_DWORD)v3 + 5];
      v10 = &v4[3 * (_DWORD)v3 + 4];
      v21 = v10;
      v11 = *v10;
      v23 = v11;
      if ( v9 )
      {
        v12 = _EH4_CallFilterFunc(v9, v6);
        v24 = 1;
        if ( v12 < 0 )
        {
          v22 = 0;
          goto LABEL_11;
        }
        if ( v12 > 0 )
        {
          if ( ExceptionRecord->ExceptionCode == -529697949
            && dword_40FCBC
            && _IsNonwritableInCurrentImage(&dword_40FCBC) )
          {
            dword_40FCBC(ExceptionRecord, 1);
          }
          _EH4_GlobalUnwind2(TargetFrame, ExceptionRecord);
          v16 = TargetFrame;
          if ( *((PVOID *)TargetFrame + 3) != v3 )
          {
            _EH4_LocalUnwind(v6, &__security_cookie);
            v16 = TargetFrame;
          }
          v16[3] = v23;
          if ( *v4 != -2 )
            v17 = *(_DWORD *)&v6[*v4] ^ (unsigned int)&v6[v4[1]];
          v18 = *(_DWORD *)&v6[v4[2]] ^ (unsigned int)&v6[v4[3]];
          _EH4_TransferToHandler(v21[2], v6);
          goto LABEL_25;
        }
        v11 = v23;
      }
      v3 = (PVOID)v11;
    }
    while ( v11 != -2 );
    if ( !v24 )
      return v22;
  }
LABEL_11:
  if ( *v4 != -2 )
    v13 = *(_DWORD *)&v6[*v4] ^ (unsigned int)&v6[v4[1]];
  v14 = *(_DWORD *)&v6[v4[2]] ^ (unsigned int)&v6[v4[3]];
  return v22;
}

IMG

機能を入力し、例外フィルタ機能403AD2として実行し続けます

IMG

何の異常フィルタを発見した、ダウンし続けています。403AE9 _EH4_TransferToHandlerを実行するには、関数を入力

IMG

例外ハンドラを起動します。4015F6にジャンプの後に、バイパス401611ジャンプここで見出され、それはより多くの[EBP-0x88]が1から出発し、1であるが、例外は、デバッガハンドルをエラーの解除を無視しない場合[ebp- 0x88]はので、ここでStrongODにはいくつかの例外をスキップ開いて、珍しいアンチデバッグにする必要があり、0にコピーされます。またはオプションのデバッグ例外を無視。
ここに画像を挿入説明

以降、一見アンチデバッグ機能4012E0を行いました

.text:004012E0                 sldt    eax ;将局部描述符存入eax中
.text:004012E3                 retn

LDTにはアンチデバッグがない場合は0が0であるが、ここでは、とやEAXをデバッグすることなく、テストそれがゼロであるかどうかを検出します。

IMG

テストコード:

#include<stdio.h>
#include<windows.h>

int main()
{
    int a = 1;
    
    
        _asm
        {
            sldt eax;
            mov a, eax;

        }
        printf("%d", a);
    
    system("pause")
        ;
}

コンパイル(復号化機能)の期間を入力しないように、あなたはジャンプを修正することができわざと最後の場所

IMG

次の復号化機能を使用すると、フラグを参照することができ、機能を実行します。

IMG

おすすめ

転載: www.cnblogs.com/playmak3r/p/12088889.html