電子科技大學軟件開發環境實驗報告_第1頁
電子科技大學軟件開發環境實驗報告_第2頁
電子科技大學軟件開發環境實驗報告_第3頁
電子科技大學軟件開發環境實驗報告_第4頁
電子科技大學軟件開發環境實驗報告_第5頁
已閱讀5頁,還剩59頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

電子科技大學實 驗 報 告學生姓名:郭小明 學號:試驗室名稱:主樓A2-412二、試驗工程名稱:軟件開發環境試驗-----Huffman編碼試驗三、試驗原理:分割函數的三項原則分割函數的三項原則包括:與其寫注釋,不如寫函數;重復就是罪惡;函數不要超過5070行。PPT贅述。Huffman編碼的根本原理本試驗要求使用Huffman編碼算法,實現對文件的壓縮和解壓。因此,我們首先介紹huffman的編碼算法。DavidHuffman使用次數少的代碼則可以使用較長的編碼,并且保持編碼的唯一可解性。指導書試驗原理局部較多,在這里就不做粘貼復制了。四、試驗目的:huffman生把握并敏捷運用分割函數的三項原則。五、試驗內容:exe程序。這個程序依據huffman編碼方式,同時包含了壓縮功能和解壓功能。用戶通過以下命令進展壓縮:C:\>test.exe–cuncompress_filenamecompress_filename上述命令中,test.exe是程序名,-c表示要進展壓縮。uncompress_filename是要壓縮的文是壓縮之后的文件名,同樣可以包含路徑信息。用戶可以通過如下命令進展解壓:C:\>test.exe–ucompress_filenameuncompress_filename上述命令中,-u表示要執行解壓命令。compress_filename是要解壓的文件名,可以包含路徑信息;uncompress_filename就是解壓后所得到的文件,同樣可以包含路徑信息。huffman樹或者編碼表或者詞頻表等等。test.exeCC++版本的。對這兩個版本的要求如下:及它們的文字說明等內容;20%;C++版本的程序,需要給出類關系圖。試驗報告是否標準試驗報告內容是否詳實試驗報告中是否包含了函數調用圖、流程圖、類圖以及它們的文字說明試驗報告中的代碼注釋是否到達要求程序是否正確無誤程序是否嚴格依據分函數的原則編寫C++版本的程序類關系的耦合度如何程序實現是否考慮了大文件狀況六、試驗器材〔設備、元器件〕:PC機,vs2023軟件平臺。七、試驗數據及結果分析:代碼見附件。huffmanForC文件中函數列表如下:///統計詞頻時用于查找是否已經記錄過,0intisInNode(intvalue)//NodehuffmanNode[260]的節點數組當中void calWeight(char*file)/*得到待壓縮文件的總字節數,權值為幾就代表著有多少個字節*/intgetSumBytes//獵取壓縮后文件的總bit數intgetSumBits//huffman樹依據huffman樹的特性,nhuffman2n-1個節點//n值由全局變量count值來確定,該函數主要用來初始化Huffman樹的全部節點信息void createHufmanTree(Node*huffmanTree)/*字符編碼,從構建好的Huffman樹當中讀取每個葉子節點的huffman編碼, 并將葉子節點的信息放入到code[]中*/HCode*getHuffmanCode(Node*huffmanTree,HCode*HC,intcode[])/*將編碼表寫入默認文件當中,并在結尾存入葉子節點數〔count〕與壓縮后文件的總bit數1111000 27......................#sum_bit##count#*/voidfreToFile(intcode[],HCode*HC)//由于詞頻表是依據字符串方式存儲的葉子節點信息,int值再使用intpowmy(inta,intb)/*從編碼表文件讀取相應信息以用來解壓文件,讀取信息包括編碼和葉子信息*/HCode*freFromFile(intcode[],HCode*HC)/*壓縮文件*/voidcompress_file(char*file1,char*file2)/*ASCII碼轉換為二進制數*/int swap(intdata)/*進展文件的解壓*/voiduncompress_file(char*file1,char*file2)//主函數intmain(intargc,char**argv)函數關系調用圖:輸入-cargv[2argv[3]輸入-c命令獵取argv[2]文件中的詞頻信息calWeight(argv[2])

isInNode依據詞頻信息建立Huffan樹createHufmanTree編碼getHuffmanCode getSumBytes

