看板 C_and_CPP 關於我們 聯絡資訊
遇到的問題(Question): 我要先誠實的說,這是作業文 我自己的作業文 但是題目我看了兩天了,只處理解決了一部分的問題 所以想請大家給我一點意見或是提示 (題目: http://isis.poly.edu/courses/cs392-f2010/labs/HW6.pdf ) 餵入的資料(Input): 餵入一串字元 希望的正確結果(Expected Output): 如果輸入的字元少於24個沒事,超過24個要避免overflow 只能印出 x is 0 不能印出 x is 1 跑出來的錯誤結果(Wrong Output): 我解決了overflow的部分 但是還是會印出x is 1 開發平台(Platform): (例: VC++, Gcc, OpenGL, Linux, ...) win7 64bit + code::blocks + GCC 程式碼(Code): (請善用置底文標色功能) #include <stdio.h> #include <stdlib.h> //BEGIN:A program to illustrate buffer overflow //vulnerability void func(char *str) { char buffer[24]; int *ret; //strcpy(buffer,str); <--原來程式用的函式 /**以下我是我改的部分**/ int temp; temp = sizeof(buffer) - 1; //printf("%d\n",temp); strncpy(buffer,str,temp); //<--避免overflow的函式 buffer[23]='\0'; puts(buffer); ret = buffer + 12; //<--改了沒用,不知道為什麼這樣用,from網路 (*ret) += 8; //<--why is it 8?? 用來改pointer,似乎沒用 /************************/ } int main(int argc, char **argv) { int x; x = 0; func(argv[1]); x = 1; printf("x is 1\n"); printf("x is 0\n"); } //END 補充說明(Supplement): 題目有兩個部分 第一題小題是如果可以修改原始碼 那要怎麼避免overflow 第二小題則是不能修改原始碼 只能執行他 那要怎麼避免overflow 我覺得最讓我不知道怎麼處理的部分是 執行完func這個function之後 回到main裡面 要跳過 x = 1; 和 printf("x is 1\n"); 在執行程式的過程中我們可以直接去抓instruction的address嗎? 然後我們可以直接修改這個address?? 所以執行完func之後可以直接跳回main的printf("x is 0\n"); ?? 我目前只想出第一小題的overflow怎麼解決 第2小題還沒想 請大家給我一點意見和提示 謝謝大家 -- 我不是宅 我只是比較居家 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 108.6.66.40
wawi:可以修改function的回傳值型態嗎? 12/08 11:43
wawi:沒事 別管我 12/08 11:46
akasan:快去看第五戒 12/08 12:35
joefaq:先把stdout導出讓他印完之後再自己印? 12/08 13:12
ledia:你就在 func 裡面, 從 buffer 之前往前印值 12/08 14:36
ledia:看看哪個是 stack 上的 return stack pointer 12/08 14:36
ledia:看不出來的話可以多 call func 幾次 12/08 14:36
ledia:知道 offset 之後再去改 12/08 14:37
loveflames:ret=buffer+12這行錯了,因為還是在buffer裡面 12/08 14:50
loveflames:第二小題在linux下倒是有很簡單的做法,用LD_PRELOAD 12/08 14:52
loveflames:用64bit要加16而不是加8,不過不是你那種做法就是了 12/08 14:56
ledia:我想第二題應該是想要用 buffer overrun 塞爛 stack 作答 12/08 14:56
ledia:LD_PRELOAD 又是另一種邪惡的東西了 XD 12/08 14:57
loveflames:用buffer當基準點也是很冒險的,因為不能保證緊鄰frame 12/08 15:00
loveflames:pointer 12/08 15:00
rock1985:這次作業我真的完全沒有頭緒,資料也都是上網查的 12/08 15:01
rock1985:真的想不到所以才來發文問問看 12/08 15:02
loveflames:parameter--ret addr--frame pointer--local var 12/08 15:07
loveflames:左邊是高位址,右邊是低位址,compiler可能會在fp跟 12/08 15:08
rock1985:印出來東西之後 怎麼判斷是不是return stack pointer? 12/08 15:09
rock1985:又來如何修改那個pointer呢?? 12/08 15:09
loveflames:local之間塞東西,local var擺放順序視complier的參數 12/08 15:10
ledia:如果你 call func 好幾次, 每次會加一定值的, 就有可能是 12/08 15:10
loveflames:而定,你首先要做的是確定buffer跟ret addr的相對位址 12/08 15:11
ledia:因為如果 call 好幾次, 每次 return value 都會到下個指令 12/08 15:11
loveflames:原po得學學debugger怎麼用 12/08 15:11
ledia:這時候把 ret 移到跳動的那個, 幫他加一個 inst 的長度 12/08 15:12
我的確不太會debug 所以我才想要學 不管這是不是作業 如果是我在網路上找到這些資料 我也會想知道要怎麼解決 很感謝大家的回答,雖然我還是不知道怎麼用 XD 話說我的code::blocks不讓我debugger 真囧 改ret真的是改到return 的 address嗎?? 還是覺得很奇怪 ※ 編輯: rock1985 來自: 108.6.66.40 (12/08 15:33)
loveflames:你可以用ollydbg,界面很簡單 12/08 15:34
loveflames:如果ret有正確指到ret addr就能改 12/08 15:35
rock1985:gdb.exe 現在抓得到嗎?? 我好像沒有這個檔案 12/08 15:56
rock1985:還是要自己抓東西回來生成?? 12/08 15:57
james732:code::blocks裝好應該就會有gdb可以用了吧? 12/08 15:58
tropical72:printf("x is 1"); exit(1); XD 12/08 16:12
rock1985:我的code::blocks 沒辦法 debugger一整個怪 = =a 12/08 22:32
loveflames:ollydbg呢 12/08 22:35
rock1985:ollydbg可以用,不過看不太懂他列出來的東西 12/09 03:21
rock1985:我大概有個底知道要怎麼處理 12/09 03:52
rock1985:但是對於stack的分析還是有點陌生,可以再給我一點提示嗎 12/09 03:52
我現在用debug去看 一些東西的記憶體位置 但是還不知道要怎麼看return address是存在stack的哪個位置 #include <stdio.h> #include <stdlib.h> //BEGIN:A program to illustrate buffer overflow //vulnerability void func(char *str) { char buffer[24]; int *ret; char *tmp; //strcpy(buffer,str); /**以下我是我改的部分**/ int temp; temp = sizeof(buffer) - 1; //printf("%d\n",temp); //ret = buffer; strncpy(buffer,str,temp); buffer[23]='\0'; puts(buffer); tmp=buffer; printf("%p: %c (0x%x)\n", tmp, *tmp, *(unsigned int *)tmp); while(tmp<buffer+23) { printf("%p: %c (0x%x)\n", tmp, *tmp, *(unsigned int *)tmp); tmp++; } /***********************/ } int main(int argc, char **argv) { int x; x = 0; //func(argv[1]); func("123456789876543212345678987654321"); x = 1; printf("x is 1\n"); printf("x is 0\n"); } //END 這是我現在測試用的程式碼 http://0rz.tw/st47M 圖是我跑debug的情況,請大家再多給我一點提示 我大概知道要怎麼處理 請大家在跟我說一下怎麼處理或是去抓stack的狀態 謝謝 ※ 編輯: rock1985 來自: 128.238.241.120 (12/09 05:01) ※ 編輯: rock1985 來自: 128.238.241.120 (12/09 05:32)