2017-08-01 35 views
0

考慮下面的C碼(x86_64的)將空程序參數向量傳遞給execve()是否合法?

#include <unistd.h> 
int main() 
{ 
    execve("/bin/ls", 0, 0); 
} 

予編譯爲gcc a.c和執行;我得到了SIGABRT錯誤

A NULL argv[0] was passed through an exec system call. 
Aborted 

下一頁上gdb下運行,起初我也得到了SIGABRT,但是我做了第二次運行和它的工作!

Starting program: /bin/ls 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 

爲什麼?


我測試了/bin/sh,發現它總是以* argv的[] = NULL工作...
我又寫了一些可執行文件(不包括所需要的任何參數)來測試,發現所有這些工作。

所以我猜只有/bin/sh或其他shell可以將* argv []設置爲NULL,其他文件(如/bin/ls)會失敗或意外行爲。

+0

閱讀[未定義行爲](https://en.wikipedia.org/wiki/Undefined_behavior)。 –

+0

閱讀https://linux.die.net/man/2/execve並查看它期望的參數。 –

+0

是的,我知道這是UB,execve()期望的是什麼參數,但有什麼方法可以找出它爲什麼工作,或者只是運氣。 我正在解決一些安全挑戰,如果我能找出它的工作原理,這對我的shellcode可能是一個很大的改進。 – poming

回答

3

execve()系統調用的手冊頁說

argvenvp陣列必須各自包括在所述陣列的端部的空指針。

如果您的程序不符合這些要求,那麼從這一點開始事情將不會如何。如果它對某些程序「起作用」,那只是運氣不好。


手冊頁還表示

按照慣例,第一這些字符串(即argv[0])應包含與正在執行的文件關聯的文件名。

該約定相當強大(由POSIX授權),所以不能這樣做的程序可以被認爲是越野車。如果你要依靠argv[0],你的main()測試它被正確調用是個好主意,所以你可以通過一個很好的錯誤消息而不是錯誤來失敗,但並不是所有的程序都會這樣做。

相關問題