getSumBitscompress_file將編碼信息寫入編碼表文件,以備解壓使用freToFile輸入-uargv[2argv[3]輸入-u命令從詞頻表當中讀取編碼信息freFromFile

powmyswapuncompress_file代碼見附件。dic.txt),然后實現了解壓縮功能。試驗文件列表:file.txt為源文件,out.txt為壓縮文件,out1.txt為解壓出來的文件下面是dic.txt的局部信息,存放的依次是Huffman編碼,對應的ASCII碼壓縮后產生的文件,確實是亂碼解壓后的文件,與壓縮前的文件,大小內容完全全都。C++Controll類classControll//:publicHuffmanTree{public:voidcompress_file(constchar*,constchar*,constchar*);voiduncompress_file(constchar*,constchar*,constchar*);voidfreFromFile(constchar*,char**,char*,int*);intpowmy(int,int);};HuffmanNode類classHuffmanNode{public:charinfo; //結點信息doubleweight; //結點權值intparent,lchild,rchild;//父親結點,左右孩子結點HuffmanNode{parent=lchild=rchild=-1;}HuffmanNode(constchar&data,constdouble&wt,constint&pa=-1,constint&lch=-1,constint&rch=-1){info=data;weight=wt;parent=pa;lchild=lch;rchild=rch;}};//classHuffmanNodeendCode類/*controlll類當中使用這個類*/classCode{public:Code:length(10){ptr=newchar[length];}~Code{delete[]ptr;}char*ptr;constintlength;};HuffmanTree類classHuffmanTree{public:HuffmanTree(constint&s=100){maxSize=(s>100s:100);arrayTree=newHuffmanNode[maxSize];currentSize=0;codeArray=0;}~HuffmanTree{delete[]arrayTree;if(codeArray!=0)delete[]codeArray;}voidrun(constchar*,constchar*);intgetSumBytes;//bytes數intcurrentSize;//當前數組大小HuffmanNode*arrayTree;//哈夫曼結點數組Code*codeArray;//數組大小為currentSizeintsum_bits;//bit數private:intmaxSize;//數組最大值//intsum_bytes;voidinsert(constchar&,constdouble&);//插入結點voidcreateHuffmanTree;//創立哈夫曼樹voidcreateHuffmanCode;//創立哈夫曼編碼voidwriteCodeToFile(constchar*);//Huffman編碼寫入到詞頻表文件當中intfindPosition(constchar&)const;//arrayTree[]中的位置intisEqual(constchar*s)const;//s是否存在于編碼系統中,假設存在則返回s在編碼系統中的位置,否則返回-1voidreverse(chararr[]);};//classHuffmanTreeend類關系圖HuffmanTree類

