2021. Niu TurnstheWorld。CTFOpenBeta-REVESE-wp

まず、赤いゲストトレーニングキャンプを吐き出しましょう。質問のpwnはありません。私はReverseしか試すことができません。

CrackMe

  1. 定期検査、シェルなし、32ビットプログラム
    ここに画像の説明を挿入します
  2. プログラムを実行して、一般的な状況を確認します
    ここに画像の説明を挿入します
  3. 32ビットidaを開き、文字列FALSEを取得してキー関数を見つけたいのですが、文字列ウィンドウで見つからないようです。rdataセクション(リソースデータセクション、によって使用されるすべてのリソースデータ)に移動します。プログラムはここにあります)およびデータセクション(このセクションはプログラムのグローバルデータ、グローバル定数などを格納します)それを探し、最後にrdataセクション
    ここに画像の説明を挿入します
    ctrl + xで「FALSE」を見つけて、それを参照する関数を見つけます
int __thiscall sub_401730(CWnd *this)
{
    
    
  int v2; // edi
  HMODULE v3; // eax
  int v4; // edx
  struct CWnd *v5; // eax
  int v6; // esi
  int i; // eax
  int v8; // eax
  CWnd *v9; // eax
  char v11[4]; // [esp+10h] [ebp-1D0h] BYREF
  int v12; // [esp+14h] [ebp-1CCh]
  int v13; // [esp+18h] [ebp-1C8h]
  int v14; // [esp+1Ch] [ebp-1C4h] BYREF
  int v15; // [esp+20h] [ebp-1C0h]
  char v16[396]; // [esp+24h] [ebp-1BCh] BYREF
  int v17[8]; // [esp+1B0h] [ebp-30h]
  int v18; // [esp+1DCh] [ebp-4h]

  v17[0] = 0xE;       #初始化的数据
  v17[1] = 0x28;
  v17[2] = 0xC;
  v17[3] = 0x39;
  v17[4] = 6;
  v17[5] = 5;
  v17[6] = 0x20;
  v17[7] = 0x1F;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
  v2 = 0;
  v18 = 0;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  LOBYTE(v18) = 1;
  v3 = GetModuleHandleW(0);
  v4 = *((unsigned __int8 *)v3 + 1);
  v12 = *(_BYTE *)v3;
  v13 = v4;
  CWnd::UpdateData(this, 1);
  v5 = CWnd::GetDlgItem(this, 1000);
  CWnd::GetWindowTextW(v5);
  v6 = *(_DWORD *)(v14 - 12);
  v15 = 0;
  memset(v16, 0, sizeof(v16));
  if ( v6 > 0 )
  {
    
    
    do
    {
    
    
      *(&v15 + v2) = (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v14, v2);
      ++v2;
    }
    while ( v2 < v6 );
  }
  for ( i = 0; i < v6; ++i )
  {
    
    
    if ( (i & 1) != 0 )
      *(&v15 + i) ^= v13;
    else
      *(&v15 + i) ^= v12;
  }
  v8 = 0;
  if ( v6 <= 0 )
    goto LABEL_14;
  do
  {
    
    
    if ( *(&v15 + v8) != v17[v8] )
      break;
    ++v8;
  }
  while ( v8 < v6 );
  if ( v8 == 8 && v6 == 8 )
  {
    
    
    MessageBoxW(0, L"TRUE", &Caption, 0);
  }
  else
  {
    
    
LABEL_14:
    MessageBoxW(0, L"FALSE", &word_4037A8, 0);
    ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator=(&v14, &unk_4037C0);
    v9 = CWnd::GetDlgItem(this, 1000);
    CWnd::SetWindowTextW(v9);
  }
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  return ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
}

おそらく、最初にデータの一部を初期化し、i&1を計算し、v13およびv12でXOR演算を実行するのがずれていることがわかったため、この質問の主なロジックは、入力データのずれに対してXOR演算を実行することですv13とv12を使用して、最後に初期化された配列を取得します。初期化された配列がv13およびv12とXORされている限り、正しい入力値
ここに画像の説明を挿入します
v13およびv12ここから取得できます。

v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;

Baidu百科事典によるGetModuleHandleW(0)関数の説明は、文字通りの意味からはあまり明確ではありません。そのときはここで立ち往生していました。odで長時間デバッグした
ここに画像の説明を挿入します
後、v13とv12の値が見つかりませんでした。ゲーム後、idaでデバッグします。初期化配列の長さによると8なので、入力したデータの長さも8です。変更するときは、長さ8の文字列を入力するだけで
、値見つけることができます。割り当てステートメントは主にここにあります。 。ローカルウィンドウでv12とv13を見つけ、v12を
ここに画像の説明を挿入します
ここに画像の説明を挿入します
取得しました。v13の値を指定すると、正しい登録コードを計算するスクリプトを記述できます。

a=[0x0e,0x28,0x0c,0x39,6,5,0x20,0x1f]

v12=0x4d
v13=0x5a

string=""

for i in range(8):
    if (i&1)!=0:
        string+=chr(a[i]^v13)
    else:
        string+=chr(a[i]^v12)

print(string)

ここに画像の説明を挿入します
ここに画像の説明を挿入します
組み立てに慣れていないので、od、idaよりも使いやすいからです。

アンチデバッグ

  1. 定期検査、32ビットプログラム、シェルなし
    ここに画像の説明を挿入します
  2. プログラムを実行して、一般的な状況を確認します
    ここに画像の説明を挿入します
  3. これはダイアログボックスの入力であるため、最初にResource Hackerを使用して入力ボックスの位置を見つけ、キーのコントロールIDが
    ここに画像の説明を挿入します
    ida alt + iで1000であることを確認し、検索即時ボックスを表示して、1000を検索します。そして、するためにダブルクリックして
    ここに画像の説明を挿入します
    呼び出し場所を見つける
    ここに画像の説明を挿入します
    。キー機能で、同じ位置にJZとJNZジャンプは最初のIDAの正常な動作に影響を与える花の指示があることが疑われていることが判明したNOP(キーパス。 - >範囲を埋める、pathcはnop)
    ここに画像の説明を挿入します
    ジャンプ先のlocal_401524をドロップし、注意を払う00401524はマルチバイト命令です。最初にショートカットキーdを使用してデータに変換し、次にオフにしてから、ショートカットキーcをに変換します。コード
    変更後
    ここに画像の説明を挿入します
    、関数の開始位置push ebpを見つけ、関数の作成を右クリックすると、f5疑似コード
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します
    ロジックが単純であることがわかります。
    ここに画像の説明を挿入します
    この問題を修正するように求められたときに値が2,882,395,322入力に等しい場合、調査する必要があります使うための指示

おすすめ

転載: blog.csdn.net/mcmuyanga/article/details/113745699