Shell-Script
我們如何使用 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
和%ebp
. 從清單中我們可以看到,當我更改eax
寄存器的內容時,沒有出現任何問題。更多資訊…
在惡劣環境下工作的安全關鍵系統中,系統更容易受到軟錯誤的影響,即像位翻轉一樣的單錯誤翻轉 ( **SEU )。**在這種情況下,研究人員開發了幾種技術來檢測此類錯誤並保持系統可靠,即容錯技術。為了評估這些技術,最有力的方法是故障注入。您應該在執行時將故障注入架構中最關鍵的部分,然後監控強化系統以評估所採用的容錯技術的故障覆蓋率。一般來說,我們應該使用故障注入來模擬軟錯誤。我很了解
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
to轉換為時int
,它可以正常工作,但我認為結果並不理想,因為我只嘗試通過將 eip 的內容與 0x1 異或來切換單個位!(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)
您應該使用
(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