Code類HuffmanNode類Control類C++版本的試驗過程總體類似C語言的試驗過程,截圖類似上面。壓縮文件命令:(1)首先讀取待壓縮文件,建立詞頻信息的存儲。Huffman樹。Huffman樹,生成編碼表信息。依據編碼表信息再次逐字節的的讀取帶壓縮文件并且壓縮文件。解壓命令從編碼表存儲文件當中讀出編碼信息。兩份源代碼打包一并交到了系統里面,以備教師查看!電子科技大學實 驗 報 告學生姓名:郭小明 學號:稱:主樓A2-412二、試驗工程名稱:軟件開發環境試驗二:流程掌握語句反匯編三、試驗原理:VS2023的反匯編調試和反匯編代碼規律。VisualStudio2023ifif/elsedo/while/for等類型語句的反匯編代碼,以到達把握流程掌握語句識別的目的。五、試驗器材〔設備、元器件〕:PC機,VS2023反匯編編碼調試軟件六、試驗步驟:if語句的反匯編在試驗報告中需要給出代碼清單2的解釋。2int_tmain(intargc,_TCHAR*argv[]){inti=3;if(i>3){i=4;}return0;}反匯編代碼inti=3;00DD138E mov dwordptr[ebp-8],3if(i>3)00DD1395 cmp dwordptr[ebp-8],300DD1399{jle00DD13A2i=4;00DD139Bmovdwordptr[ebp-8],4}return0;00DD13A2 xor eax,eax反匯編代碼清單2,下面進展解釋:inti=3;00DD138E mov dwordptr[ebp-8],3EBP尋址的函數中,ebp-偏移量就是局部變量的地址。inti=3。int_tmain(intargc,_TCHAR*argv[]){00DD1370 push ebp00DD1371 mov ebp,espebp壓棧,然后將現在的棧頂指針esp賦值給〔由于棧是由高到低的挨次生長的,所以此時n就可以表示p后面n字節的地址了,然后我們再定義ti=;剛好壓棧后存儲在p為了防止溢出攻擊,在p后面空出4個字節,然后再安排四個字節存放i變量,于是iebp-8int4個字節,所以就在[ebp8]dwordptr用來指明數據的字節數00DD1395 cmp dwordptr[ebp-8],3同上dwordptr[ebp8]是指明數據字節數,獵取i數據值,cmp是將i值與3進展比較,其實就是執行i-3,然后在標志存放器〔PSW----ProgramStatusWord〕的各位反響比較的結果。00DD1399 jle 00DD13A2jle〔jle,jumpiflightorequal〕的含義是第一個操作數小于或等于其次個操作數時跳(固然此時就是通過標志存放器〔PSW----ProgramStatusWord〕中的數值來推斷)。然后我們觀看跳轉地址00DD13A2 其實就是 00DD13A2 xor eax,eax 最終一句return0的代碼。i=4;00DD139B mov dwordptr[ebp-8],4這是if條件語句里面的代碼,將i值賦值為4,同理,dwordptr[ebp-8]是通過ebp-8找尋到i的地址單元,然后dr賦給這個地址〔的存放地址;return0;00DD13A2 xor eax,eax程序返回0eax清零代碼清單3int_tmain(intargc,_TCHAR*argv[]){inti=3;if(i<3){i=4;}return0;}下面是代碼清單3的反匯編代碼和解釋。inti=3;0122138E mov dwordptr[ebp-8],3if(i<3)01221395 cmp dwordptr[ebp-8],301221399 jge 012213A2{i=4;0122139B mov dwordptr[ebp-8],4}return0;012213A2 xor eax,eaxinti=3;0122138E mov dwordptr[ebp-8],3定義一個int型的變量i,賦值為3,[ebp-8] ebp-8是i變量地址,[ebp-8]是i變量,dwordptr是指明該地址數據由4字節構成,然后通過mov指令將3賦值給i。if(i<3)01221395 cmp dwordptr[ebp-8],3dr-數據值-8是變量的地址-]是變量是將值與3進展比較,其實就是執行i-3,然后在標志存放器〔PSW----ProgramStatusWord〕的各位反響比較的結果。01221399 jge 012213A2通過與代碼清單2的比較我們可以得出,jge〔jge,jumpifgreaterorequal〕是當第一個操作數大于或者等于其次個操作數的時候進展跳轉。且跳轉地址就是return0代碼的地址。i=4;0122139B mov dwordptr[ebp-8],4這是if條件語句里面的代碼,將i值賦值為4,同理,dwordptr[ebp-8]是通過ebp-8找尋到i的地址單元,然后dr賦給這個地址〔的存放地址;012213A2 xor eax,eax程序返回0eax清零代碼清單4int_tmain(intargc,_TCHAR*argv[]){inti=3;if(i==3){i=4;}return0;}下面是代碼清單4的反匯編代碼及解釋inti=3;002B138E mov dwordptr[ebp-8],3if(i==3)002B1395002B1399{cmpjnedwordptr[ebp-8],3002B13A2i=4;002B139Bmovdwordptr[ebp-8],4}return0;002B13A2 xor eax,eax}inti=3;002B138E mov dwordptr[ebp-8],3定義一個int型的變量i,賦值為3,[ebp-8] ebp-8是i變量地址,[ebp-8]是i變量,dwordptr是指明該地址數據由4字節構成,然后通過mov指令將3賦值給i。if(i==3)002B1395 cmp dwordptr[ebp-8],3dr-數據值-8是變量的地址-]是變量是將值與3進展比較,其實就是執行i-3,然后在標志存放器〔PSWProgramStatusWord〕的各位反響比較的結果。002B1399 jne 002B13A2通過與代碼清單2的比較我們可以得出,jne〔jne,jumpifnotequal〕是當第一個操作數不等于其次個操作數的時候進展跳轉。且跳轉地址就是return0代碼的地址。i=4;002B139B mov dwordptr[ebp-8],4這是if條件語句里面的代碼,將i值賦值為4,同理,dwordptr[ebp-8]是通過ebp-8找尋到i的地址單元,然后dr賦給這個地址〔的存放地址;002B13A2 xor eax,eax程序返回0eax清零試驗有要求:另外,還可以自行試驗<=、>=時的狀況。在試驗報告中,給出這些狀況的反匯編代碼及解釋。最終,在試驗報告中,總結出條件推斷語句的反匯編代碼規章。下面是在>=狀況下的反匯編代碼:inti=3;00CF138E mov dwordptr[ebp-8],3//if(i==3)if(i>=3)00CF1395 cmp dwordptr[ebp-8],300CF1399 jl 00CF13A2{i=4;00CF139B mov dwordptr[ebp-8],4}return0;00CF13A2 xor eax,eax*********************************************下面只是解釋這句不同的代碼:00CF1399 jl 00CF13A2通過與代碼清單2的比較我們可以得出,jl〔jne,jumpifless〕是當第一個操作數小于其次個操作數的時候進展跳轉。且跳轉地址就是return0代碼的地址。下面是<=代碼的反匯編代碼:inti=3;008C138E mov dwordptr[ebp-8],3//if(i==3)if(i<=3)008C1395008C1399{cmpjgdwordptr[ebp-8],3008C13A2i=4;008C139Bmovdwordptr[ebp-8],4}return0;008C13A2 xor eax,eax008C1399 jg 008C13A2通過與代碼清單2的比較我們可以得出,jg〔jne,jumpifgreater〕是當第一個操作數大于其次個操作數的時候進展跳轉。且跳轉地址就是return0代碼的地址。條件推斷語句的反匯編代碼規章:由兩條匯編指令構成:cmp操作數1 操作數2和jXX 地址cmp用于條件推斷比較Jxx用于在不符合推斷的狀況下跳轉到后面的代碼處jg〔jne,jumpifgreater〕jl〔jne,jumpifless〕jne〔jne,jumpifnotequal〕jge〔jge,jumpifgreaterorequal〕jle〔jle,jumpiflightorequal〕if/else語句的反匯編5int_tmain(intargc,_TCHAR*argv[]){inti=3;if(i<3){i=4;}else{i=5;}return0;}代碼清單5的反匯編結果代碼清單6:inti=3;00F9138E mov dwordptr[ebp-8],3if(i<3)00F91395 cmp dwordptr[ebp-8],300F91399 jge 00F913A4{i=4;00F9139B mov dwordptr[ebp-8],4}else00F913A2 jmp 00F913AB{i=5;00F913A4 mov dwordptr[ebp-8],5}return0;00F913AB xor eax,eax}由于一些相類似的反匯編指令已經在前面做了詳盡的解釋,下面重點對if else 代碼的反匯編進展解釋:if(i<3)00F91395cmp dwordptr[ebp-8],3將i與3進展比較,轉變相應的標志存放器位。00F91399jge 00F913A4假設第一個操作數大于或者等于其次個操作數就跳轉到00F913A4這個位置去執行指令代碼,這個位置{i=5;00F913A4 mov dwordptr[ebp-8],5}是else 里面的內容,執行完畢之后就return0;00F913AB xor eax,eax返回0,eax清零假設沒有進展跳轉的話〔第一個操作數大于其次個操作數〕挨次執行下面的代碼:{i=4;00F9139B mov dwordptr[ebp-8],4}else00F913A2 jmp 00F913AB執行到else下面的代碼之后就跳轉到了 00F913AB 這個位置,而這個地址的指令代碼是return0;00F913AB xor eax,eax返回0,eax清零。以上反匯編指令剛好和我們的規律是一樣的。if-else構成的多分支流程的反匯編代碼的規律:cmp操作數1 操作數2jxx else里面的反匯編代碼地址 ;假設不符合條件則跳轉{If條件語句里的反匯編代碼}elsejmp 下面一個大括號后的反匯編代碼地址{else條件語句里面的反匯編代碼}7int_tmain(intargc,_TCHAR*argv[]){inti=3;if(i>30){i=4;}elseif(i>=20){i=5;}elseif(i<=5){i=6;}elseif(i<10){i=7;}elseif(i==12){i=8;}else{i=9;}return0;}代碼清單7的反匯編結果:inti=3;00E9138E mov dwordptr[ebp-8],3 //定義變量i=3if(i>30)00E91395 cmp dwordptr[ebp-8],1Eh //對i和30這個兩個操作數進展比較00E91399 jle 00E913A4 //假設操作數1小于等于操作數2,跳轉,//且地址為大括號后面指令代碼地址{i=4;00E9139Bmovdwordptr[ebp-8],4//假設符合if條件,執行賦值語句00E913A2}jmp00E913E7//執行完畢后直接跳到返回語句處elseif(i>=20)00E913A4 cmp dwordptr[ebp-8],14h //假設前一個條件推斷為假,則跳至此處//與20再推斷00E913A8 jl 00E913B3{i=5;

