Dd

使用 dd 修補二進製文件

  • January 29, 2021

我已經多次閱讀這句話(下面),最近一次是在這裡dd,並且一直對如何使用更新檔來修補任何東西感到困惑,更不用說編譯器了:

30 年前我在學校使用的 Unix 系統在 RAM 和磁碟空間方面非常有限。尤其是/usr/tmp文件系統很小,當有人試圖編譯一個大程序時,就會出現問題。當然,無論如何,學生不應該寫“大程序”。大型程序通常是從“某處”複製的原始碼。我們中的許多人復製/usr/bin/cc/home/<myname>/cc,並**用於dd修補二進製文件以使用/tmp而不是/usr/tmp**更大的 。當然,這只會讓問題變得更糟——這些副本佔用的磁碟空間在當時確實很重要,現在/tmp經常被填滿,甚至阻止其他使用者編輯他們的文件。在他們發現發生了什麼之後,系統管理員做了一個chmod go-r /bin/* /usr/bin/*它“修復”了問題,並刪除了我們所有的 C 編譯器副本。

(強調我的)

手冊頁沒有說明任何關於修補的dd內容,而且無論如何也不認為它可以重新用於執行此操作。

二進製文件真的可以打更新檔dd嗎?這有什麼歷史意義嗎?

讓我們試試看。這是一個簡單的 C 程序:

#include <stdio.h>
int main(int argc, char **argv) {
   puts("/usr/tmp");
}

我們將把它建構成test

$ cc -o test test.c

如果我們執行它,它會列印“/usr/tmp”。

讓我們找出“ /usr/tmp”在二進製文件中的位置:

$ strings -t d test | grep /usr/tmp
1460 /usr/tmp

-t d 將十進制的偏移量列印到它找到的每個字元串的文件中。

現在讓我們創建一個只有“ /tmp\0”的臨時文件:

$ printf "/tmp\x00" > tmp

所以現在我們有了二進製文件,我們知道要更改的字元串在哪裡,並且我們有一個包含替換字元串的文件。

現在我們可以使用dd

$ dd if=tmp of=test obs=1 seek=1460 conv=notrunc

tmp這從(我們的“ ”文件)讀取數據/tmp\0,將其寫入我們的二進製文件,使用 1 字節大小的輸出塊,在寫入任何內容之前跳到我們之前找到的偏移量,並且在完成後明確不截斷文件。

我們可以執行打更新檔的執行檔:

$ ./test
/tmp

程序列印出的字元串文字已更改,因此它現在包含“ /tmp\0tmp\0”,但字元串函式在看到第一個空字節後立即停止。這種修補只允許使字元串更短或相同長度,而不是更長,但它足以滿足這些目的。

所以我們不僅可以使用 來修補東西dd,而且我們剛剛完成了它。

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