Shell-Script

我們如何使用 GDB 對寄存器執行算術運算?

  • July 3, 2020

我想將位翻轉錯誤注入正在執行的程序中。為此,我使用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) 

此外,當我將voidto轉換為時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

引用自:https://unix.stackexchange.com/questions/596371