//假設不符合此處的if條件語句則跳轉//到下一個if條件處00E913AA mov dwordptr[ebp-8],5 //假設符合前一個if條件,執行賦值語句00E913B1 jmp 00E913E7 //執行完畢后直接跳到返回語句處}elseif(i<=5)00E913B3 cmp dwordptr[ebp-8],5 //假設前一個條件推斷為假,則跳至此處//與5再比較推斷00E913B7 jg 00E913C2 //假設不符合此處的if條件則跳轉到//下一個if條件處 以下類似,不做//重復解釋{i=6;00E913B9 mov dwordptr[ebp-8],600E913C0 jmp 00E913E7}elseif(i<10)00E913C2 cmp dwordptr[ebp-8],0Ah00E913C6 jge 00E913D1{i=7;00E913C8movdwordptr[ebp-8],700E913CFjmp00E913E7}elseif(i==12) //此時到達了最終一個if條件判//斷處,依據上面if-else的匯編//解釋執行00E913D1 cmp dwordptr[ebp-8],0Ch00E913D5 jne 00E913E0{i=8;00E913D7 mov dwordptr[ebp-8],8}else00E913DE jmp 00E913E7{i=9;00E913E0 mov dwordptr[ebp-8],9}return0;00E913E7 xor eax,eax}if-else構成的多分支流程的反匯編代碼的規律。:代碼形式為if( )cmp12jxx 地址〔ifif條件處再進展比較〕{................................jmp 整個多分支流程語句后的指令地址}elseif( )cmp12jxx 地址〔ifif條件處再進展比較〕{................................jmp 整個多分支流程語句后的指令地址}elseif( )cmp12jxx 地址〔ifif條件處再進展比較〕{................................jmp 整個多分支流程語句后的指令地址}elseif( )cmp12jxx 地址〔ifelse條件處再進展比較〕{.................................}elsejmp 整個多分支流程語句后的指令地址{..................................}循環的反匯編通過試驗指導書當中給出的代碼清單9的反匯編結果和分析,給出for循環反匯編代碼的規律如下:for(inti=0;i<10;i++){定義i變量,并進展初始化指令代碼jmpxxxA處執行B:執行計數變量遞增操作將變量i mov到eax處eax1eaxmovi的變量里A:cmp12與循環完畢條件做比較指令代碼jxx xxx 假設照舊滿足條件,向下執行;否則跳轉到C處向下執行循環體指令代碼..........................................jmpxxxB處執行}C:代碼清單10while循環的代碼例如:int_tmain(intargc,_TCHAR*argv[]){inti=0;intj=0;while(i<10){j++;i++;}return0;}代碼清單10的反匯編結果:inti=0;0025138E mov dwordptr[ebp-8],0intj=0;00251395 mov dwordptr[ebp-14h],0while(i<10)0025139C002513A0{cmpjgedwordptr[ebp-8],0Ah002513B6j++;002513A2moveax,dwordptr[ebp-14h]002513A5addeax,1002513A8movi++;dwordptr[ebp-14h],eax002513ABmoveax,dwordptr[ebp-8]002513AEaddeax,1002513B1movdwordptr[ebp-8],eax}002513B4 jmp 0025139Creturn0;002513B6 xor eax,eax在代碼清單10當中,在地址0025138E處mov dwordptr[ebp-8],0將[ebp-8]設置為0,馬上i設置為0;同理在地址00251395處mov dwordptr[ebp-14h],0 將[ebp-14]設置為0,馬上j設置為0;在地址0025139C處cmp dwordptr[ebp-8],0Ah,將i的值與10做比較,在地址002513A0 處e 6 假設小于0則跳轉到6處執行〔即返回語句,假設連續向下執行,則002513A2002513A5002513A8三地址處的指令對j進展加一操作,002513AB002513AE002513B1對i進展加一操作;在002513B4jmp 0025139C 跳轉回cmp的指令處連續執行。通過代碼清單10while語句的反匯編代碼規律whileA :cmp操作數1操作數2 while循環完畢條件做比較jxx B{

