プログラムをデバッグしようとしていますが、int(int i = 0; i < 10; i ++)の行に興味があり、GDBデバッガでi < 10をi < = 10に変更します。私はprintを使って変数名を変更しましたが、これをどうやって行うのですか?ありがとうございました。GDBを使用してforループ条件を変更しますか?
2
A
答えて
2
GDBデバッガでi < 10からi < = 10に変更します。
正確にはに応じて、これを行う方法はいくつかあります。
x86_64
に、バイナリが最適化せずにビルドされていると仮定します。
考える:
ここ#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++)
printf("%d\n", i);
return 0;
}
gcc -g -std=c99 t.c && gdb -q ./a.out
gdb) disas main
Dump of assembler code for function main:
0x000000000040052d <+0>: push %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x10,%rsp
0x0000000000400535 <+8>: movl $0x0,-0x4(%rbp)
0x000000000040053c <+15>: jmp 0x400556 <main+41>
0x000000000040053e <+17>: mov -0x4(%rbp),%eax
0x0000000000400541 <+20>: mov %eax,%esi
0x0000000000400543 <+22>: mov $0x4005f4,%edi
0x0000000000400548 <+27>: mov $0x0,%eax
0x000000000040054d <+32>: callq 0x400410 <[email protected]>
0x0000000000400552 <+37>: addl $0x1,-0x4(%rbp)
0x0000000000400556 <+41>: cmpl $0x9,-0x4(%rbp)
0x000000000040055a <+45>: jle 0x40053e <main+17>
0x000000000040055c <+47>: mov $0x0,%eax
0x0000000000400561 <+52>: leaveq
0x0000000000400562 <+53>: retq
End of assembler dump.
あなたはアドレス0x400556
の命令が一定9
で(場所$rbp-4
にスタックに保存されている)i
の値を比較し、値が以下である場合にジャンプして戻ることがわかります9
。
ですから、コンパイルされたコードは、それはすべきではないと言う場合でも取るべき力ジャンプを0x40055a
の命令にブレークポイントを設定し、ことができます。
(gdb) b *0x40055a if i == 10
Breakpoint 1 at 0x40055a: file t.c, line 4.
(gdb) run
Starting program: /tmp/a.out
0
1
2
3
4
5
6
7
8
9
Breakpoint 1, 0x000000000040055a in main() at t.c:4
4 for (int i = 0; i < 10; i++)
(gdb) p i
$1 = 10
(gdb) jump *0x40053e
Continuing at 0x40053e.
10
[Inferior 1 (process 22210) exited normally]
出来上がり:私たちは、印刷しました余分な価値。
別の可能なアプローチ:0x400556
の命令にブレークポイントを設定i-1
にi
の値を調整し、シングルステップ、i+1
にi
の値を調整し続けます。
さらに別のアプローチ:定数10
の代わり9
と比較する0x400556
でバイナリパッチ命令:ここ
(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 09 cmpl $0x9,-0x4(%rbp)
End of assembler dump.
あなたは一定の9
は特にバイトで、命令バイトの一部であることがわかります住所0x400559
。あなたはそのバイトを変更することができます。
(gdb) start
Starting program: /tmp/a.out
Temporary breakpoint 1, main() at t.c:4
4 for (int i = 0; i < 10; i++)
の命令を上書きし、再び分解してみましょう:
(gdb) set *(char*)0x400559 = 10
(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 0a cmpl $0xa,-0x4(%rbp)
End of assembler dump.
は良いルックス:我々は今10
代わりの9
と比較。それは動作しますか?
(gdb) c
Continuing.
0
1
2
3
4
5
6
7
8
9
10
[Inferior 1 (process 23131) exited normally]
はい、あります。
P.S.バイナリパッチのパッチ適用は、ソースを編集してバイナリを再構築するのと同じですが、次の場合にパッチが "忘れられ"ます。run
。
関連する問題
- 1. forループの開始条件を変更できますか?
- 2. Objective-Cでは、forループの条件をループ中に変更できますか?
- 3. 終了条件として変数を使用するとForループが無限ループに入ります
- 4. ロボットフレームワークを使用したforループの複数条件チェック
- 5. R - forループを使用してデータフレームの値を条件付きで変更する
- 6. サプリーまたはループを使用した繰り返しの条件変更
- 7. PHP:whileループ - 条件で変更された変数を使用
- 8. 条件を使用してSASデータセットを変更する
- 9. forループ内のパンダクエリ条件
- 10. forループ内の条件
- 11. forループ条件の規則
- 12. 条件付きForループPHP
- 13. Pythonでforループを使用して配列の要素を変更します。
- 14. forループを使用してr内のdata.frameを変更します
- 15. gridviewデータバインド後の条件を使用して列の値を変更します
- 16. JButtonで色を変更し、forループの終了条件を無限に設定します
- 17. 子要素データを使用する条件付きfilterBy for v-forループ
- 18. 特定の条件(ドット位置、ウィンドウ幅)を使用してforループをwhileループに変更するにはどうすればよいですか?
- 19. オブジェクトのリストの内容をループの条件として使用してPythonのデータフレームを変更する方法
- 20. Forループを続ける条件
- 21. forループを使用したPythonの1つのライナー条件付きリターン
- 22. Break for forループを使用して
- 23. C - whileループの条件の位置をCのセグメンテーションフォルトに変更しますか?
- 24. 条件に基づいてforループから変数を取得する
- 25. 条件を変更してimageButtonイメージを変更する
- 26. Wordpress:条件を変更してアップロードディレクトリを変更する
- 27. ForEach for forループを使用しないで変換しますか?
- 28. ループ不変条件ループ
- 29. ループを使用して同じ手順を繰り返しますが、他の条件を使用します
- 30. 条件付きのforループデクリメントを使用できますか?
gdbはコードを変更できません。読み取り専用に設定されています... –
私は同意します:実際にデバッガ(Visual Studio?)内の*コードを置き換えることを可能にするいくつかのツールがあると思いますが、gdbがこれを行うことができるかどうかは疑問です。 – GhostCat
私はレジスタを変更してジャンプ条件を反転することができますね... – arrowd