免責事項:私はUbuntu-12.04とgcc-4.8.-2とgdb-7.7.1デバッガを使用しています。
check
を入力してifにステップするまでは、デバッガでプログラムを実行しました。私は、コードを逆アセンブルし、アセンブリを見て:
(gdb) disass
Dump of assembler code for function check:
0x000000000040062d <+0>: push %rbp
0x000000000040062e <+1>: mov %rsp,%rbp
0x0000000000400631 <+4>: sub $0x10,%rsp
=> 0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp)
0x0000000000400639 <+12>: je 0x400647 <check+26>
0x000000000040063b <+14>: mov $0x400754,%edi
0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]>
0x0000000000400645 <+24>: jmp 0x400651 <check+36>
0x0000000000400647 <+26>: mov $0x400766,%edi
0x000000000040064c <+31>: callq 0x4004e0 <[email protected]>
0x0000000000400651 <+36>: leaveq
そして、私は私のレジスタ(単に重要なものを示す)の値を見て:
(gdb) info reg
rbp 0x7fffffffdf00 0x7fffffffdf00
rsp 0x7fffffffdef0 0x7fffffffdef0
rip 0x400635 0x400635 <check+8>
eflags 0x206 [ PF IF ]
次に、私が指示(gdb) ni
を踏んシングル道cmp
作品はそのSIMUであることを
(gdb) disass
Dump of assembler code for function check:
0x000000000040062d <+0>: push %rbp
0x000000000040062e <+1>: mov %rsp,%rbp
0x0000000000400631 <+4>: sub $0x10,%rsp
0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp)
=> 0x0000000000400639 <+12>: je 0x400647 <check+26>
0x000000000040063b <+14>: mov $0x400754,%edi
0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]>
0x0000000000400645 <+24>: jmp 0x400651 <check+36>
0x0000000000400647 <+26>: mov $0x400766,%edi
0x000000000040064c <+31>: callq 0x4004e0 <[email protected]>
0x0000000000400651 <+36>: leaveq
0x0000000000400652 <+37>: retq
End of assembler dump.
(gdb) info reg
eflags 0x206 [ PF IF ]
リコール:と解体とeflags
の値を取得繰り返しますje
が利用するフラグを適切に設定する減算を実行します。したがって、このコードは0から-0x4(%rpb)の減算を実行します(ゼロフラグを適切に設定します)。数字が同じ場合、jzはジャンプを行います。ゼロ・フラグは、現在設定されていることを
(gdb) set $ZF = 6
(gdb) set $eflags |= (1 << $ZF)
(gdb) print $eflags
$1 = [ PF ZF IF ]
お知らせ:
は、だから私は、コマンドシーケンスとフラグレジスタを修正しました。他のブロックである
(gdb) ni
(gdb) disass
Dump of assembler code for function check:
0x000000000040062d <+0>: push %rbp
0x000000000040062e <+1>: mov %rsp,%rbp
0x0000000000400631 <+4>: sub $0x10,%rsp
0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp)
0x0000000000400639 <+12>: je 0x400647 <check+26>
0x000000000040063b <+14>: mov $0x400754,%edi
0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]>
0x0000000000400645 <+24>: jmp 0x400651 <check+36>
=> 0x0000000000400647 <+26>: mov $0x400766,%edi
0x000000000040064c <+31>: callq 0x4004e0 <[email protected]>
0x0000000000400651 <+36>: leaveq
0x0000000000400652 <+37>: retq
End of assembler dump.
を、あなたはフラグが表示されるはずです:単一の命令セット(ni
)とは、解体を見てみましょう。 (私のテストプログラムでは、猫の旗の行をコメントアウトしたことに注意してください)。
ここで/はどのように '無効 'に設定されていますか?私はそれが 'check'関数で使われているのを見ていますが、どのように設定されているのかわかりません。 – thurizas
私はそれについては分かりません。実際に私はこの点についても混乱していました。私はこのコードを書いていません。私はこのコードを手に入れました。私はそれを実行すると、フラグの内容にアクセスできるようにパスワードを要求します。私はパスワードを知らないので、今、私はフラグにアクセスするためにパスワードを推測するためにいくつかの悪用/バックドアを見つけなければなりません。そして私はどんな悪用も見つけられないようです。 – sar
プログラムをデバッグできる場合は、比較を変更できるはずです。たとえば、invalidはローカル変数であり、スタックに格納されます。テストの前に値を変更することができます。 – thurizas