假設不符合條件則,跳轉到B處連續執行,假設符合,則挨次執行循環體循環體指令............................................................................................................}jmp A A處連續執行B:....................................代碼清單11int_tmain(intargc,_TCHAR*argv[]){intj=0;inti=0;do{j++;i++;}while(i<10);return0;}代碼清單11的反匯編結果:intj=0;0019138E mov dwordptr[ebp-8],0inti=0;00191395do{movdwordptr[ebp-14h],0j++;0019139Cmoveax,dwordptr[ebp-8]0019139Faddeax,1001913A2movi++;dwordptr[ebp-8],eax001913A5moveax,dwordptr[ebp-14h]001913A8addeax,1001913ABmovdwordptr[ebp-14h],eax}while(i<10);001913AE cmp dwordptr[ebp-14h],0Ah001913B2 jl 0019139Creturn0;001913B4 xor eax,eax}在代碼清單11當中,在地址0019138E處將[ebp-8]設置為0,馬上j設置為0,在地址00191395處,將00191395設置為0,馬上i設置為0.在地址0019139C0019139F001913A2三個地址處執行j增1的操作,在001913A5001913A8001913AB三個地址處執行i增1的操作。在地址001913AE處執行循環條件比較指令cmp dwordptr[ebp-14h],0Ah在接下來的001913B2 jl 0019139C這條指令當中,假設操作數1即i小于操作數2即10,就跳轉到0019139C地址處連續執行,否則向下連續執行。do-while循環的反匯編代碼規律:do{ 循環體指令代碼A:........................................................................................................................................................................}while( );cmp操作數1 操作數2 do------while循環條件推斷語句jxxA假設符合條件的話,就跳轉到A處的循環體局部開頭執行,否則連續向下執行電子科技大學實 驗 報 告學生姓名:郭小明 學號:試驗室名稱:主樓A2-412二、試驗工程名稱:軟件開發環境試驗三:函數調用棧幀布局三、試驗原理:保存函數返回地址。另外,局部變量也通常位于棧上。VisualStudio2023為了防止棧上局部數組溢出,又實行了特別的保護措施。本試驗就需要通過觀看VisualStudio2023。四、試驗目的:本試驗總體目的是,通過使用VisualStudio2023查看函數調用時參數、局部變量等在棧上的分布狀況,以到達把握函數調用時棧幀布局的目的。六、試驗器材〔設備、元器件:PC機,VS2023軟件平臺。七、試驗步驟:在源文件中,編寫如下代碼。voidf{}intmain{f;return0;}得到反匯編代碼如下:voidf{008D13A0 push ebp008D13A1movebp,esp008D13A3subesp,0C0h008D13A9pushebx008D13AApushesi008D13ABpushedi008D13ACleaedi,[ebp-0c0h]008D13B2movecx,30h008D13B7moveax,0CCCCCCCCh008D13BCrepstosdwordptres:[edi]}008D13BEpopedi008D13BFpopesi008D13C0popebx008D13C1movesp,ebp008D13C3popebp008D13C4ret2stos指令的含義是:將eax的值放在[edi]中,之后在這里將edi4。repstosstos,直到ecx0ecx1。2,以及內存映像〔調式->窗口->內存〕2。返回地址ebp

ebp的值..0xcccccccc..原ebx的值原esi的值原edi的值

