這是我編譯的C代碼:爲什麼緩衝區不會溢出這個代碼?
#include <stdio.h>
#include <stdlib.h>
int main(){
long val=0x41414141;
char buf[20];
printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
printf("Here is your chance: ");
scanf("%24s",&buf);
printf("buf: %s\n",buf);
printf("val: 0x%08x\n",val);
if(val==0xdeadbeef)
system("/bin/sh");
else {
printf("WAY OFF!!!!\n");
exit(1);
}
return 0;
}
在這裏,我期待的溢出long val
如果用戶輸入字符串24個字符長,在val
更改值。但即使字符串足夠長,它也不會溢出。有人可以解釋這種行爲嗎?
我在macOS上。這是gcc -v
吐出:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
此外,谷歌上搜索了一下後,我試着用這些標誌GCC:
gcc -g -fno-stack-protector -D_FORTIFY_SOURCE=0 -o overflow_example overflow_example.c
的是,結果是一樣的。
此代碼是narnia
對overthewire的戰爭遊戲挑戰的一部分。我設法在他們的遠程外殼上解決了這個挑戰,它的行爲和預期的一樣。現在,我試圖在我的本地系統上重現這個相同的挑戰並面臨這個問題。請幫忙。
編輯:對於UB大喊大叫的人:就像我說的,這是overthewire上要解決的挑戰之一,所以它不能有UB。有一些博客(here's on I found)爲這個挑戰提供了演練,併爲提供了合理的邏輯解釋,爲什麼代碼的行爲方式與此相同,我同意這一點。我也明白,編譯後的二進制文件是依賴於平臺的。 那麼,我該怎麼做才能生成這個在本地系統上可能溢出的二進制文件?
未定義的行爲=未定義的行爲。無法保證這些變量在內存中分配的位置。 – Lundin
@Lundin先生,請強調這兩點不是相關的。 –
您正在利用*未定義行爲*,未定義行爲的定義未定義。另外,由編譯器創建的堆棧佈局很大程度上取決於編譯器,而像這樣的破解可能無法在所有編譯器上運行。特別是如果有一些優化正在進行(這可能完全優化'val'變量)。 –