[BUUCTF] REVERSE- [Wangding Cup2020ブルードラゴングループ] singal

【ワンディングカップ2020ブルードラゴングループ】singal

別館

ステップ

  1. 定期検査、32ビットプログラム、シェルなし
    ここに画像の説明を挿入します
  2. プログラムをローカルで試す
    ここに画像の説明を挿入します
  3. 32ビットidaがロードされます。まず、メイン関数を見つけてフラグ文字列のスタイルを決定します。フラグ{……}
    ここに画像の説明を挿入します
    入力ポイントのプロンプト文字列に従って、対応する関数を見つけ、文字列の長さを確認します。 15された
    ここに画像の説明を挿入します
    機能を右クリックして、コールにこの機能の場所を見つけることはvm_operad()関数になる。vm_operadのパラメータV4は上段でqmemcpy関数を呼び出すことを知っている主な機能を見てください。Baiduはそのqmemcpyを語ります=逆方向のmemcpyは、C言語のmemcpyのコピー機能です。、unk_403040のデータの0x1C8バイトをv4にコピーします
    。unk_403040このアドレスには大量のデータがあります。コピー0x1C8が0x403208に
    ここに画像の説明を挿入します
    選択さ、shift + eが配列に変換されます。
    ここに画像の説明を挿入します
    4つのバイトがintに等しい、interlプロセッサは、リトルエンディアンストレージ、A1アレイのちょうど値は3つの00S前進数である。それを整理するために
    v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1]
    リトルエンディアン順に注意を払うときに32 -ビットプログラムが格納されています。順序を逆にしません。メモリ内の処理を探しましょう。その時点でのいくつかのデータ

次に、配列を呼び出し、114vm_operad関数を入力します

int __cdecl vm_operad(int *a1, int _114)
{
  int result; // eax
  char Str[200]; // [esp+13h] [ebp-E5h] BYREF
  char v4; // [esp+DBh] [ebp-1Dh]
  int v5; // [esp+DCh] [ebp-1Ch]
  int v6; // [esp+E0h] [ebp-18h]
  int v7; // [esp+E4h] [ebp-14h]
  int v8; // [esp+E8h] [ebp-10h]
  int v9; // [esp+ECh] [ebp-Ch]

  v9 = 0;
  v8 = 0;
  v7 = 0;
  v6 = 0;
  v5 = 0;
  while ( 1 )
  {
    result = v9;
    if ( v9 >= _114 )
      return result;
    switch ( a1[v9] )
    {
      case 1:
        Str[v6 + 100] = v4;
        ++v9;
        ++v6;
        ++v8;
        break;
      case 2:
        v4 = a1[v9 + 1] + Str[v8];
        v9 += 2;
        break;
      case 3:
        v4 = Str[v8] - LOBYTE(a1[v9 + 1]);
        v9 += 2;
        break;
      case 4:
        v4 = a1[v9 + 1] ^ Str[v8];
        v9 += 2;
        break;
      case 5:
        v4 = a1[v9 + 1] * Str[v8];
        v9 += 2;
        break;
      case 6:
        ++v9;
        break;
      case 7:
        if ( Str[v7 + 100] != a1[v9 + 1] )
        {
          printf("what a shame...");
          exit(0);
        }
        ++v7;
        v9 += 2;
        break;
      case 8:
        Str[v5] = v4;
        ++v9;
        ++v5;
        break;
      case 10:
        read(Str);
        ++v9;
        break;
      case 11:
        v4 = Str[v8] - 1;
        ++v9;
        break;
      case 12:
        v4 = Str[v8] + 1;
        ++v9;
        break;
      default:
        continue;
    }
  }
}

値が7に等しい場合、str配列の値はa1配列の次のビットと比較され、エラーを待たずに等式が続行されます。7の後の数字は、暗号化後に正しい入力と比較する必要がある値です。7の値だけがa1配列の最後にあり、この値の文字列を抽出します。

str=[]
a1=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(a1)):
          if a1[i]==7:
                    str.append(a1[i+1])

print(a1)

ここに画像の説明を挿入します
str = [34、63、52、50、114、51、24、167、49、241、40、132、193、30、122]
次に、スイッチの他のケースオプションは、str配列に対する操作であり、最終的に次のようになります。 strの値、解くための逆アルゴリズム

LOBYTEという機能が入っています。やってみると百度に行って、一番右だと言う人もいれば、右の4桁と言う人もいました。統一された声明はありません。他のマスターのwpを見つけました。これはidaの機能だと言ったので、この機能は無視してください。raxは64ビットレジスタ、eaxは32ビットレジスタ、axは16ビットレジスタ、alはaxレジスタの下位8ビット、ahはaxレジスタの上位8ビットです。
ここに画像の説明を挿入します

a1=[]
v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(v4)):
          if v4[i]==7:
                    a1.append(v4[i+1])
#print(a1)

a1 = [34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
a1.reverse()
v4.reverse()

v9 = 0
us = 0
v5 = 0
flag = []
for i in range(0, len(v4)):
    if i == len(v4) - 1:
        flag.append(us)

    if v4[i] == 1 and v4[i - 1] != 1:
        v5 = a1[v9]
        v9 += 1
        flag.append(us)

    if v4[i] == 2:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 - v4[i - 1]
            # print(us,v5,a[i-1])

    if v4[i] == 3:
        if (v4[i + 1] != 2 and v4[i + 1] != 4 and v4[i + 1] != 5):
            us = v5 + v4[i - 1]  # LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略

    if v4[i] == 4:
        if (v4[i + 1] != 3 and v4[i + 1] != 2 and v4[i + 1] != 5):
            us = v5 ^ v4[i - 1]

    if v4[i] == 5:
        if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 2):
            us = int(v5 / v4[i - 1])
    if v4[i] == 8:
        v5 = us

    if v4[i] == 11:
        us = v5 + 1

    if v4[i] == 12:
        us = v5 - 1
        # print("12:",us)

flag.reverse()
out = ''
for j in flag:
    out += chr(j)
print("flag{" + out + "}")

フラグ{757515121f3d478}

おすすめ

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