0xc0個0xcc0x30個0xcccccccc20xc0個字節的0xcc是否有溢出而寫的。代碼清單2的解釋:在008D13A0地址處將ebp的值壓入堆棧,并在008D13A1地址處將現在棧頂esp的值賦給ebp,然后再008D13A3處將esp的值減去0C0h,此時棧又向下面生長了0C0h個單位。然后在008D13A9008D13AA008D13AB三個地址處依次將ebx,esi,edi008D13ACleaedi,[ebp-0C0h]008D13AC地址處,將ebp0C0h這個地址值賦給edi。008D13B2movecx,30h將ecx的值賦為30h,在008D13B7mov eax,0CCCCCCCCh處將eax的值賦值為0CCCCCCCCh,stoseax[edi]edi的值4。repstosstosecx0,每次循環ecx都會1edi,esi,ebxebp中的esp的值esp,在將ebp出棧,就復原了現場。在源文件中,編寫如下代碼:#include“stdafx.h“voidf{inti=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}4:voidf{002513A0pushebp002513A1movebp,esp002513A3subesp,0CCh002513A9pushebx002513AApushesi002513ABpushedi002513ACleaedi,[ebp-0CCh]002513B2movecx,33h002513B7moveax,0CCCCCCCCh002513BCrepstosdwordptres:[edi]inti=0;002513BEmovdwordptr[i],0}002513C5popedi002513C6popesi002513C7popebx002513C8movesp,ebp002513CApopebp002513CBret在試驗報告中,需要給出代碼清單4中反匯編代碼的解釋。4,以及內存映像〔調式->窗口->內存〕3。返回地址ebpebp-4ebp-8ebp-0x0c

前幀ebp的值0xcccccccci0xcccccccc..0xcccccccc..原ebx的值原esi的值原edi的值

0xcc

共有0xcc個字節3只有一個整型局部變量時的布局inti120x0ci4i40xcccccccc。代碼清單4的解釋:002B13AC 代碼清單4的實現步驟總體類似于代碼清單2,也是首先將ebp壓棧,然后將esp保存進ebp,有所變化的就是這次是將esp的值減去0CCh,比上一次無局部變量的時候多了0Ch,然后照舊是壓ebx,esi,edi002B13AC 是將ebp與ebx之間的堆棧字節通通賦值為0xcc。在之后將i的值賦值為0,然后同樣是出棧和恢復地址。char類型局部變量、只有一個short類型局部變量,以及只有一個double類型局部變量時棧幀的布局。即代碼清單5、代碼清單6、代碼清單7中f函數所對應的棧幀布局。下面是chari=0;的反匯編代碼清單5:(留意右鍵顯示符號名)voidf{00AE13A0 push ebp00AE13A1movebp,esp00AE13A3subesp,0CCh00AE13A9pushebx00AE13AApushesi00AE13ABpushedi00AE13ACleaedi,[ebp-0CCh]00AE13B2movecx,33h00AE13B7moveax,0CCCCCCCCh00AE13BCrepstosdwordptres:[edi]chari=0;00AE13BEmovbyteptr[i],0}00AE13C2popedi00AE13C3popesi00AE13C4popebx00AE13C5movesp,ebp00AE13C7popebp00AE13C8ret返回地址前幀ebp的值ebp0xccccccccccebp-4iebp-5

0xcccccccccccccc

0xcc個字節ebp-0x0Ch 0xcccccccc0xC0oxcch原esi的值原edi的值下面是shorti0;的反匯編代碼清單6:voidf{012313A0 push ebp012313A1movebp,esp012313A3subesp,0CCh012313A9pushebx012313AApushesi012313ABpushedi012313ACleaedi,[ebp+FFFFFF34h]012313B2movecx,33h012313B7moveax,0CCCCCCCCh012313BCrepstosdwordptres:[edi]shorti=0;012313BE012313C0}xormov012313BE012313C0}xormoveax,eaxwordptr[ebp-10h],ax012313C4popedi012313C5popesi012313C6popebx012313C7movesp,ebp012313C9popebp012313CAret返回地址前幀ebp的值ebp0xcccccccc0xccccccccebp-8iebp-100xccccebp-0x0Ch0xcccccccc0xC0oxcch原esi的值原edi的值下面是doublei0;的反匯編代碼清單7:voidf{013C13A0 push ebp013C13A1movebp,esp013C13A3subesp,0CCh013C13A9pushebx013C13AApushesi013C13ABpushedi013C13ACleaedi,[ebp+FFFFFF34h]013C13B2movecx,33h013C13B7moveax,0CCCCCCCCh013C13BCrepstosdwordptres:[edi]doublei=0;013C13BE fldz013C13C0 fstp qwordptr[ebp-1Ch]}013C13C3popedi013C13C4popesi013C13C5popebx013C13C6movesp,ebp013C13C8popebp013C13C9ret返回地址前幀ebp的值ebp

0xccccccccccebp-4 0xC0oxcchi0xcc個字節ebp-0x0Ch

