华中科技大学计算机系统基础实验报告.docx

上传人:b****5 文档编号:5583974 上传时间:2022-12-28 格式:DOCX 页数:28 大小:1.50MB
下载 相关 举报
华中科技大学计算机系统基础实验报告.docx_第1页
第1页 / 共28页
华中科技大学计算机系统基础实验报告.docx_第2页
第2页 / 共28页
华中科技大学计算机系统基础实验报告.docx_第3页
第3页 / 共28页
华中科技大学计算机系统基础实验报告.docx_第4页
第4页 / 共28页
华中科技大学计算机系统基础实验报告.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

华中科技大学计算机系统基础实验报告.docx

《华中科技大学计算机系统基础实验报告.docx》由会员分享,可在线阅读,更多相关《华中科技大学计算机系统基础实验报告.docx(28页珍藏版)》请在冰豆网上搜索。

华中科技大学计算机系统基础实验报告.docx

华中科技大学计算机系统基础实验报告

 

课程实验报告

课程名称:

计算机系统基础

专业班级:

学号:

姓名:

指导教师:

报告日期:

2016年5月24日

计算机科学与技术学院

 

实验1:

数据表示

1.1实验概述

本实验的目的是更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。

实验中,你需要解开一系列编程“难题”——使用有限类型和数量的运算操作实现一组给定功能的函数,在此过程中你将加深对数据二进制编码表示的了解。

实验语言:

c;实验环境:

linux

1.2实验内容

需要完成bits.c中下列函数功能,具体分为三大类:

位操作、补码运算和浮点数操作。

1.3实验设计

源码如下:

/*

*lsbZero-set0totheleastsignificantbitofx

*Example:

lsbZero(0x87654321)=0x87654320

*Legalops:

!

~&^|+<<>>

*Maxops:

5

*Rating:

1

*/

intlsbZero(intx){

//x右移一位再左移一位实现把最低有效位置0

x=x>>1;

x=x<<1;

returnx;

}

/*

*byteNot-bit-inversiontobytenfromwordx

*Bytesnumberedfrom0(LSB)to3(MSB)

*Examples:

getByteNot(0x12345678,1)=0x1234A978

*Legalops:

!

~&^|+<<>>

*Maxops:

6

*Rating:

2

*/

intbyteNot(intx,intn){

//x第n个字节每位都和1异或实现取反

inty=0xff;

n=n<<3;

y=y<

x=(x^y);

returnx;

}

/*

*byteXor-comparethenthbyteofxandy,ifitissame,return0,ifnot,return1

*example:

byteXor(0x12345678,0x87654321,1)=1

*byteXor(0x12345678,0x87344321,2)=0

*Legalops:

!

~&^|+<<>>

*Maxops:

20

*Rating:

2

*/

intbyteXor(intx,inty,intn){

//把x和y的第n个字节取出来异或,再转换为逻辑的0和1

n=n<<3;

x=x>>n;

y=y>>n;

x=x&(0xff);

y=y&(0xff);

return!

!

(x^y);

}

/*

*logicalAnd-x&&y

*Legalops:

!

~&^|+<<>>

*Maxops:

20

*Rating:

3

*/

intlogicalAnd(intx,inty){

//把x和y分别转化为逻辑的0和1,再相与

x=(!

(!

x))&(!

(!

y));

returnx;

}

/*

*logicalOr-x||y

*Legalops:

!

~&^|+<<>>

*Maxops:

20

*Rating:

3

*/

intlogicalOr(intx,inty){

//把x和y分别转化为逻辑的0和1,再相或

x=(!

(!

x))|(!

(!

y));

returnx;

}

/*

*rotateLeft-Rotatextotheleftbyn

*Canassumethat0<=n<=31

*Examples:

rotateLeft(0x87654321,4)=0x76543218

*Legalops:

~&^|+<<>>!

*Maxops:

25

*Rating:

3

*/

