华中科技大学计算机系统基础实验报告_第1页
华中科技大学计算机系统基础实验报告_第2页
华中科技大学计算机系统基础实验报告_第3页
华中科技大学计算机系统基础实验报告_第4页
华中科技大学计算机系统基础实验报告_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

./课程实验报告课程名称:计算机系统基础专业班级:学号:姓名:指导教师:报告日期:2016年5月24日计算机科学与技术学院目录实验1:2实验2:9实验3:22实验总结30.实验1:数据表示1.1实验概述本实验的目的是更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。实验中,你需要解开一系列编程"难题"——使用有限类型和数量的运算操作实现一组给定功能的函数,在此过程中你将加深对数据二进制编码表示的了解。实验语言:c;实验环境:linux1.2实验容需要完成bits.c中下列函数功能,具体分为三大类:位操作、补码运算和浮点数操作。1.3实验设计源码如下:/**lsbZero-set0totheleastsignificantbitofx*Example:lsbZero<0x87654321>=0x87654320*Legalops:!~&^|+<<>>*Maxops:5*Rating:1*/intlsbZero<intx>{//x右移一位再左移一位实现把最低有效位置0x=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<<n;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和1n=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><<n>;x=<<x>><32+<~n+1>>>&z>+<x<<n>;returnx;}/**parityCheck-returns1ifxcontainsanoddnumberof1's*Examples:parityCheck<5>=0,parityCheck<7>=1*Legalops:!~&^|+<<>>*Maxops:20*Rating:4*/intparityCheck<intx>{//每次将数的低半数位与高半数位比较,再把y右移31位,最后把y转化为逻辑的0和1inty;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时还要+1inty=<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+1inty=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:BinaryBombs2.1实验概述本实验中,你要使用课程所学知识拆除一个"binarybombs"来增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。一个"binarybombs"〔二进制炸弹,下文将简称为炸弹是一个Linux可执行C程序,包含了6个阶段〔phase1~phase6。炸弹运行的每个阶段要求你输入一个特定的字符串,若你的输入符合程序预期的输入,该阶段的炸弹就被"拆除",否则炸弹"爆炸"并打印输出"BOOM!!!"字样。实验的目标是拆除尽可能多的炸弹层次。每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增:*阶段1:字符串比较*阶段2:循环*阶段3:条件/分支*阶段4:递归调用和栈*阶段5:指针*阶段6:链表/指针/结构另外还有一个隐藏阶段,但只有当你在第4阶段的解之后附加一特定字符串后才会出现。为了完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法"推断"出拆除炸弹所需的目标字符串。这可能需要你在每一阶段的开始代码前和引爆炸弹的函数前设置断点,以便于调试。实验语言:C语言实验环境:linux2.2实验容反汇编bomb,得到汇编代码,根据汇编代码完成拆炸弹任务。2.2.1阶段1字符串比较1.任务描述:找到与输入的字符串进行比较的存储的字符串的首地址,进而得到存储的字符串,得到结果。2.实验设计:根据反汇编代码一步一步分析,具体见实验过程。3.实验过程:将bomb反汇编输出到asm.txt文件中,在反汇编代码中查找phase_1的位置:从上面的语句可以看出<strings_not_equal>所需要的两个变量是存在于%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,54.实验结果:输入上述序列后得:可知结果正确。2.2.3阶段3条件/分支1.任务描述:完成炸弹3的拆除2.实验设计:观察分析phase_3代码,使用gdb调试分析结果3.实验过程:找到phase_3代码如下:08048c0a<phase_3>:8048c0a: 83ec3c sub$0x3c,%esp8048c0d: 8d44242c lea0x2c<%esp>,%eax8048c11: 89442410 mov%eax,0x10<%esp>8048c15: 8d442427 lea0x27<%esp>,%eax8048c19: 8944240c mov%eax,0xc<%esp>8048c1d: 8d442428 lea0x28<%esp>,%eax8048c21: 89442408 mov%eax,0x8<%esp>8048c25: c74424044ea204 movl$0x804a24e,0x4<%esp>由此行代码查看输入容:可知输入的依次是数字、字符、数字8048c43: 837c242807 cmpl$0x7,0x28<%esp>8048c48: 0f87f5000000 ja8048d43<phase_3+0x139>…8048d43: e88d040000 call80491d5<explode_bomb>可见输入的第一个数一定小于78048c4e: 8b442428 mov0x28<%esp>,%eax8048c52: ff248560a20408 jmp*0x804a260<,%eax,4>假设输入的第一个数为0,即<%eax>=0,所以:8048c59: b876000000 mov$0x76,%eax8048c5e: 817c242c040100 cmpl$0x104,0x2c<%esp>所以第二个字符ascll码为0x76,即字符'v'而第三个数为0x104,即2604.实验结果:从实验结果来看结果正确,拆弹成功。2.2.4阶段4递归调用和栈1.任务描述:拆除炸弹42.实验设计:观察分析phase_4代码,使用gdb调试分析结果3.实验过程:用x/sb0x804a3cf来查询有几个输入以及输入的类型,如下所示:由此可见输入是两个整数。再由phase_4中:知道func4第二个参数值为1f,即37再仔细研究func4函数,发现其实现了递归调用:08048d5c<func4>:8048d5c: 56 push%esi8048d5d: 53 push%ebx8048d5e: 83ec14 sub$0x14,%esp8048d61: 8b542420 mov0x20<%esp>,%edx/ebx是传递的参数/8048d65: 8b442424 mov0x24<%esp>,%eax8048d69: 8b742428 mov0x28<%esp>,%esi8048d6d: 89f1 mov%esi,%ecx8048d6f: 29c1 sub%eax,%ecx8048d71: 89cb mov%ecx,%ebx8048d73: c1eb1f shr$0x1f,%ebx/ebx右移31位/8048d76: 01d9 add%ebx,%ecx8048d78: d1f9 sar%ecx8048d7a: 8d1c01 lea<%ecx,%eax,1>,%ebx8048d7d: 39d3 cmp%edx,%ebx8048d7f: 7e17 jle8048d98<func4+0x3c>8048d81: 8d4bff lea-0x1<%ebx>,%ecx8048d84: 894c2408 mov%ecx,0x8<%esp>8048d88: 89442404 mov%eax,0x4<%esp>8048d8c: 891424 mov%edx,<%esp>8048d8f: e8c8ffffff call8048d5c<func4>8048d94: 01d8 add%ebx,%eax8048d96: eb1b jmp8048db3<func4+0x57>8048d98: 89d8 mov%ebx,%eax8048d9a: 39d3 cmp%edx,%ebx8048d9c: 7d15 jge8048db3<func4+0x57>8048d9e: 89742408 mov%esi,0x8<%esp>8048da2: 8d4301 lea0x1<%ebx>,%eax8048da5: 89442404 mov%eax,0x4<%esp>8048da9: 891424 mov%edx,<%esp>8048dac: e8abffffff call8048d5c<func4>8048db1: 01d8 add%ebx,%eax8048db3: 83c414 add$0x14,%esp8048db6: 5b pop%ebx8048db7: 5e pop%esi8048db8: c3 ret下面就来剖析func4,这个函数在确定栈之后,首先取出来传递给它的参数,依次放在eax,edx,esi.中,从一个jle和一个jge可以看出,这个递归函数跳出的条件根据func4的第二个参数和第二个参数进过种种运算的结果等于第一个参数即可。注意在递归过程中第一个参数是不变的,最后返回值是经过运算后的ebx加上第一个参数。当时做实验时推出了具体的表达式,未记录下来,只记录了最后得出fun<11>=31。运行结果如下:由此可见,phase_4拆除成功!4.实验结果:给出阶段x的实验结果和必要的结果分析2.2.5阶段5phase_51.任务描述:拆除一个关于指针的炸弹。2.实验设计:此阶段实验与指针相关,又根据静态调试跟踪可知,需借助gdb的动态调试跟踪来查找相关地址中存放的数据的值,进而分析出最终的拆弹密码。3.实验过程:首先观察代码,分析代码时发现有多个跳转指令,具体为x>15时,bomb;x>=1时,取x低4位;使用gdb调试发现,要输入的是两个%d数。由后面的步骤知输入第一个数为初始数组下标,第二个数为循环15次累加求的和。再接着:8048e70: 8b048580a20408 mov0x804a280<,%eax,4>,%eax,这句就是从<0x804a280+eax*4>里面拿数据出来,加到eax上。因为eax只能是0~F的数,所以0x804a260这个地址里面存的应该是一个数据大小为16的数组,用gdb看,得到:观察到果然是一个数组,然后下面就是把5个输入对应ascll码的低4位转换的十进制数对应的数值一个一个的转化为这个数组,得到累加值ecx。观察循环部分:由此知当退出循环的条件是取出的数eax为15,而且循环次数为15次由于115=12+3+7+11+13+9+4+8+10+1+2+14+6+15=a<5>+a<12>+a<6>最后得到的ecx值是115,输入的初始数组下标为5。所以答案为:51154.实验结果:可知结果正确。2.2.6阶段6phase_61.任务描述:拆除一个关于链表/指针/结构的炸弹。2.实验设计:初步静态分析,此阶段代码有些过长,所以单纯通过静态调试跟踪有些困难,因此我首先找到几个循环体,通过静态调试跟踪和动态调试跟踪的方法来确认循环体的功能,最后将循环体结合起来,拆除此阶段炸断。3.实验过程:由于代码较长,为便于分析,先总结一下,phase_6分为:参数读取,一个双层循环,三个单层循环。首先是参数读取:由此可见,readsix_number所有参数均小于6且不相等。由于后面代码部分过多,便采用gdb单步执行来了解代码的功能。在此,观察到后面:可以看到输入六个数字的初始地址值在0x804c13c,再由for循环中:8048ebf: 8b5208 mov0x8<%edx>,%edx可以看出六个数字按8个字节的顺序进行排列,因此分别调用gdb查看<0x804c13c>、*<0x804c13c+0x8>、*<*<0x804c13c+0x8>+0x8>、*<*<*<0x804c13c+0x8>+0x8>+0x8>、*<*<*<*<0x804c13c+0x8>+0x8>+0x8>+0x8>、*<*<*<*<*<0x804c13c+0x8>+0x8>+0x8>+0x8>+0x8>的值即可。如图所示:在下面检测链表值时,要求链表值从大到小排列。由上图可以看出,链表原本各个位置的值按顺序排列位:292385c63db7e308。按从小到大顺序排列应该为:7ec62923083853db。由此可以看出,用户应该输入:531624。4.实验结果:可见结果正确。1.3实验小结本次实验熟悉了obj、gdb的各种操作,对数据在计算机中的存储有了更加清晰的认识,更加加深了对汇编代码的理解,对循环、分支、数组指针结构在机器部的存储有了更深刻的认识。实验3:缓冲区溢出攻击3.1实验概述本实验的目的在于加深对IA-32函数调用规则和栈结构的具体理解。实验的主要容是对一个可执行程序"bufbomb"实施一系列缓冲区溢出攻击〔bufferoverflowattacks,也就是设法通过造成缓冲区溢出来改变该可执行程序的运行存映像,继而执行一些原来程序中没有的行为,例如将给定的字节序列插入到其本不应出现的存位置等。本次实验需要你熟练运用gdb、objdump、gcc等工具完成。实验中你需要对目标可执行程序BUFBOMB分别完成5个难度递增的缓冲区溢出攻击。5个难度级分别命名为Smoke〔level0、Fizz〔level1、Bang〔level2、Boom〔level3和Nitro〔level4,其中Smoke级最简单而Nitro级最困难。实验语言:c;实验环境:linux3.2实验容设法通过造成缓冲区溢出来改变该可执行程序的运行存映像,继而执行一些原来程序中没有的行为。3.2.0阶段0smoke1.任务描述:将getbuf函数执行return后执行test函数改为执行smoke函数。2.实验设计:首先根据反汇编代码求得buf离返回地址的字节距离,确定要填充几个字节,然后找到smoke函数的起始地址,把这个地址填入buf末尾,即可实现该功能。3.实验过程:首先通过gdb工具对bufbomb文件进行反汇编,查看getbuf的汇编代码:可见lea把buf的指针地址-0x28<%ebp>传给了Gets<>,所以buf离返回地址有0x28+4=44个字节的距离,因此只要在buf处开始填44个字节的非'\n'数,接下来填写要返回的地址,因为要返回至smoke,查看smoke函数的代码:可见smoke函数起始地址为0x08048c90,所以最后四个字节应该填入908c0408,所以输入的48个字节为:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000908c04084.实验结果:可见getbuf成功返回至smoke。3.2.1阶段1fizz1.任务描述:将getbuf函数执行return后执行test函数改为执行fizz函数。2.实验设计:跟阶段0类似,多了一个比较cookie环节,所以要把cookie填入相应地址。3.实验过程:只是将执行的函数从smoke改为fizz,查看fizz的汇编代码:可知val变量存储地址为fizz函数中的0x8<%ebp>,而fizz函数开始的地址为08048cba,所以输入的前44个字节为非'\n'任意值,第45-48个字节存放fizz函数起始地址,即ba8c0408,接下来4字节也是非'\n'值,最后为cookie值,即07ab9967,所以输入的56个字节为0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba8c04080000000007ab99674.实验结果:可见成功返回至fizz。3.2.2阶段2bang1.任务描述:将getbuf函数执行return后执行test函数改为执行bang函数。2.实验设计:找到cookie的地址和global_value的地址,将global_value的值改为cookie值,再使函数成功跳至bang执行。3.实验过程:先观察bang的代码:bang函数的首地址0x08048d05,在bang函数中,会将全局变量global_value和cookie进行比较,global_value的地址是0x804c218,cookie的地址是0x804c220,global_value在c代码中显示为0,所以需要修改global_value的值使其与cookie一致。汇编代码为:mov 0x804c220,%eaxmov %eax,0x804c218ret将这4行代码保存至example.s文件,进行汇编和反汇编,查看example.d文件得到指令序列:a120c20408a318c20408c3设置断点查看cookie为0x6799ab07时buf的首地址:为0x55683148,综合之前的指令序列,45-48字节放buf首址,49-52放bang函数首址,得到:a120c20408a318c20408c30

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论