0

私は学校のバイナリ爆弾に取り組んできましたが、フェーズ 5 で完全に失われました。課題の目的は、コードを分解して文字列を見つけることです。これは「チラシ」であることがわかり、それをリバース エンジニアリングして、 「フライヤー」と同じ数値です。しかし、これを行う方法を見つけるために過去 3 ~ 4 時間を費やしましたか? 答える必要はありませんが、私が何をする必要があるかを理解するのを手伝ってください。gdb を使用して逆アセンブルされたコードは次のとおりです。

Dump of assembler code for function phase_5:
0x08048d88 <+0>:    push   %ebx
0x08048d89 <+1>:    sub    $0x28,%esp
0x08048d8c <+4>:    mov    0x30(%esp),%ebx
0x08048d90 <+8>:    mov    %gs:0x14,%eax
0x08048d96 <+14>:    mov    %eax,0x1c(%esp)
0x08048d9a <+18>:    xor    %eax,%eax
0x08048d9c <+20>:    mov    %ebx,(%esp)
0x08048d9f <+23>:    call   0x804902b <string_length>
0x08048da4 <+28>:    cmp    $0x6,%eax
0x08048da7 <+31>:    je     0x8048dae <phase_5+38>
0x08048da9 <+33>:    call   0x804934c <explode_bomb>
0x08048dae <+38>:    mov    $0x0,%eax
0x08048db3 <+43>:    movsbl (%ebx,%eax,1),%edx
0x08048db7 <+47>:    and    $0xf,%edx
0x08048dba <+50>:    movzbl 0x804a4b8(%edx),%edx
0x08048dc1 <+57>:    mov    %dl,0x15(%esp,%eax,1)
0x08048dc5 <+61>:    add    $0x1,%eax
0x08048dc8 <+64>:    cmp    $0x6,%eax
0x08048dcb <+67>:    jne    0x8048db3 <phase_5+43>
0x08048dcd <+69>:    movb   $0x0,0x1b(%esp)
0x08048dd2 <+74>:    movl   $0x804a48e,0x4(%esp)
0x08048dda <+82>:    lea    0x15(%esp),%eax
0x08048dde <+86>:    mov    %eax,(%esp)
0x08048de1 <+89>:    call   0x8049044 <strings_not_equal>
0x08048de6 <+94>:    test   %eax,%eax
0x08048de8 <+96>:    je     0x8048def <phase_5+103>
0x08048dea <+98>:    call   0x804934c <explode_bomb>
0x08048def <+103>:    mov    0x1c(%esp),%eax
0x08048df3 <+107>:    xor    %gs:0x14,%eax
0x08048dfa <+114>:    je     0x8048e05 <phase_5+125>
0x08048dfc <+116>:    lea    0x0(%esi,%eiz,1),%esi
0x08048e00 <+120>:    call   0x8048810 <__stack_chk_fail@plt>
0x08048e05 <+125>:    add    $0x28,%esp
0x08048e08 <+128>:    pop    %ebx
0x08048e09 <+129>:    ret    
End of assembler dump.
4

1 に答える 1

2

何が正しいかははっきりしていませんflyersが、これは 1 つの正しい入力であり、他の入力を見つける必要があると思います。

重要な部分は<+47><+50>です。16 バイトのルックアップ テーブルを使用して入力文字列を変換しています。コードは基本的にやっています:

for(int i = 0; i != 6; i += 1) output[i] = table[input[i] & 0xf];

下位 4 ビットを共有するすべての文字が同じ出力を生成することは明らかです (ルックアップ テーブルの値が一意であっても)。たとえば、最初の文字fは ASCII コード 0x66 を持っているため、テーブル エントリ 0x06 によってマップされます。同じことが、(0x26)、(0x36)、(0x46)、(0x56)、(0x76) など、下位 4 ビットとして 0x06 を持つすべての文字に&適用6FVますv。それらのいずれかに置き換えることができますf(簡潔にするために、印刷不可能で完全な8ビット値は省略されています)。他の文字についても同様に等価性を求めることができます。

flyers代わりに が必要な出力である場合は、アドレスのルックアップ テーブルの内容を調べ0x804a4b8て、予想される出力にマップされる正しい文字を含む入力文字列を提供する必要があります。

于 2013-02-01T17:08:43.777 に答える