GDBを使用してレジスタで算術演算をどのように実行できますか? [閉鎖]

GDBを使用してレジスタで算術演算をどのように実行できますか? [閉鎖]

実行中のプログラムにビットフリップエラーを挿入したいと思います。これを行うには、gdbターゲットプログラムにブレークポイントを挿入し、ランダムに選択されたレジスタの単一ビットを反転します。 Ubuntuでこのコマンドを実行しようとすると、gdb次のエラーが発生します$eip

(gdb) info r
...
eip        0x804af59        0x804af59 <main+37>
...

(gdb) p/a $eip
$4 = 0x804af59 <main+37>

(gdb) set $eip = $eip ^ 0x800
argument to arithmetic operation not a number or boolean

(gdb) set $eax = $eax ^ 0x1
(gdb)

わかりません。これはGDBのバグですか?または文法的エラー。

次のレジスタを変更しようとするとエラーが発生します%eip。リストから、レジスタの内容を変更しても問題が発生しないことがわかります。%esp%ebpeax

追加情報...

過酷な環境で動作する安全性が重要なシステムでは、システムは単一エラーロールオーバー(たとえば、単一エラーロールオーバー)などのソフトエラーに対してより脆弱です。南東大学)少し反転したようなものです。これに関連して、研究者はこれらのエラーを検出し、システムの信頼性を維持するためのさまざまな技術、すなわちフォールトトレランス技術を開発しました。これらの技術を評価するための最も効果的なアプローチはエラー注入です。実行時には、アーキテクチャの最も重要な部分にエラーを挿入し、強化されたシステムを監視して使用するフォールトトレランス技術のエラー適用範囲を評価する必要があります。通常、ソフトエラーをシミュレートするには欠陥注入を使用する必要があります。私はeipレジストラの仕事が何であるか、それがプログラムの制御フローにどれほど敏感であるかを知っています。

使用されるGDBのバージョンは次のとおりです。

gdb --version
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.

gdbセッションのいくつかの出力:

(gdb) p $eip
$1 = (void (*)()) 0x804af34 <main>

(gdb) ptype $eip
type = void (*)()
(gdb) 

そしてvoidに変換するとintエラーなしでうまく動作しますが、しかし、結果は理想的ではないと思います。、eipの内容を0x1とXORして単一ビットだけをトグルしようとするからです!

(gdb) set $eip=*(int *) $eip ^ 0x1
(gdb) p $eip
$2 = (void (*)()) 0x4244c8c

eip0x804af34。したがって、ビット演算を行うと0x1、結果は次のようになります。0x804AF35いいえ0x4244c8c? !

(gdb) p $eip
$8 = (void (*)()) 0x804af34 <main>
(gdb) p *(int *) ($eip)
$9 = 69487757
(gdb) p *(int *) $eip ^0x1
$10 = 69487756
(gdb) p/a *(int *) $eip ^0x1
$11 = 0x4244c8c
(gdb) 

答え1

(int)intへの強制ポインタを使用する必要があります。今後のテストでは、次のことを行う必要があります。いいえメモリを*指すポインタを逆参照するために使用されます。$eip

(gdb) p/x (int)$eip  
$4 = 0xf7eb9810
(gdb) p/x (int)$eip^1
$5 = 0xf7eb9811
(gdb) set $eip = (int)$eip^1
(gdb) p/x (int)$eip
$6 = 0xf7eb9811
(gdb) set $eip = (int)$eip^0x800
(gdb) p/x (int)$eip
$7 = 0xf7eb9011

関連情報