introtateLeft(intx,intn){

//先构造低n位为1,高(32-n)位为0的数z,x左移n位后的数加上x右移(32-n)位的数&z即可

intz;

z=~(((1<<31)>>31)<

x=((x>>(32+(~n+1)))&z)+(x<

returnx;

}

/*

*parityCheck-returns1ifxcontainsanoddnumberof1's

*Examples:

parityCheck(5)=0,parityCheck(7)=1

*Legalops:

!

~&^|+<<>>

*Maxops:

20

*Rating:

4

*/

intparityCheck(intx){

//每次将数的低半数位与高半数位比较,再把y右移31位,最后把y转化为逻辑的0和1

inty;

y=x<<16;

y=y^x;

y=y^(y<<8);

y=y^(y<<4);

y=y^(y<<2);

y=y^(y<<1);

y=y>>31;

return!

(!

y);

}

/*

*mul2OK-Determineifcancompute2*xwithoutoverflow

*Examples:

mul2OK(0x30000000)=1

*mul2OK(0x40000000)=0

*

*Legalops:

~&^|+<<>>

*Maxops:

20

*Rating:

2

*/

intmul2OK(intx){

//把x第31位和30位分别和1做按位与,再异或,再和1异或

intm;

m=((x>>31)&0x1)^((x>>30)&0x1);

returnm^0x1;

}

/*

*mult3div2-multipliesby3/2roundingtoward0,

*ShouldexactlyduplicateeffectofCexpression(x*3/2),

*includingoverflowbehavior.

*Examples:

mult3div2(11)=16

*mult3div2(-9)=-13

*mult3div2(1073741824)=-536870912(overflow)

*Legalops:

!

~&^|+<<>>

*Maxops:

12

*Rating:

2

*/

intmult3div2(intx){

//左移一位再+x即x*3,右移一位的时候,当y的最高位和最低位都为0时还要+1

inty=(x<<1)+x;

y=(y>>1)+(((y>>31)&1)&(((y<<31)>>31)&1));

returny;

}

/*

*subOK-Determineifcancomputex-ywithoutoverflow

*Example:

subOK(0x80000000,0x80000000)=1,

*subOK(0x80000000,0x70000000)=0,

*Legalops:

!

~&^|+<<>>

*Maxops:

20

*Rating:

3

*/

intsubOK(intx,inty){

//x的最高有效位和y的最高有效位不同且x和(x-y)的最高位不同才能判断溢出

intm=(x>>31)&1;

intn=(y>>31)&1;

x=(m^n)&(m^(((x+(~y+1))>>31)&1));

return(!

x);

}

/*

*absVal-absolutevalueofx

*Example:

absVal(-1)=1.

*Youmayassume-TMax<=x<=TMax

*Legalops:

!

~&^|+<<>>

*Maxops:

10

*Rating:

4

*/

intabsVal(intx){

//x最高位为0时就是x,最高位为1时是~x+1

inty=x>>31;

x=(y&(~x+1))+((~y)&x);

returnx;

}

/*

*float_abs-Returnbit-levelequivalentofabsolutevalueofffor

*floatingpointargumentf.

*Boththeargumentandresultarepassedasunsignedint's,but

*theyaretobeinterpretedasthebit-levelrepresentationsof

*single-precisionfloatingpointvalues.

*WhenargumentisNaN,returnargument..

*Legalops:

Anyinteger/unsignedoperationsincl.||,&&.alsoif,while

*Maxops:

10

*Rating:

2

*/

unsignedfloat_abs(unsigneduf){

intx=uf&(~(1<<31));

if(x>0x7f800000)

{

returnuf;

}

elsereturnx;

}

/*

*float_f2i-Returnbit-levelequivalentofexpression(int)f

*forfloatingpointargumentf.

*Argumentispassedasunsignedint,but

*itistobeinterpretedasthebit-levelrepresentationofa

*single-precisionfloatingpointvalue.

*Anythingoutofrange(includingNaNandinfinity)shouldreturn

*0x80000000u.

*Legalops:

Anyinteger/unsignedoperationsincl.||,&&.alsoif,while

*Maxops:

30

*Rating:

4

*/

intfloat_f2i(unsigneduf){

unsignednum=0x80000000;

intx=(uf&0x007fffff)^0x00800000;

intorder=0;

order=(uf&0x7f800000)>>23;

if(order>158){

returnnum;

}

if(order<127)return0;

elseif(((uf>>31)&1)==1){

if(order>150){

return~(x<<(order-150))+1;

}

elsereturn~(x>>(150-order))+1;

}

else{

if(order>150)returnx<<(order-150);

elsereturnx>>(150-order);

}

}

1.4实验过程

编写源码,运行btest,得出实验结果。

1.5实验结果

可见13个函数全部正确。

1.6实验小结

此次实验主要考查的是对数据的处理,对此需要掌握数据在机器中的表示,运用合理的位运算来实现相应的功能。

实验2:

BinaryBombs

2.1实验概述

本实验中,你要使用课程所学知识拆除一个“binarybombs”来增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。

一个“binarybombs”(二进制炸弹,下文将简称为炸弹)是一个Linux可执行C程序,包含了6个阶段(phase1~phase6)。

炸弹运行的每个阶段要求你输入一个特定的字符串,若你的输入符合程序预期的输入,该阶段的炸弹就被“拆除”,否则炸弹“爆炸”并打印输出"BOOM!

!

!

"字样。

实验的目标是拆除尽可能多的炸弹层次。

每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增:

*阶段1:

字符串比较

*阶段2:

循环

*阶段3:

条件/分支

*阶段4:

递归调用和栈

*阶段5:

指针

*阶段6:

链表/指针/结构

另外还有一个隐藏阶段,但只有当你在第4阶段的解之后附加一特定字符串后才会出现。

为了完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。

这可能需要你在每一阶段的开始代码前和引爆炸弹的函数前设置断点,以便于调试。

实验语言:

C语言

实验环境:

linux

2.2实验内容

反汇编bomb,得到汇编代码,根据汇编代码完成拆炸弹任务。

2.2.1阶段1字符串比较

1.任务描述:

找到与输入的字符串进行比较的存储的字符串的首地址,进而得到存储的字符串,得到结果。

2.实验设计:

根据反汇编代码一步一步分析,具体见实验过程。

3.实验过程:

将bomb反汇编输出到asm.txt文件中,在反汇编代码中查找phase_1的位置:

从上面的语句可以看出所需要的两个变量是存在于%ebp所指的堆栈存储单元里,在main函数中:

得知%eax里存储的是调用read_line()函数后返回的结果,就是输入的字符串,所以得知和用户输入字符串比较的字符串的存储地址为0x804a204,可用gdb查看这个地址存储的数据内容:

翻译过后的结果为Thefuturewillbebettertomorrow.

4.实验结果:

可见结果正确。

2.2.2阶段2循环

1.任务描述:

完成炸弹2的拆除

2.实验设计:

观察分析phase_2代码,使用gdb调试分析结果

3.实验过程:

找到phase_2代码:

由read_six_numbers知是要输入6个数字,观察:

可知输入的第一个和第二个必须依次为0,1

观察这两个循环可知只有当输入的数为前两个数之和时才不会bomb,故得到序列0,1,1,2,3,5

4.实验结果:

输入上述序列后得:

可知结果正确。

2.2.3阶段3条件/分支

1.任务描述:

完成炸弹3的拆除

2.实验设计:

观察分析phase_3代码,使用gdb调试分析结果

3.实验过程:

找到phase_3代码如下:

08048c0a:

8048c0a:

83ec3csub$0x3c,%esp

8048c0d:

8d44242clea0x2c(%esp),%eax

8048c11:

89442410mov%eax,0x10(%esp)

8048c15:

8d442427lea0x27(%esp),%eax

8048c19:

8944240cmov%eax,0xc(%esp)

8048c1d:

8d442428lea0x28(%esp),%eax

8048c21:

89442408mov%eax,0x8(%esp)

8048c25:

c74424044ea204movl$0x804a24e,0x4(%esp)

由此行代码查看输入内容:

可知输入的依次是数字、字符、数字

8048c43:

837c242807cmpl$0x7,0x28(%esp)

8048c48:

0f87f5000000ja8048d43

8048d43:

e88d040000call80491d5

可见输入的第一个数一定小于7

8048c4e:

8b442428mov0x28(%esp),%eax

8048c52:

ff248560a20408jmp*0x804a260(,%eax,4)

假设输入的第一个数为0,即(%eax)=0,所以:

8048c59:

b876000000mov$0x76,%eax

8048c5e:

817c242c040100cmpl$0x104,0x2c(%esp)

所以第二个字符ascll码为0x76,即字符'v'

而第三个数为0x104,即260

4.实验结果:

从实验结果来看结果正确,拆弹成功。

2.2.4阶段4递归调用和栈

1.任务描述:

拆除炸弹4

2.实验设计:

观察分析phase_4代码,使用gdb调试分析结果

3.实验过程:

用x/sb0x804a3cf来查询有几个输入以及输入的类型,如下所示:

由此可见输入是两个整数。

再由phase_4中:

知道func4第二个参数值为1f,即37

再仔细研究func4函数,发现其实现了递归调用:

08048d5c:

8048d5c:

56push%esi

8048d5d:

53push%ebx

8048d5e:

83ec14sub$0x14,%esp

8048d61:

8b542420mov0x20(%esp),%edx/ebx是传递的参数/

8048d65:

8b442424mov0x24(%esp),%eax

8048d69:

8b742428mov0x28(%esp),%esi

8048d6d:

89f1mov%esi,%ecx

8048d6f:

29c1sub%eax,%ecx

8048d71:

89cbmov%ecx,%ebx

8048d73:

c1eb1fshr$0x1f,%ebx/ebx右移31位/

8048d76:

01d9add%ebx,%ecx

8048d78:

d1f9sar%ecx

8048d7a:

8d1c01lea(%ecx,%eax,1),%ebx

8048d7d:

39d3cmp%edx,%ebx

8048d7f:

7e17jle8048d98

8048d81:

8d4bfflea-0x1(%ebx),%ecx

8048d84:

894c2408mov%ecx,0x8(%esp)

8048d88:

89442404mov%eax,0x4(%esp)

8048d8c:

891424mov%edx,(%esp)

8048d8f:

e8c8ffffffcall8048d5c

8048d94:

01d8add%ebx,%eax

8048d96:

eb1bjmp8048db3

8048d98:

89d8mov%ebx,%eax

8048d9a:

39d3cmp%edx,%ebx

8048d9c:

7d15jge8048db3

8048d9e:

89742408mov%esi,0x8(%esp)

8048da2:

8d4301lea0x1(%ebx),%eax

8048da5:

89442404mov%eax,0x4(%esp)

8048da9:

891424mov%edx,(%esp)

8048dac:

e8abffffffcall8048d5c

8048db1:

01d8add%ebx,%eax

8048db3:

83c414add$0x14,%esp

8048db6:

5bpop%ebx

8048db7:

5epop%esi

8048db8:

c3ret

下面就来剖析func4,这个函数在确定栈之后,首先取出来传递给它的参数,依次放在eax,edx,esi.中,从一个jle和一个jge可以看出,这个递归函数跳出的条件根据func4的第二个参数和第二个参数进过种种运算的结果等于第一个参数即可。

注意在递归过程中第一个参数是不变的,最后返回值是经过运算后的ebx加上第一个参数。

当时做实验时推出了具体的表达式,未记录下来,只记录了最后得出fun(11)=31。

运行结果如下:

由此可见,phase_4拆除成功!

4.实验结果:

给出阶段x的实验结果和必要的结果分析

2.2.5阶段5phase_5

1.任务描述:

拆除一个关于指针的炸弹。

2.实验设计:

此阶段实验与指针相关,又根据静态调试跟踪可知,需借助gdb的动态调试跟踪来查找相关地址中存放的数据的值,进而分析出最终的拆弹密码。

3.实验过程:

首先观察代码,分析代码时发现有多个跳转指令,具体为x>15时,bomb;x>=1时,取x低4位;

使用gdb调试发现,要输入的是两个%d数。

由后面的步骤知输入第一个数为初始数组下标,第二个数为循环15次累加求的和。

 

再接着:

8048e70:

8b048580a20408mov0x804a280(,%eax,4),%eax,这句就是从(0x804a280+eax*4)里面拿数据出来,加到eax上。

因为eax只能是0~F的数,所以0x804a260这个地址里面存的应该是一个数据大小为16的数组,用gdb看,得到:

观察到果然是一个数组,然后下面就是把5个输入对应ascll码的低4位转换的十进制数对应的数值一个一个的转化为这个数组,得到累加值ecx。

观察循环部分:

由此知当退出循环的条件是取出的数ea

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1