0xcccccccc原esi的值原edi的值在源文件中,編寫代碼清單8:voidf{chari=0;intj=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}并進展反匯編得到代碼清單9:voidf{00D813A0 push ebp00D813A1movebp,esp00D813A3subesp,0D8h00D813A9pushebx00D813AApushesi00D813ABpushedi00D813ACleaedi,[ebp+FFFFFF28h]00D813B2movecx,36h00D813B7moveax,0CCCCCCCCh00D813BCrepstosdwordptres:[edi]chari=0;00D813BE mov byteptr[ebp-5],0intj=0;00D813C2}movdwordptr[ebp-14h],000D813C9popedi00D813CApopesi00D813CBpopebx00D813CCmovesp,ebp00D813CEpopebp00D813CFret在試驗報告中,需要給出代碼清單9中反匯編代碼的解釋。9,以及內存映像〔調式->窗口->內存〕4。49對應的棧幀布局4可以看出,當增加一個局部變量時,這個局部變量的上方和下方都會填充假設干個0xcc字節。在試驗報告中,完成下面幾種情形的棧幀布局分析,并寫出棧幀布局的規律。9的解釋:首先將p壓棧,然后將現在〔棧頂指針〕的值賦給〔保存原始現場,然后將p-hi-的地址值賦給edi,再將ecx36h,然后將eax賦值為0CCCCCCCCh,之后執行stos指令,將這一段未被初始化的棧全部賦值為0xCCh.,chari=0〔ebp-5〕,inti=0賦值(ebp-14h),在之后,將edi,esi,ebx出棧,并且將esp復原為原來的ebp的值〔即復原現場。voidf{chari=0;shortj=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}下面是代碼清單10的反匯編代碼:voidf{00F613A0 push ebp00F613A1 mov ebp,esp00F613A3subesp,0D8h00F613A9pushebx00F613AApushesi00F613ABpushedi00F613ACleaedi,[ebp+FFFFFF28h]00F613B2movecx,36h00F613B7moveax,0CCCCCCCCh00F613BCrepstosdwordptres:[edi]chari=0;00F613BE mov byteptr[ebp-5],0shortj=0;00F613C200F613C4}xormoveax,eaxwordptr[ebp-14h],ax00F613C8popedi00F613C9popesi00F613CApopebx00F613CBmovesp,ebp00F613CDpopebp00F613CE ret返回地址ebp的值0xcccccccci〔1個字節〕0xcc0xcc0xccj〔2個字節〕0xcccccccc0xcccccccc〔共計有ebx的值esi的值edi的值voidf{chari=0;charj=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}11的反匯編代碼:voidf{000213A0 push ebp000213A1movebp,esp000213A3subesp,0D8h000213A9pushebx000213AApushesi000213ABpushedi000213ACleaedi,[ebp+FFFFFF28h]000213B2movecx,36h000213B7moveax,0CCCCCCCCh000213BCrepstosdwordptres:[edi]chari=0;000213BE mov byteptr[ebp-5],0charj=0;000213C2}movbyteptr[ebp-11h],0000213C6popedi000213C7popesi000213C8popebx000213C9movesp,ebp000213CBpopebp000213CCret返回地址ebp的值0xcccccccci0xcc0xcc0xcc0xcccccccc0xccccccccj0xcc0xcc0xcc0xcccccccc0xcccccccc〔0xc0個0xcc〕ebx的值esi的值edi的值下面是代碼清單12;voidf{chari=0;intj=0;shortk=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}下面是代碼清單12的反匯編代碼voidf{00A313A0 push ebp00A313A1movebp,esp00A313A3subesp,0E4h //將esp的值減去0E4h個單位00A313A9pushebx00A313AApushesi00A313ABpushedi00A313ACleaedi,[ebp+FFFFFF1Ch]00A313B2movecx,39h00A313B7moveax,0CCCCCCCCh00A313BCrepstosdwordptres:[edi]chari=0;00A313BE mov byteptr[ebp-5],0 值i賦值為0intj0;00A313C2 mov dwordptr[ebp-14h],0 0shortk0;00A313C900A313CB}xormoveax,eaxwordptr[ebp-20h],ax00A313CFpopedi //出棧00A313D0popesi00A313D1popebx00A313D2movesp,ebp ///恢復現場00A313D4popebp00A313D5ret代碼清單12的棧幀布局:返回地址0xcccccccci〔1個字節〕0xcc0xcc0xcc0xcccccccc0xccccccccj〔4個字節〕0xcccccccc0xcccccccc0xcc0xcck〔2個字節〕0xcccccccc0xcccccccc〔共計有0xc0的值的值棧幀布局的規律總結:壓棧保存。pushebp;存放器。movebpesp;安排棧大小棧大小=0xc0+變量個數* 0x0csubesp棧大小;的值壓棧ebp-edileaedi[ebp-棧大小]stos指令初始化棧char int short三種類型局部變量的棧安排方式不同每個變量都是占了12字節的棧,其中12字節分為三局部,第一局部440xcccccccc其次局部4個字節存放變量,其中int型完全占用其次局部4個字節,char型占0xccshort占用其次局部后兩個字節,剩下兩個字節填入0xccduoble型變量的狀況下,124個字節存放8個字節存放變量ebp,恢復調用函數前的現場。3.315可以看出,在 數中,將ecx的值同513的棧幀布局 security_cookie進展了比較。正常狀況下,這兩者應當是相等的。假設有越界寫的行為,可能會造成x的值同 e不全都。當不相等時e,tl,即不相等時跳轉,跳轉到failure處。1315ecx和 security_cookie的值不全都。試驗報告中需要給出添加的代碼及解釋,以及程序的運行結果截圖。ebpebp-4ebp-8ebp-9ebp-0x0cebp-0x10ebp-0x14

返回地址前幀ebp的值安全cookie的異或運算結果0xcccccccci0xcc0xcc0xcc0xcccccccc0xcccccccc

共有0xec個字節ebp-0x28

chara[20]ebp-0x2c 0xcccccccc..0xcccccccc..原ebx的值原esi的值原edi的值

共有0xc0個0xcc513的棧幀布局。添加代碼之后的程序:#include“stdafx.h“voidf{chari=0;chara[20];a[0]=0;a[36]=100;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}通過棧幀的布圖可以看出,我們通過 a[36]就可以訪問到我們的 ,通過更改 security_cookie的值,我們就可以造成ecx的值同 security_cookie不全都,從而導致我們 從而報錯。下面是程序的調試截圖:試驗程序:下面是反匯編調試后的代碼,逐步調試,按F11鍵進入 security_check_cookie函數,我們查看執行過程我們看到確實是執行了failure后面的程序,然后連續運行直至報錯。#include“stdafx.h“voidf{chara[1];a[0]=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}代碼清單16的反匯編代碼:voidf{01211A40 push ebp01211A41movebp,esp01211A43subesp,0CCh01211A49pushebx01211A4Apushesi01211A4Bpushedi01211A4Cleaedi,[ebp-0CCh]01211A52movecx,33h01211A57moveax,0CCCCCCCCh01211A5Crepstosdwordptres:[edi]chara[1];a[0]=0;01211A5E mov byteptr[ebp-5h],0}01211A62 push edx01211A63movecx,ebp01211A65pusheax01211A66leaedx,[(1211A7Ch)]01211A6Ccall(121108Ch)01211A71popeax01211A72popedx01211A73popedi01211A74popesi01211A75popebx01211A76movesp,ebp01211A78popebp01211A79ret返回地址前幀ebp的值0xccccccccchar a[1]〔一字節〕0xcc0xcc0xcc0xcccccccc0xcccccccc(共計0xc0個0xcc)原ebx的值原dsi的值原edi的值#include“stdafx.h“voidf{chara[3];a[0]=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}17的反匯編代碼voidf{004113A0 push ebp004113A1movebp,esp004113A3subesp,0CCh004113A9pushebx004113AApushesi004113ABpushedi004113ACleaedi,[ebp+FFFFFF34h]004113B2movecx,33h004113B7moveax,0CCCCCCCCh004113BCrepstosdwordptres:[edi]chara[3];a[0]=0;004113BE mov byteptr[ebp-10h],0}004113C2pushedx004113C3movecx,ebp004113C5pusheax004113C6leaedx,ds:[004113DCh]004113CCcall0041108C004113D1popeax004113D2popedx004113D3popedi004113D4popesi004113D5popebx004113D6movesp,ebp004113D8popebp004113D9ret返回地址ebp的值0xcccccccc(共計有0x0D 個0xcc)0xCC個字節

chara[3]〔3個字節〕0xcc)的值的值

