电子科技大学软件开发环境实验报告_第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

提交评论