我有一個 64 位 ELF 二進制檔案。我沒有它的源代碼,不知道它是用什么引數編譯的,這里不允許提供。我擁有的唯一相關資訊是源是一個 .c 檔案(因此沒有手工制作的程式集),通過 Makefile 編譯。
在使用 IDA 反轉這個二進制檔案時,我偶然發現了一個我以前從未見過并且絕對無法解釋的極其奇怪的結構。這是使用 IDA 語法對一個函式的原始反編譯:
mov rax, [rsp var_20]
xor rax, fs:28h
jnz location
add rsp, 28h
pop rbx
pop rbp
retn
location:
call __stack_chk_fail
nop dword ptr [rax]
db 2Eh
nop word ptr [rax rax 00000000h]
...then dozens of instructions of normal and functional code
在這里,我們有一個簡單的金絲雀檢查,如果有效則回傳,__stack_chk_fail否則呼叫。一切都很正常。但是在這個檢查之后,仍然有匯編和全功能代碼。
查看手冊__stack_chk_fail,我確保該函式確實退出了程式,并且沒有可以繼續的極端情況:
描述
介面 __stack_chk_fail() 應中止呼叫它的函式,并顯示已檢測到堆疊溢位的訊息。呼叫該函式的程式將退出。
我還嘗試撰寫這個小 C 程式,以尋找重現此問題的方法:
#include <stdio.h>
#include <stdlib.h>
int foo()
{
int a = 3;
printf("%d\n", a);
return 0;
int b = 7;
printf("%d\n", b);
}
int main()
{
foo();
return 0;
}
但是后面的代碼return被 gcc 簡單地省略了。
我的二進制檔案似乎也不容易受到緩沖區溢位的影響,我可以利用它rip在金絲雀檢查后控制和跳轉到代碼。我還檢查了 everycall和 jumps using objdump,而且這段代碼似乎永遠不會被呼叫。
有人可以解釋發生了什么嗎?這段代碼最初是如何生成的?這是二進制檔案作者的笑話嗎?
uj5u.com熱心網友回復:
我懷疑您正在查看填充,然后是 IDA 沒有名稱的無關函式。
為了檢驗這個假設,我需要以下附加資訊:
- 緊隨其后的位元組的地址
call __stack_chk_fail。 - 作為呼叫或跳轉指令目標的下一個更高地址。
- 這兩個地址之間的位元組的原始十六進制轉儲。
- 從作為呼叫或跳轉指令目標的下一個更高地址開始的四或五條指令的反匯編。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/427876.html
上一篇:使用讀/寫系統呼叫實作cp命令
下一篇:在c中將節點添加到鏈表的段錯誤