ebp-10h#include“stdafx.h“voidf{chara[5];a[0]=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}18的反匯編代碼:voidf{00281A40 push ebp00281A41movebp,esp00281A43subesp,0D4h00281A49pushebx00281A4Apushesi00281A4Bpushedi00281A4Cleaedi,[ebp-0D4h]00281A52movecx,35h00281A57moveax,0CCCCCCCCh00281A5Crepstosdwordptres:[edi]00281A5Emoveax,dwordptr[ security_cookie(28702Ch)]00281A63xoreax,ebp00281A65movdwordptr[ebp-4],eaxchara[5];a[0]=0;00281A68 mov byteptr[ebp-1Ch],0}00281A6C push edx00281A6D mov ecx,ebp00281A6F push eax00281A70leaedx,[(281A90h)]00281A76call@ILT+135(@_RTC_CheckStackVars@8)(28108Ch)00281A7Bpopeax00281A7Cpopedx00281A7Dpopedi00281A7Epopesi00281A7Fpopebx00281A80movecx,dwordptr[ebp-4]00281A83xorecx,ebp00281A85call@ILT+25(@ security_check_cookie@4)(28101Eh)00281A8Amovesp,ebp00281A8Cpopebp00281A8Dret返回地址ebp的值cookie的異或運算結果ch個〕chara[5](5個字節)0xcc個字節ebp-1Ch0xcc)ebx的值esi的值#include“stdafx.h“voidf{chari[5];charj[7];i[0]=0;j[0]=0;}int_tmain(intargc,_TCHAR*argv[]){f;return0;}說明何種狀況下,才會有 security_cookie的安全性檢查?答:經過試驗覺察,在數組長度大于或者等于5個的狀況下就會消滅 security_cookie的安全性檢查。在前面已經得出的棧幀布局規律根底之上,把局部數組的狀況考慮進去,在試驗報告中寫出的布局規律。答:在前面的棧幀布局規律的根底上加上局部數組之后,消滅了如下變化:假設數組長度大于等于5的話,在前幀ebp之后會存儲4個字節的安全cookie異或運算結果,用于檢查緩沖區溢出。在存放局部數組的時候,與一般局部變量的存放狀況不同,是單獨開拓一塊空間存放數組,且依據數組下標大小依據小下標對應小地址,大下標對應大地址的方式存儲,并

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論