电子科技大学软件开发环境实验报告Word格式文档下载.docx
《电子科技大学软件开发环境实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《电子科技大学软件开发环境实验报告Word格式文档下载.docx(56页珍藏版)》请在冰点文库上搜索。
首先mov指令把3赋值给dwordptr[i],cmp比较3和1EH(30)的大小,jle指令3小于30跳转到411394h,在继续比较14H,3也小于20,在跳转到004113A3h在比较3小于5,符合要求,mov指令把6赋值给dwordptr[i],跳转至4113D7.
if-else分支用的都是反比,先进行比较根据结果进行跳转。
根据对代码清单9的分析,总结出for循环的反汇编代码规律先赋初值,根据cmp来进行判断,看是否应该跳出循环,如果不跳出则利用add或sub指令进行重新赋值,知道跳出循环为止。
代码清单10首先先把0赋值给dwordptr[i];
把0赋值给dwordptr[j];
cmp指令比较dwordptr[i]和0AH(10)的大小,通过jge指令,如果i的值大于或等于10就跳转至4113A6H,执行地址00411392处、地址00411395处、地址00411398处的机器码。
这三条指令的含义是对j做加1运算,同理,041139B,041139E,04113A1对i做加一运算。
代码清单11首先先把0赋值给dwordptr[i];
把0赋值给dwordptr[j];
041138C,041138F,0411392三条地址指令对j进行加一运算,0411395,0411398,041139B对i进行加一运算,到地址041139E处,cmp指令比较i与0AH(10)的大小,jl不大于就回跳到41138C的地址,继续执行循环.
计算机科学与工程学院
2012年12月8日
实验二
代码清单2的反汇编解释:
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个范围0C0H;
等于在栈中空出一片空间来存局部变量。
04113A904113AA04113AB保存三个寄存器的值。
把ebp-0C0h加载到edi中,目的是保存局部变量的区域。
从ebp-0C0h开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令.
以上的语句就是在栈中开辟一块空间放局部变量;
然后把这块空间都初始化为0CCCCCCCCh,041138E,041138F,04113C0恢复原来寄存器的值。
movesp,ebp恢复原来的esp和ebp。
代码清单4的反汇编解释:
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个范围0CCH;
把ebp+FFFFFF34h加载到edi中,目的是保存局部变量的区域。
04113B2把33h赋值给ecx,从ebp+FFFFFF34h开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令
然后把这块空间都初始化为0CCCCCCCCh,04113BE把0赋值给i,04113C5,04113C6,04113C7恢复原来寄存器的值。
代码清单5的反汇编代码
解释:
0411399041139A041139B保存三个寄存器的值。
把ebp-0CCh加载到edi中,目的是保存局部变量的区域。
04113A2把33h赋值给ecx,从ebp-0CCh开的区域初始化成全部0CCCCCCCCh,04113AE把0字符赋值给byteptr[i]把初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令以上的语句就是在栈中开辟一块空间放局部变量;
然后把这块空间都初始化为0CCCCCCCCh,04113B2,04113B3,04113B4恢复原来寄存器的值。
在主程序_tmain中
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移一个范围0CCH;
04113D904113DA,04113DB保存三个寄存器的值。
04113A2把30h赋值给ecx,从ebp-0CCh开始的区域初始化成全部0CCCCCCCCh,04113EE运行函数F()。
栈帧布局:
代码清单6的反汇编代码
04113A2把33h赋值给ecx,从ebp-0CCh开的区域初始化成全部0CCCCCCCCh,04113AE把0字符赋值给wordptr[i]把初始化局部变量空间REP;
然后把这块空间都初始化为0CCCCCCCCh,04113B4,04113B5,04113B6恢复原来寄存器的值。
代码清单7的反汇编代码
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个
范围0CCH;
把ebp-0D0h加载到edi中,目的是保存局部变量的区域。
04113A2把34h赋值给ecx,从ebp-0CCh开始的区域初始化成全部0CCCCCCCCh,04113AE把0字符赋值给dwordptr[i]把初始化局部变量空间REP;
然后把这块空间都初始化为0CCCCCCCCh,04113B3,04113B4,04113B5恢复原来寄存器的值。
代码清单9的解释
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个范围
0D8H;
把ebp+FFFFFF28h加载到edi中,目的是保存局部变量的区域。
04113B2把36h赋值给ecx,从ebp+FFFFFF28h开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令041138E把0赋值给byteptr[ebp-5],地址为ebp-5,04113C2把0赋值到ebp-14。
然后把这块空间都初始化为0CCCCCCCCh,04113BE把0赋值给i,04113C9,04113CA,04113CB恢复原来寄存器的值。
代码清单10的反汇编代码
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个范围0D8H;
把ebp-0D8h加载到edi中,目的是保存局部变量的区域。
04113B2把36h赋值给ecx,从ebp+-0D8h开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令04113AE把0赋值给byteptr[i],,04113B2把0赋值到wordptr[j]。
然后把这块空间都初始化为0CCCCCCCCh,04113BE把0赋值给i,04113B8,04113B9,04113BA恢复原来寄存器的值。
代码清单11的反汇编代码
CX不等于0,则重复执行字符串指令04113AE把0赋值给byteptr[i],,04113B2把0赋值到byteptr[j]。
然后把这块空间都初始化为0CCCCCCCCh,04113BE把0赋值给i,04113B6,04113B7,04113B8恢复原来寄存器的值。
代码清单12的反汇编代码
保存ebp,将esp放入ebp中,此时ebp和esp相同,把esp往上移动一个范围0E4H;
04113B2把39h赋值给ecx,从ebp+-0D8h开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令04113AE把0赋值给byteptr[i],,04113B2把0赋值到dwordptr[j],0411389把0赋值给wordptr[k]。
然后把这块空间都初始化为0CCCCCCCCh,04113BE把0赋值给i,04113BF,04113C0,04113C1恢复原来寄存器的值。
代码清单13中添加代码
a[22]=0;
这样就可以造成越界。
这样就造成了ecx和security_cookie的值不一致。
以下是代码运行截图
代码清单16的反汇编代码
0CCH;
0411A290411A2A0411A2B保存三个寄存器的值。
从ebp-0Ch开始的区域初始化成全部0CCCCCCCCh,初始化局部变量空间REP;
CX不等于0,则重复执行字符串指令0411A3E把0赋值给byteptr[a],
并未启用__security_cookie的安全性检查
帧栈布局
代码清单17的反汇编代码
然后把这块空间都初始化为0CCCCCCCCh,0411A53,0411A54,0411A55恢复原来寄存器的值。
代码清单18的反汇编代码
代码解释和16,17类似,但是最重要的是,其启用了__security_cookie的安全性检查地址00411A3E处,将__security_cookie的值放入eax中。
然后地址00411A43处,将eax和ebp进行异或运算,并把运算结果存储于eax中。
在调用该函数之前,在地址00411A60处,从ebp-4取出之前的异或运算结果。
然后在地址00411A63处,将该结果再与ebp做异或运算,并保存在ecx中。
此时正常情况下,ecx就应该是__security_cookie的值了
代码清单19的反汇编代码
CX不等于0,则重复执行字符串指令,xor异或操作,0411A48把0赋值给byteptr[ebp-10],0411A4C把0赋值给byteptr[ebp-20]
然后把这块空间都初始化为0CCCCCCCCh,0411A60,0411A61,0411A62恢复原来寄存器的值。
其启用了__security_cookie的安全性检查地址00411A3E处,将__security_cookie的值放入eax中。
在调用该函数之前,在地址00411A45处,从ebp-4取出之前的异或运算结果。
然后在地址00411A67处,将该结果再与ebp做异或运算,并保存在ecx中。
2012年12月15日
实验三
1实验目的
本实验总体目的是,通过使用huffman编码算法从而实现文件的压缩和解压,以达到使学生掌握并灵活运用分割函数的三项原则。
本实验学时数为8学时。
2实验原理
分割函数的三项原则
分割函数的三项原则包括:
与其写注释,不如写函数;
重复就是罪恶;
函数不要超过50行至70行。
C++程序源码及截图:
#include<
stdafx.h>
cmath>
iostream>
string>
vector>
fstream>
bitset>
algorithm>
time.h>
usingstd:
:
cout;
endl;
cerr;
string;
vector;
bitset;
classHTNode
{
public:
stringletter;
intparent;
doubleweight;
HTNode*lchild;
HTNode*rchild;
stringHCode;
HTNode():
letter("
"
),parent(0),weight(0),lchild(NULL),rchild(NULL),HCode("
){};
HTNode(stringlett,intp,doublew,HTNode*l,HTNode*r,stringhc)
{letter=lett;
parent=p;
weight=w;
lchild=l;
rchild=r;
HCode=hc;
};
voidHuffTree(vector<
HTNode>
iteratorbeg,vector<
iteratorend);
voidHuffEncode(string&
textin,string&
textout);
voidHuffCompress(string&
textout,string&
bintext);
voidHuffDecode(string&
CodedData,string&
Decodedata);
intmain(intargc,char*argv[])
clock_tstart_time=clock();
//测试程序运行时间
//读取文件到字符串textin
//a="
-c"
b="
-u"
;
intp=strcmp(argv[1],"
);
intq=strcmp(argv[1],"
if(p==0){
stringtextin,buff;
std:
ifstreaminfile;
infile.open(argv[2]);
if(!
infile)
{
cout<
<
"
Cann'
topen1.\n"
;
return-1;
}
while(!
infile.eof())
getline(infile,buff);
textin+=buff;
infile.close();
//将string型textin,按huffman码写成string型的textout。
此时huffman码是字符型,不是位型,textout的大小是textin的四五倍。
stringtextout;
HuffEncode(textin,textout);
//调用压缩子程序,把string型textout每个字符映射成二进制位,压缩后以ASCII码显示成乱码。
stringbintext;
HuffCompress(textout,bintext);
//输出压缩文件
//cout<
textin.size()<
<
textout.size()<
bintext.size()<
endl;
ofstreamoutfile("
animalEncode.txt"
outfile<
bintext;
outfile.close();
ofstreamoutfile12(argv[3]);
outfile12<
outfile12.close();
if(q==0){
//解压文件
//读取压缩文件到字符串textin11
stringtextin11,buff11;
ifstreaminfile11;
infile11.open(argv[2]);
infile11)
topen2.\n"
infile11.eof())
getline(infile11,buff11);
textin11+=buff11;
infile11.close();
stringDecode;
HuffDecode(textin11,Decode);
ofstreamoutfile13(argv[3]);
outfile13<
Decode;
outfile13.close();
clock_tend_time=clock();
Timeexhausted:
end_time-start_time<
endl;
return0;
}
//一次建好所有Huffman节点。
调用这个子函数时,所有的HN(Max)都被HuffTree引用,调入内存,建立父子节点的指针链接;
iteratorend)
//检测输入的huffman叶子数,若太于个,计算量太大,返回。
if(end-beg>
500)
cerr<
ToomuchHuffmanleafnode;
return;
intNum_Lett=(end-be