実行中のプログラムにビットフリップエラーを挿入したいと思います。これを行うには、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
%ebp
eax
追加情報...
過酷な環境で動作する安全性が重要なシステムでは、システムは単一エラーロールオーバー(たとえば、単一エラーロールオーバー)などのソフトエラーに対してより脆弱です。南東大学)少し反転したようなものです。これに関連して、研究者はこれらのエラーを検出し、システムの信頼性を維持するためのさまざまな技術、すなわちフォールトトレランス技術を開発しました。これらの技術を評価するための最も効果的なアプローチはエラー注入です。実行時には、アーキテクチャの最も重要な部分にエラーを挿入し、強化されたシステムを監視して使用するフォールトトレランス技術のエラー適用範囲を評価する必要があります。通常、ソフトエラーをシミュレートするには欠陥注入を使用する必要があります。私は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
値eip
は0x804af34。したがって、ビット演算を行うと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