HIT CSAPP LAB5

2023-10-28 03:59
文章标签 lab5 hit csapp

本文主要是介绍HIT CSAPP LAB5,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LinkLab

链接

目 录

第1章 实验基本信息 - 3 -

1.1 实验目的 - 3 -
1.2 实验环境与工具 - 3 -
1.2.1 硬件环境 - 3 -
1.2.2 软件环境 - 3 -
1.2.3 开发工具 - 3 -

1.3 实验预习 - 3 -

第2章 实验预习 - 5 -

2.1 ELF文件格式解读 - 5 -
2.2程序的内存映像结构 - 5 -
2.3程序中符号的位置分析 - 6 -
2.4程序运行过程分析 - 12 -

第3章 各阶段的原理与方法 - 15 -

3.1 阶段1的分析 - 15 -
3.2 阶段2的分析 - 16 -
3.3 阶段3的分析 - 21 -
3.4 阶段4的分析 - 23 -
3.5 阶段5的分析 - 26 -

第4章 总结 - 36 -

4.1 请总结本次实验的收获 - 36 -
4.2 请给出对本次实验内容的建议 - 36 -

参考文献 - 37 -

第1章 实验基本信息

1.1 实验目的

  理解链接的作用与工作步骤
  掌握 ELF 结构、符号解析与重定位的工作过程
  熟练使用 Linux 工具完成 ELF 分析与修改

1.2 实验环境与工具

1.2.1 硬件环境

  X64 CPU;2GHz;2G RAM;256GHD Disk 以上

1.2.2 软件环境

  Windows7 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位;

1.2.3 开发工具

  Visual Studio 2010 64位以上;GDB/OBJDUMP;DDD/EDB等

1.3 实验预习

  上实验课前,必须认真预习实验指导书(PPT或PDF)
  了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。
  请按顺序写出ELF格式的可执行目标文件的各类信息。
  请按照内存地址从低到高的顺序,写出Linux下X64内存映像。
  请运行“LinkAddress -u 学号 姓名” 按地址顺序写出各符号的地址、空间。并按照Linux下X64内存映像标出其所属各区。
  请按顺序写出LinkAddress从开始执行到main前/后执行的子程序的名字。(gcc与objdump/GDB/EDB)

第2章 实验预习

2.1 ELF文件格式解读

请按顺序写出ELF格式的可执行目标文件的各类信息(5分)
  ELF头
  段头部表:将连续的文件映射到运行时的内存段。
  .init:定义了_init函数,程序初始化代码会调用它。
  .text:已编译程序的机器代码。
  .rodata:只读数据,比如printf语句中的格式串和开关语句的跳转表
  .data:已初始化的全局和静态C变量。局部C变量在运行时被保存在栈中,既不出现在.data节中,也不出现在.bss节中。
  .bss:未初始化的全局和静态C变量,以及所有被初始化为0的全局或静态变量。
  .symtab:一个符号表,它存放在程序中定义和引用的函数和全局变量的信息。
  .debug:一个调试符号表,其条目时程序中定义的全局变量和类型定义,程序中定义和引用的全局变量,以及原始的C源文件。
  .line:原始C源程序的行号和.text节中机器指令之间的映射
  .strtab:一个字符串表,其内容包括.symtab和.debug节中的符号表,以及节头部中的节名字。
  节头部表:描述目标文件的节。

2.2程序的内存映像结构

  请按照内存地址从低到高的顺序,写出Linux下X64内存映像(5分)
在这里插入图片描述

2.3程序中符号的位置分析

  请运行“LinkAddress -u 学号 姓名” 按地址顺序写出各符号的地址、空间。并按照Linux下X64内存映像标出其所属各区(5分)

所属区各符号的地址、空间(地址从小到大)
只读代码段(.init , .text , .rodata)exit 0x400630 4195888
printf 0x400600 4195840
malloc 0x400620 4195872
free 0x4005d0 4195792
读写段(.data .bss)show_pointer 0x400746 4196166
useless 0x400777 4196215
main 0x400782 4196226
global 0x60206c 6299756
huge array 0x602080 6299776
big array 0x40602080 1080041600
运行时堆(由malloc创建)p1 0x7febf17c9010 140651345514512
p2 0x435a5420 1129993248
p3 0x7fec01d7a010 140651619917840
p4 0x7febb17c8010 140650271768592
p5 (nil) 0
用户栈(运行时创建)argc 0x7ffd01e746dc 140724635387612
local 0x7ffd01e746e0 140724635387616
argv 0x7ffd01e74808 140724635387912
argv[0] 7ffd01e751d2
argv[1] 7ffd01e751e0
argv[2] 7ffd01e751e3
argv[3] 7ffd01e751ee
argv[0] 0x7ffd01e751d2 140724635390418
./linkaddress
argv[1] 0x7ffd01e751e0 140724635390432
-u
argv[2] 0x7ffd01e751e3 140724635390435
“这里是学号再挣扎一下嘻嘻”
argv[3] 0x7ffd01e751ee 140724635390446
“这里是姓名”
env 0x7ffd01e74830 140724635387952
env 0x7fff66970c70 140734914563184
env[0] env 0x7fff669721f8 140734914568696
XDG_VTNR=7
env[1] env 0x7fff66972203 140734914568707
LC_PAPER=zh_CN.UTF-8
env[2] env 0x7fff66972218 140734914568728
LC_ADDRESS=zh_CN.UTF-8
env[3] env 0x7fff6697222f 140734914568751
XDG_SESSION_ID=c2
env[4] env 0x7fff66972241 140734914568769
XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/helloworld
env[5] env 0x7fff66972277 140734914568823
LC_MONETARY=zh_CN.UTF-8
env[6] env 0x7fff6697228f 140734914568847
CLUTTER_IM_MODULE=xim
env[7] env 0x7fff669722a5 140734914568869
SESSION=ubuntu
env[8] env 0x7fff669722b4 140734914568884
GPG_AGENT_INFO=/home/helloworld/.gnupg/S.gpg-agent:0:1
env[9] env 0x7fff669722eb 140734914568939
TERM=xterm-256color
env[10] env 0x7fff669722ff 140734914568959
VTE_VERSION=4205
env[11] env 0x7fff66972310 140734914568976
XDG_MENU_PREFIX=gnome-
env[12] env 0x7fff66972327 140734914568999
SHELL=/bin/bash
env[13] env 0x7fff66972337 140734914569015
QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1
env[14] env 0x7fff6697235a 140734914569050
WINDOWID=54525962
env[15] env 0x7fff6697236c 140734914569068
LC_NUMERIC=zh_CN.UTF-8
env[16] env 0x7fff66972383 140734914569091
UPSTART_SESSION=unix:abstract=/com/ubuntu/upstart-session/1000/2061
env[17] env 0x7fff669723c7 140734914569159
GNOME_KEYRING_CONTROL=
env[18] env 0x7fff669723de 140734914569182
GTK_MODULES=gail:atk-bridge:unity-gtk-module
env[19] env 0x7fff6697240b 140734914569227
USER=helloworld
env[20] env 0x7fff6697241b 140734914569243
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:
.tar=01;31:
.tgz=01;31:
.arc=01;31:
.arj=01;31:
.taz=01;31:
.lha=01;31:
.lz4=01;31:
.lzh=01;31:
.lzma=01;31:
.tlz=01;31:
.txz=01;31:
.tzo=01;31:
.t7z=01;31:
.zip=01;31:
.z=01;31:
.Z=01;31:
.dz=01;31:
.gz=01;31:
.lrz=01;31:
.lz=01;31:
.lzo=01;31:.xz=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31:.tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.alz=01;31:.ace=01;31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.cab=01;31:.jpg=01;35:.jpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35:.pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35:.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg=01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35:.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf=01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:.fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00;36:.flac=00;36:.m4a=00;36:.mid=00;36:.midi=00;36:.mka=00;36:.mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.oga=00;36:.opus=00;36:.spx=00;36:*.xspf=00;36:
env[21] *env 0x7fff669729a3 140734914570659
QT_ACCESSIBILITY=1
env[22] *env 0x7fff669729b6 140734914570678
LC_TELEPHONE=zh_CN.UTF-8
env[23] *env 0x7fff669729cf 140734914570703
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
env[24] *env 0x7fff66972a09 140734914570761
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
env[25] *env 0x7fff66972a3d 140734914570813
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
env[26] *env 0x7fff66972a66 140734914570854
SESSION_MANAGER=local/ubuntu:@/tmp/.ICE-unix/2295,unix/ubuntu:/tmp/.ICE-unix/2295
env[27] *env 0x7fff66972ab8 140734914570936
DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path
env[28] *env 0x7fff66972aeb 140734914570987
XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg
env[29] *env 0x7fff66972b2f 140734914571055
DESKTOP_SESSION=ubuntu
env[30] *env 0x7fff66972b46 140734914571078
PATH=/home/helloworld/bin:/home/helloworld/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
env[31] *env 0x7fff66972bdf 140734914571231
QT_IM_MODULE=fcitx
env[32] *env 0x7fff66972bf2 140734914571250
QT_QPA_PLATFORMTHEME=appmenu-qt5
env[33] *env 0x7fff66972c13 140734914571283
LC_IDENTIFICATION=zh_CN.UTF-8
env[34] *env 0x7fff66972c31 140734914571313
XDG_SESSION_TYPE=x11
env[35] *env 0x7fff66972c46 140734914571334
PWD=/home/helloworld/hitics/lab5/32
env[36] *env 0x7fff66972c6a 140734914571370
JOB=dbus
env[37] *env 0x7fff66972c73 140734914571379
XMODIFIERS=@im=fcitx
env[38] *env 0x7fff66972c88 140734914571400
GNOME_KEYRING_PID=
env[39] *env 0x7fff66972c9b 140734914571419
LANG=zh_CN.UTF-8
env[40] *env 0x7fff66972cac 140734914571436
GDM_LANG=zh_CN
env[41] *env 0x7fff66972cbb 140734914571451
MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path
env[42] *env 0x7fff66972cf1 140734914571505
LC_MEASUREMENT=zh_CN.UTF-8
env[43] *env 0x7fff66972d0c 140734914571532
COMPIZ_CONFIG_PROFILE=ubuntu
env[44] *env 0x7fff66972d29 140734914571561
IM_CONFIG_PHASE=1
env[45] *env 0x7fff66972d3b 140734914571579
PAPERSIZE=a4
env[46] *env 0x7fff66972d48 140734914571592
GDMSESSION=ubuntu
env[47] *env 0x7fff66972d5a 140734914571610
SESSIONTYPE=gnome-session
env[48] *env 0x7fff66972d74 140734914571636
GTK2_MODULES=overlay-scrollbar
env[49] *env 0x7fff66972d93 140734914571667
SHLVL=1
env[50] *env 0x7fff66972d9b 140734914571675
HOME=/home/helloworld
env[51] *env 0x7fff66972db1 140734914571697
XDG_SEAT=seat0
env[52] *env 0x7fff66972dc0 140734914571712
LANGUAGE=zh_CN:en_US:en
env[53] *env 0x7fff66972dd8 140734914571736
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
env[54] *env 0x7fff66972e04 140734914571780
XDG_SESSION_DESKTOP=ubuntu
env[55] *env 0x7fff66972e1f 140734914571807
LOGNAME=helloworld
env[56] *env 0x7fff66972e32 140734914571826
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-QnglPcTmlQ
env[57] *env 0x7fff66972e6e 140734914571886
XDG_DATA_DIRS=/usr/share/ubuntu:/usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop
env[58] *env 0x7fff66972ed2 140734914571986
QT4_IM_MODULE=fcitx
env[59] *env 0x7fff66972ee6 140734914572006
LESSOPEN=
/usr/bin/lesspipe %s
env[60] *env 0x7fff66972f06 140734914572038
INSTANCE=
env[61] *env 0x7fff66972f10 140734914572048
XDG_RUNTIME_DIR=/run/user/1000
env[62] *env 0x7fff66972f2f 140734914572079
DISPLAY=:0
env[63] *env 0x7fff66972f3a 140734914572090
XDG_CURRENT_DESKTOP=Unity
env[64] *env 0x7fff66972f54 140734914572116
GTK_IM_MODULE=fcitx
env[65] *env 0x7fff66972f68 140734914572136
LESSCLOSE=/usr/bin/lesspipe %s %s
env[66] *env 0x7fff66972f8a 140734914572170
LC_TIME=zh_CN.UTF-8
env[67] *env 0x7fff66972f9e 140734914572190
LC_NAME=zh_CN.UTF-8
env[68] *env 0x7fff66972fb2 140734914572210
XAUTHORITY=/home/helloworld/.Xauthority
env[69] *env 0x7fff66972fda 140734914572250
_=./linkaddress

linkaddress.c程序如下:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>static void show_pointer(void *p, char *descr) {//    printf("Pointer for %s at %p\n", descr, p);printf("%s\t%p\t%lu\n", descr, p, (unsigned long) p);
}char big_array[1L<<24];    /*  16 MB */
char huge_array[1L<<30];   /*   1 GB */
int global = 0;int useless() { return 0; }int main (int argc,char *argv[])
{char **env = __environ;    //环境变量__environ void *p1, *p2, *p3, *p4,*p5;int local = 0;if(argc!=4){printf("Usage: LinkAddress P1 P2 P3\n");return 1;}useless(); //打印系统变量信息  show_pointer((void *) env, "env");int i=0;while(*env) { printf("env[%d]\t",i);show_pointer((void *) (*env), "*env");puts(*env);    env++;   i++;} p1 = malloc(1L << 28);p2 = malloc(1L << 17);p3 = malloc( (1L << 17) +1);p4 = malloc(1L << 30);p5 = malloc(1L << 31);show_pointer((void *) big_array, "big array");show_pointer((void *) huge_array, "huge array");show_pointer((void *) &local, "local");show_pointer((void *) &global, "global");show_pointer((void *) &argc, "argc");show_pointer((void *) argv, "argv");printf("argv[0] %16lx\n",(unsigned long) (*argv));printf("argv[1] %16lx\n",(unsigned long) (*(argv+1)));    //argv[1]  argv 指针+1 就是argv地址+8printf("argv[2] %16lx\n",(unsigned long) (*(argv+2)));printf("argv[3] %16lx\n",(unsigned long) (*(argv+3)));show_pointer((void *) argv[0], "argv[0]");printf("%s\n",argv[0]);show_pointer((void *) argv[1], "argv[1]");printf("%s\n",argv[1]);show_pointer((void *) argv[2], "argv[2]");printf("%s\n",argv[2]);show_pointer((void *) argv[3], "argv[3]");printf("%s\n",argv[3]);show_pointer((void *) p1, "p1");show_pointer((void *) p2, "p2");show_pointer((void *) p3, "p3");show_pointer((void *) p4, "p4");show_pointer((void *) p5, "p5");show_pointer((void *) show_pointer, "show_pointer");show_pointer((void *) useless, "useless");show_pointer((void *) main, "main");show_pointer((void *) exit, "exit");show_pointer((void *) printf, "printf");show_pointer((void *) malloc, "malloc");show_pointer((void *) free, "free");free(p1);      free(p2);       free(p3);	    free(p4);         return 0;
}

2.4程序运行过程分析

  请按顺序写出LinkAddress从开始执行到main前/后执行的子程序的名字(使用gcc与objdump/GDB/EDB)(5分)
  main()执行前:
  Breakpoint 9, 0x0000000000400650 in _start ()
  Breakpoint 6, 0x0000000000400610 in __libc_start_main@plt ()
  Breakpoint 17, 0x0000000000400b10 in __libc_csu_init ()
  Breakpoint 1, 0x0000000000400598 in _init ()
  Breakpoint 13, 0x0000000000400720 in frame_dummy ()
  Breakpoint 11, 0x00000000004006c0 in register_tm_clones ()
  main执行时:
  Breakpoint 16, 0x0000000000400782 in main ()
  main执行后:
  Breakpoint 3, 0x00000000004005e0 in puts@plt ()
  Breakpoint 7, 0x0000000000400620 in malloc@plt ()
  Breakpoint 12, 0x0000000000400700 in __do_global_dtors_aux ()
  Breakpoint 10, 0x0000000000400680 in deregister_tm_clones ()
  Breakpoint 19, 0x0000000000400b84 in _fini ()
  objdump中:
  main()前:
  Breakpoint 1 at 0x400598
  <function, no debug info> _init;
  Breakpoint 2 at 0x4005d0
  <function, no debug info> free@plt;
  Breakpoint 3 at 0x4005e0
  <function, no debug info> puts@plt;
  Breakpoint 4 at 0x4005f0
  <function, no debug info> __stack_chk_fail@plt;
  Breakpoint 5 at 0x400600
  <function, no debug info> printf@plt;
  Breakpoint 6 at 0x400610
  <function, no debug info> __libc_start_main@plt;
  Breakpoint 7 at 0x400620
  <function, no debug info> malloc@plt;
  Breakpoint 8 at 0x400630
  <function, no debug info> exit@plt;
  Breakpoint 9 at 0x400650
  <function, no debug info> _start;
  Breakpoint 10 at 0x400680
  <function, no debug info> deregister_tm_clones;
  Breakpoint 11 at 0x4006c0
  <function, no debug info> register_tm_clones;
  Breakpoint 12 at 0x400700
  <function, no debug info> __do_global_dtors_aux;
  Breakpoint 13 at 0x400720
  <function, no debug info> frame_dummy;
  Breakpoint 14 at 0x400746
  <function, no debug info> show_pointer;
  Breakpoint 15 at 0x400777
  <function, no debug info> useless;
  main():
  Breakpoint 16 at 0x400782
  <function, no debug info> main;
  main()后:
  Breakpoint 17 at 0x400b10
  <function, no debug info> __libc_csu_init;
  Breakpoint 18 at 0x400b80
  <function, no debug info> __libc_csu_fini;
  Breakpoint 19 at 0x400b84
  <function, no debug info> _fini;

第3章 各阶段的原理与方法

  每阶段40分,phasex.o 20分,分析20分,总分不超过80分

3.1 阶段1的分析

  程序运行结果截图:
在这里插入图片描述
  分析与设计的过程:
  首先readelf -a phase1.o 查看elf文件内容,根据节头信息可知,字符串输出起始地址在 .data 段中,.data节开始于0x80的位置。
在这里插入图片描述
  运行linkbomb1程序,查看输出的字符串如下图:
在这里插入图片描述
  找到 .data节,找到与乱码字符串相同的位置,偏移量为11(10)的地方为待输入字符串所在地址,
在这里插入图片描述
  使用hexedit修改其ascii码,(学号) 的ascii码为(学号),最后再以00表示字符串结束,于是得到以下的修改结果。再次链接并且运行linkbomb1即可输出(学号)。
在这里插入图片描述

3.2 阶段2的分析

  程序运行结果截图:
在这里插入图片描述
  分析与设计的过程:
  查看phase2.o的反汇编代码:
在这里插入图片描述
  反汇编代码如下:

phase2.o:     文件格式 elf32-i386Disassembly of section .text:00000000 <cbLxqPqM>:0:	55                   	push   %ebp1:	89 e5                	mov    %esp,%ebp3:	53                   	push   %ebx4:	83 ec 04             	sub    $0x4,%esp7:	e8 fc ff ff ff       	call   8 <cbLxqPqM+0x8>c:	81 c3 02 00 00 00    	add    $0x2,%ebx12:	83 ec 08             	sub    $0x8,%esp15:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax1b:	50                   	push   %eax1c:	ff 75 08             	pushl  0x8(%ebp)1f:	e8 fc ff ff ff       	call   20 <cbLxqPqM+0x20>24:	83 c4 10             	add    $0x10,%esp27:	85 c0                	test   %eax,%eax29:	75 10                	jne    3b <cbLxqPqM+0x3b>2b:	83 ec 0c             	sub    $0xc,%esp2e:	ff 75 08             	pushl  0x8(%ebp)31:	e8 fc ff ff ff       	call   32 <cbLxqPqM+0x32>36:	83 c4 10             	add    $0x10,%esp39:	eb 01                	jmp    3c <cbLxqPqM+0x3c>3b:	90                   	nop3c:	8b 5d fc             	mov    -0x4(%ebp),%ebx3f:	c9                   	leave  40:	c3                   	ret    00000041 <do_phase>:41:	55                   	push   %ebp42:	89 e5                	mov    %esp,%ebp44:	e8 fc ff ff ff       	call   45 <do_phase+0x4>49:	05 01 00 00 00       	add    $0x1,%eax4e:	90                   	nop4f:	90                   	nop50:	90                   	nop51:	90                   	nop52:	90                   	nop53:	90                   	nop54:	90                   	nop55:	90                   	nop56:	90                   	nop57:	90                   	nop58:	90                   	nop59:	90                   	nop5a:	90                   	nop5b:	90                   	nop5c:	90                   	nop5d:	90                   	nop5e:	90                   	nop5f:	90                   	nop60:	90                   	nop61:	90                   	nop62:	90                   	nop63:	90                   	nop64:	90                   	nop65:	90                   	nop66:	90                   	nop67:	90                   	nop68:	90                   	nop69:	90                   	nop6a:	90                   	nop6b:	90                   	nop6c:	90                   	nop6d:	90                   	nop6e:	90                   	nop6f:	5d                   	pop    %ebp70:	c3                   	ret    Disassembly of section .text.__x86.get_pc_thunk.ax:00000000 <__x86.get_pc_thunk.ax>:0:	8b 04 24             	mov    (%esp),%eax3:	c3                   	ret    Disassembly of section .text.__x86.get_pc_thunk.bx:00000000 <__x86.get_pc_thunk.bx>:0:	8b 1c 24             	mov    (%esp),%ebx3:	c3                   	ret 

  其中含有函数cbLxqPqM,对其进行gdb,使用jump等指令对函数cbLxqPqM相应内容进行查看:
在这里插入图片描述
  可以得到此时待比较字符串内容为学号(学号)。而执行strcmp之前向栈中压入了两个参数id以及MYID,我们需要在do_phase函数的nop部分,执行压栈,并且跳转到cbLxqPqM函数。

static void OUTPUT_FUNC_NAME( const char *id )     // 该函数名对每名学生均不同  
{  if( strcmp(id,MYID) != 0 ) return;  printf("%s\n", id);  
}  
void do_phase()  {  // 在代码节中预留存储位置供学生插入完成功能的必要指令  asm( “nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t…” );       
}  

  查看main函数, call 0x804848f <__x86.get_pc_thunk.ax> 和add $0x1bb1, %eax指令,实现了%eax指向_GLOBAL_OFFSET_TABLE。
在这里插入图片描述
  查看cbLxqPqM函数,同样的 call 0x8048370 <__x86.get_pc_thunk.bx> 和add $0x1b61, %ebx 指令,实现了%ebx指向_GLOBAL_OFFSET_TABLE。
在这里插入图片描述
  又因为%ebx之后还执行了lea -0x19fc(%ebx), %eax,目的是重定位之后使%eax指向 .rodata,因此在nop处填写的汇编代码中,需要同样的操作,使do_phase中%eax也指向 .rodata ,操作为lea -0x19fc(%eax),%eax。
  读取寄存器中的数据可说明上述表述正确。
在这里插入图片描述
  然后我们需要使用相对寻址的方式,使do_phase 函数跳转到cbLxqPqM函数。由于函数此时地址为0x08048493,而do_phase函数执行到lea -0x19fc(%eax),%eax时%eax的值为0x8048604,根据二者的差值,即可跳转至%eax减去0x171处的地址。
  故而采用以下汇编代码:

leal  -0x19fc(%eax),%eax
leal  -0x171(%eax),%ecx
pushl %eax
calll *%ecx
popl %eax

在这里插入图片描述
  将其插入第一个nop(90)0x44+0x4e=0x92即可:
在这里插入图片描述
在这里插入图片描述

3.3 阶段3的分析

  程序运行结果截图:
在这里插入图片描述
  分析与设计的过程:
  分析do_phase的反汇编指令,获取COOKIE字符串。gcc -m32 -o linkbomb3 main.o phase3.o链接之后,使用gdb进行调试do_phase函数:
  其中白色部分为循环部分,如下图。显然这部分循环可以写成如下形式:

char PHASE3_CODEBOOK[256];  
void do_phase(){  const char cookie[] = PHASE3_COOKIE;  for( int i=0; i<sizeof(cookie)-1; i++ )  printf( "%c", PHASE3_CODEBOOK[ (unsigned char)(cookie[i]) ] );printf( "\n" );  
}  

在这里插入图片描述
  反汇编代码如下:

phase3.o:     文件格式 elf32-i386Disassembly of section .text:00000000 <do_phase>:0:	55                   	push   %ebp1:	89 e5                	mov    %esp,%ebp3:	53                   	push   %ebx4:	83 ec 24             	sub    $0x24,%esp7:	e8 fc ff ff ff       	call   8 <do_phase+0x8>c:	81 c3 02 00 00 00    	add    $0x2,%ebx12:	65 a1 14 00 00 00    	mov    %gs:0x14,%eax18:	89 45 f4             	mov    %eax,-0xc(%ebp)1b:	31 c0                	xor    %eax,%eax1d:	c7 45 e9 76 69 6a 72 	movl   $0x726a6976,-0x17(%ebp)24:	c7 45 ed 65 62 7a 75 	movl   $0x757a6265,-0x13(%ebp)2b:	66 c7 45 f1 73 70    	movw   $0x7073,-0xf(%ebp)31:	c6 45 f3 00          	movb   $0x0,-0xd(%ebp)35:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)3c:	eb 2b                	jmp    69 <do_phase+0x69>3e:	8d 55 e9             	lea    -0x17(%ebp),%edx41:	8b 45 e4             	mov    -0x1c(%ebp),%eax44:	01 d0                	add    %edx,%eax46:	0f b6 00             	movzbl (%eax),%eax49:	0f b6 c0             	movzbl %al,%eax4c:	8b 93 00 00 00 00    	mov    0x0(%ebx),%edx52:	0f b6 04 02          	movzbl (%edx,%eax,1),%eax56:	0f be c0             	movsbl %al,%eax59:	83 ec 0c             	sub    $0xc,%esp5c:	50                   	push   %eax5d:	e8 fc ff ff ff       	call   5e <do_phase+0x5e>62:	83 c4 10             	add    $0x10,%esp65:	83 45 e4 01          	addl   $0x1,-0x1c(%ebp)69:	8b 45 e4             	mov    -0x1c(%ebp),%eax6c:	83 f8 09             	cmp    $0x9,%eax6f:	76 cd                	jbe    3e <do_phase+0x3e>71:	83 ec 0c             	sub    $0xc,%esp74:	6a 0a                	push   $0xa76:	e8 fc ff ff ff       	call   77 <do_phase+0x77>7b:	83 c4 10             	add    $0x10,%esp7e:	90                   	nop7f:	8b 45 f4             	mov    -0xc(%ebp),%eax82:	65 33 05 14 00 00 00 	xor    %gs:0x14,%eax89:	74 05                	je     90 <do_phase+0x90>8b:	e8 fc ff ff ff       	call   8c <do_phase+0x8c>90:	8b 5d fc             	mov    -0x4(%ebp),%ebx93:	c9                   	leave  94:	c3                   	ret    Disassembly of section .text.__x86.get_pc_thunk.bx:00000000 <__x86.get_pc_thunk.bx>:0:	8b 1c 24             	mov    (%esp),%ebx3:	c3                   	ret  

  运行到图示处,再接着查看%ebp-0x17处的cookie内容,存储内容为vijrebzusp。
在这里插入图片描述
  使用readelf确定PHASE3_CODEBOOK[256]数组对应的名称。readelf -a phase3.o得到:
在这里插入图片描述
  Num为11处,Ndx为COM,Name为qZwfEQMjKc。故而数组PHASE3_CODEBOOK[256]实际名称为qZwfEQMjKc。这是因为QDwnxQFyLh已经在phase3.o中有了全局弱定义,所以必然存在于符号表.symtab中。
  从而只要使相应位置字符为学号即可。cookie中字符串vijrebzusp转换为ascii为(十进制):118 105 106 114 101 98 122 117 115 112,将以上相应位置的字符改为学号(学号)即可。然后将该.c文件预处理编译汇编成.o文件。
在这里插入图片描述

char qZwfEQMjKc[256] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aa3aaa18aaaaa9a01a71aaa0aaaaaaa";

3.4 阶段4的分析

  程序运行结果截图:
在这里插入图片描述
  分析与设计的过程:
  查看do_phase处的反汇编代码,可以看出应该是switch开关语句,图片如下。

  每次比较之前都将cookie字符-0x41与0x19进行比较,并跳转到%eax所存的地址处,%eax的值为(((%eax-0x41)<<2)+%ebx-0x189c),外括号代表寻址, 这里是将cookie值作为索引映射到switch跳转表,switch跳转表保存在.rodata中。当将main.o和phase4.o链接之后确定跳转表的值。当程序运行时,程序先拿到跳转表的值,跳转表中存放着相对偏移位置,通过 %eax=%ebx+偏移量 获得存储在.text段中共的case代码段地址,之后跳转执行。
在这里插入图片描述

void do_phase()  
{  const char cookie[] = PHASE4_COOKIE;  char c;  for ( int i = 0; i < sizeof(cookie)-1; i++ )   {  c = cookie[i];  switch (c)   {  // 每个学生的映射关系和case顺序建议不一样  case ‘A’: { c = 48; break; }   case ‘B’: { c = 121; break; }case ‘Z’: { c = 93; break; }  }  printf("%c", c);  }  
}  

在这里插入图片描述
  我们可以得到所有的case类在跳转表里面对应的偏移量,我们选择输出指定字母串为学号的case块的跳转表偏移量,按cookie映射顺序与位置填入到.rodata跳转表之中。偏移量依次为7,22,17,21,0,18,11,6,3,5
  查看.rel.rodata段获取偏移量值:
在这里插入图片描述
  由于每次重定位时都会覆盖.rodata段的值,故而选择更改.rel.rodata段的值。根据输出的值4:7aB<MkW~,将.rel.rodata从0x648开始更改,可以知道原来分别对应.L12,.L27,.L22,.L26,.L4,.L23,.L16,.L11,.L8,.L10,根据偏移量将对应位置的对应信息更改,分别改成.L24,L24,.L20,.L28,.L18,.L28,.L28,.L22,.L24,.L29,
  如图所示:
在这里插入图片描述

3.5 阶段5的分析

  程序运行结果截图:
在这里插入图片描述
  分析与设计的过程:
  使用readlef查看phase5.o的信息:
  .rel.text从0x6e8起,占的内存为0xd8;.rel.rodata从0x7c0起,占0x40。
在这里插入图片描述
  查看相应信息,相应信息对应内容如下:

offset需要进行重定向的代码在.text或.data节中的偏移位置,4个字节。
info包括symbol和type两部分,其中symbol占前3个字节,type占后1个字节,symbol代表重定位到的目标在.symtab中的偏移量,type代表重定位的类型
Type重定位到的目标的类型
name重定位到的目标的名称

  与第四轮相同,一个重定位信息占8个字节,前4个字节代表offset,后四个字节代表info,其中info的高3个字节代表symbol是该symbol在.symtab中的Num,info的低1个字节代表type。
  将.rel.text的已有重定位信息整理如下,重定位的代码中8个缺少的部分,需要根据反汇编代码填写。
在这里插入图片描述
  其中可能存在的type类型如下:

info.type含义已知重定位目标
02R_386_PC32__X86.get_pc_thunk.bx , transform_code,generate_code,encode,__X86.get_pc_thunk.ax
0aR_386_GOTPCGLOBAL_OFFSET_TABLE
09R_386_GOTOFF.rodata , CODE,BUF
04R_386_PLT32strlen,puts

  查看.rel.rodata节,其中有.L3,.L5,.L2,.L6,.L7,.L8,.L2,.L9,均已填充完毕,无需更改.rel.rodata段
在这里插入图片描述
  再查看符号表.symtab中的具体信息,.L2,.L3,.L5,.L6,.L7,.L8,.L9在其中。
在这里插入图片描述
  根据以上OBJECT可推知UJXJSd, mvEQni,CODE,BUF为数组或数组中的内容。根据.symtab同样可以获取偏移量。
  查看具体代码:

const int TRAN_ARRAY[] = {… …};
const char FDICT[] = FDICTDAT;
char BUF[] = MYID; 
char CODE = PHASE5_COOKIE;int transform_code( int code, int mode )  {switch( TRAN_ARRAY [mode] & 0x00000007 )  {case 0:code = code & (~ TRAN_ARRAY[mode]);break;case 1:code = code ^ TRAN_ARRAY[mode];break;… …}return code;
}void generate_code( int cookie )  {int i;CODE = cookie;for( i=0; i<sizeof(TRAN_ARRAY)/sizeof(int); i++ )CODE = transform_code( CODE, i );
}int encode( char* str )  {int i, n = strlen(str);for( i=0; i<n; i++ ) {str[i] = (FDICT[str[i]] ^ CODE) & 0x7F;if( str[i]<0x20 || str[i]>0x7E ) str[i] = ' ';}return n;
}void do_phase()  {generate_code(PHASE5_COOKIE);encode(BUF);printf("%s\n", BUF);
}

  对反汇编代码进行说明和补充。
  由.rel.rodata段(图片在上面)可以知道//部分是已经填充好的。
  接下来对照代码根据功能填充(前面加了6个~)斜体部分,为了获取偏移量,我们根据反汇编代码将要更改的位置确定偏移量,根据.symtab表获取info的symbol(高3个字节)位,根据类型确定type(低一个字节)位。填充如下:

00000000 <transform_code>:0:	55                   	push   %ebp1:	89 e5                	mov    %esp,%ebp3:	e8 fc ff ff ff       	call   4 <transform_code+0x4>
~~~~~~//映射__x86.get_pc_thunk.ax         其offset为0x00000004     info为0x00001a028:	05 01 00 00 00       	add    $0x1,%eax
//映射_GLOBAL_OFFSET_TABLE_    其offset为0x00000009     info为0x00001b0a d:	8b 55 0c             	mov    0xc(%ebp),%edx                   //%edx为mode10:	8b 94 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%edx
//映射UJXJSd  TRAN_ARRAY          其offset为0x00000013     info为0x00001509   17:	83 e2 07             	and    $0x7,%edx1a:	83 fa 07             	cmp    $0x7,%edx1d:	77 68                	ja     87 <.L2>1f:	c1 e2 02             	shl    $0x2,%edx22:	8b 94 02 c0 00 00 00 	mov    0xc0(%edx,%eax,1),%edx
//映射.rodata段                              其offset为0x00000025     info为0x0000050929:	01 c2                	add    %eax,%edx2b:	ff e2                	jmp    *%edx0000002d <.L3>:2d:	f7 55 08             	notl   0x8(%ebp)30:	eb 59                	jmp    8b <.L2+0x4>00000032 <.L5>:32:	8b 55 0c             	mov    0xc(%ebp),%edx35:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x00000038    其info为0x000015093c:	83 e0 03             	and    $0x3,%eax3f:	89 c1                	mov    %eax,%ecx41:	d3 7d 08             	sarl   %cl,0x8(%ebp)44:	eb 45                	jmp    8b <.L2+0x4>00000046 <.L6>:46:	8b 55 0c             	mov    0xc(%ebp),%edx49:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
~~~~~~//映射UJXJSd        其offset为0x0000004c    其info为0x0000150950:	f7 d0                	not    %eax52:	21 45 08             	and    %eax,0x8(%ebp)55:	eb 34                	jmp    8b <.L2+0x4>00000057 <.L7>:57:	8b 55 0c             	mov    0xc(%ebp),%edx5a:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x0000005d    其info为0x0000150961:	c1 e0 08             	shl    $0x8,%eax64:	09 45 08             	or     %eax,0x8(%ebp)67:	eb 22                	jmp    8b <.L2+0x4>00000069 <.L8>:69:	8b 55 0c             	mov    0xc(%ebp),%edx6c:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
~~~~~~//映射UJXJSd        其offset为0x0000006f    其info为0x0000150973:	31 45 08             	xor    %eax,0x8(%ebp)76:	eb 13                	jmp    8b <.L2+0x4>00000078 <.L9>:78:	8b 55 0c             	mov    0xc(%ebp),%edx7b:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x0000007e    其info为0x0000150982:	89 45 08             	mov    %eax,0x8(%ebp)85:	eb 04                	jmp    8b <.L2+0x4>00000087 <.L2>:87:	f7 5d 08             	negl   0x8(%ebp)8a:	90                   	nop8b:	8b 45 08             	mov    0x8(%ebp),%eax8e:	5d                   	pop    %ebp8f:	c3                   	ret    00000090 <generate_code>:90:	55                   	push   %ebp91:	89 e5                	mov    %esp,%ebp93:	53                   	push   %ebx94:	83 ec 10             	sub    $0x10,%esp97:	e8 fc ff ff ff       	call   98 <generate_code+0x8>
~~~~~~//映射__x86.get_pc_thunk.bx    其offset为0x00000098  其info为0x00001d029c:	81 c3 02 00 00 00    	add    $0x2,%ebx
//映射_GLOBAL_OFFSET_TABLE_     其offset为0x0000009e    其info为0x00001b0aa2:	8b 45 08             	mov    0x8(%ebp),%eaxa5:	88 83 00 00 00 00    	mov    %al,0x0(%ebx)
//映射CODE      其offset为0x000000a7    其info为0x00001809ab:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)b2:	eb 20                	jmp    d4 <generate_code+0x44>b4:	0f b6 83 00 00 00 00 	movzbl 0x0(%ebx),%eax
~~~~~~//映射CODE   其offset为0x000000b7  其info为0x00001809bb:	0f be c0             	movsbl %al,%eaxbe:	ff 75 f8             	pushl  -0x8(%ebp)c1:	50                   	push   %eaxc2:	e8 fc ff ff ff       	call   c3 <generate_code+0x33>
//映射transform_code    其offset为0x000000c3   其info为0x00001902c7:	83 c4 08             	add    $0x8,%espca:	88 83 00 00 00 00    	mov    %al,0x0(%ebx)
~~~~~~//映射CODE     其offset为0x000000cc  其info为0x00001809   d0:	83 45 f8 01          	addl   $0x1,-0x8(%ebp)d4:	8b 45 f8             	mov    -0x8(%ebp),%eaxd7:	83 f8 0a             	cmp    $0xa,%eaxda:	76 d8                	jbe    b4 <generate_code+0x24>dc:	90                   	nopdd:	8b 5d fc             	mov    -0x4(%ebp),%ebxe0:	c9                   	leave  e1:	c3                   	ret    ktkk) q000000e2 <encode>:e2:	55                   	push   %ebpe3:	89 e5                	mov    %esp,%ebpe5:	53                   	push   %ebxe6:	83 ec 14             	sub    $0x14,%espe9:	e8 fc ff ff ff       	call   ea <encode+0x8>
//映射__x86.get_pc_thunk.bx    其offset为0x000000ea   其info为0x00001d02ee:	81 c3 02 00 00 00    	add    $0x2,%ebx
~~~~~~//映射_GLOBAL_OFFSET_TABLE_  其offset为0x000000f0   其info为0x00001b0af4:	83 ec 0c             	sub    $0xc,%espf7:	ff 75 08             	pushl  0x8(%ebp)fa:	e8 fc ff ff ff       	call   fb <encode+0x19>
//映射strlen    其offset为0x000000fb   其info为0x00001f04ff:	83 c4 10             	add    $0x10,%esp102:	89 45 f4             	mov    %eax,-0xc(%ebp)105:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)10c:	eb 5d                	jmp    16b <encode+0x89>10e:	8b 55 f0             	mov    -0x10(%ebp),%edx111:	8b 45 08             	mov    0x8(%ebp),%eax114:	01 d0                	add    %edx,%eax116:	0f b6 00             	movzbl (%eax),%eax119:	0f be c0             	movsbl %al,%eax11c:	0f b6 94 03 00 00 00 	movzbl 0x0(%ebx,%eax,1),%edx
//映射mvEQni    其offset为0x00000120   其info为0x00001609123:	00 124:	0f b6 83 00 00 00 00 	movzbl 0x0(%ebx),%eax
~~~~~~//映射CODE 其offset为0x00000127  其info为0x0000180912b:	89 d1                	mov    %edx,%ecx12d:	31 c1                	xor    %eax,%ecx12f:	8b 55 f0             	mov    -0x10(%ebp),%edx132:	8b 45 08             	mov    0x8(%ebp),%eax135:	01 d0                	add    %edx,%eax137:	83 e1 7f             	and    $0x7f,%ecx13a:	89 ca                	mov    %ecx,%edx13c:	88 10                	mov    %dl,(%eax)13e:	8b 55 f0             	mov    -0x10(%ebp),%edx141:	8b 45 08             	mov    0x8(%ebp),%eax144:	01 d0                	add    %edx,%eax146:	0f b6 00             	movzbl (%eax),%eax149:	3c 1f                	cmp    $0x1f,%al14b:	7e 0f                	jle    15c <encode+0x7a>14d:	8b 55 f0             	mov    -0x10(%ebp),%edx150:	8b 45 08             	mov    0x8(%ebp),%eax153:	01 d0                	add    %edx,%eax155:	0f b6 00             	movzbl (%eax),%eax158:	3c 7f                	cmp    $0x7f,%al15a:	75 0b                	jne    167 <encode+0x85>15c:	8b 55 f0             	mov    -0x10(%ebp),%edx15f:	8b 45 08             	mov    0x8(%ebp),%eax162:	01 d0                	add    %edx,%eax164:	c6 00 20             	movb   $0x20,(%eax)167:	83 45 f0 01          	addl   $0x1,-0x10(%ebp)16b:	8b 45 f0             	mov    -0x10(%ebp),%eax16e:	3b 45 f4             	cmp    -0xc(%ebp),%eax171:	7c 9b                	jl     10e <encode+0x2c>173:	8b 45 f4             	mov    -0xc(%ebp),%eax176:	8b 5d fc             	mov    -0x4(%ebp),%ebx179:	c9                   	leave  17a:	c3                   	ret    0000017b <do_phase>:17b:	55                   	push   %ebp17c:	89 e5                	mov    %esp,%ebp17e:	53                   	push   %ebx17f:	83 ec 04             	sub    $0x4,%esp182:	e8 fc ff ff ff       	call   183 <do_phase+0x8>
~~~~~~//映射__x86.get_pc_thunk.bx 其offset为0x00000183  其info为0x00001d02  187:	81 c3 02 00 00 00    	add    $0x2,%ebx
//映射_GLOBAL_OFFSET_TABLE_     其offset为0x00000189    其info为0x00001b0a18d:	68 ca 00 00 00       	push   $0xca192:	e8 fc ff ff ff       	call   193 <do_phase+0x18>
//映射generate_code   其offset为0x00000193  其info为0x00001c02197:	83 c4 04             	add    $0x4,%esp19a:	83 ec 0c             	sub    $0xc,%esp19d:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
//映射BUF   其offset为0x0000019f  其info为0x000017091a3:	50                   	push   %eax1a4:	e8 fc ff ff ff       	call   1a5 <do_phase+0x2a>
//映射encode   其offset为0x000001a5  其info为0x00001e021a9:	83 c4 10             	add    $0x10,%esp1ac:	83 ec 0c             	sub    $0xc,%esp1af:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
//映射BUF        其offset为0x000001b1  其info为0x000017091b5:	50                   	push   %eax1b6:	e8 fc ff ff ff       	call   1b7 <do_phase+0x3c>
//映射puts        其offset为0x000001b7  其info为0x000021041bb:	83 c4 10             	add    $0x10,%esp1be:	90                   	nop1bf:	8b 5d fc             	mov    -0x4(%ebp),%ebx1c2:	c9                   	leave  1c3:	c3                   	ret    Disassembly of section .text.__x86.get_pc_thunk.ax:00000000 <__x86.get_pc_thunk.ax>:0:	8b 04 24             	mov    (%esp),%eax3:	c3                   	ret    Disassembly of section .text.__x86.get_pc_thunk.bx:00000000 <__x86.get_pc_thunk.bx>:0:	8b 1c 24             	mov    (%esp),%ebx3:	c3                   	ret    

  按照上述规则按小端法填充,未填充时如下:
在这里插入图片描述
  填充时如下:
在这里插入图片描述

这篇关于HIT CSAPP LAB5的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/290552

相关文章

[学习笔记]《CSAPP》深入理解计算机系统 - Chapter 3 程序的机器级表示

总结一些第三章的一些关键信息 Chapter 3 程序的机器级表示结构 updating... Chapter 3 程序的机器级表示 局部变量通常保存在寄存器中,而不是内存中,访问寄存器比内存快的多. 有些时候,局部数据必须存放在内存中, 寄存器不足够存放所有的本地数据对一个局部变量使用地址运算符 &, 因此必须能够为它产生一个地址某些局部变量是数组或结构,因此必须能够通过数组或

CSAPP Data Lab

CSAPP 的第一个 Lab,对应知识点为书中的第 2 章(信息的表示与处理),要求使用受限制的运算符和表达式实现一些位操作。主要分为两个部分:整数部分和浮点数部分。其中整数部分限制较多,比较偏重技巧性,部分题个人认为很有难度。而浮点数部分则比较基础,主要考察对 IEEE 754 标准的熟悉程度,代码较长,但思路相对简单。 bitXor 思路 使用德-摩根定律进行推导,推导过程如下: 代

1003 Hit or Miss

又是个坑了我2小时WA到吐的大水题,狗血题目就看了我半天!真是无力吐槽那坑爹的英文题目的描述了。 1.开始以为是几个玩家同步报数匹配,其实是轮流报数匹配,即:A->B->C->D->A->B->C->D->A->B.......  2. 大致流程是:A做一次报数,如果没有match,放回A自己的底部。如果match了,放到B的底部。A做完一次报数后,轮到B报数(注意只有当B有牌时才报数),如果

深入理解计算机系统 CSAPP 第七章 与静态库链接

//addvec.cint addcnt = 0;void addvec(int *x ,int *y,int *z,int n){int i;addcnt++;for(i=0;i<n;i++)z[i]=x[i]+y[i];} //multvec.cint multcnt = 0;void multvec(int *x ,int *y,int *z,int n){int i;mult

CSAPP《深入理解计算机系统》深读笔记4——第三章-程序的机器级表示(一)

CSAPP《深入理解计算机系统》深读笔记4——第三章-程序的机器级表示(一) 你好我是拉依达,这是我秋招结束后更新的第一个系列。我将争取完成“ 年轻人,你渴望力量吗?”的全套深度笔记。 今天开始进行第一本CSAPP:深入理解计算机系统。 程序的机器级表示 编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。 GCC C语言编译器以汇编代码的形式

深入理解计算机系统 CSAPP 家庭作业6.35

第一步先求(S,E,B,m) 题目说共C=128个字节,块大小B为16个字节,那就是分为八组:0,1,2,3,4,5,6,7.然后每组存4个int 每个4字节 C=B*E*S .B=16 ,直接映射的E就是1,所以S=8 (S,E,B,m)=(8,1,16,7) C128M128s3b4t0 sizeof(int)==0100地址(二进制)COCIsrc[0][0]00000

深入理解计算机系统 CSAPP 家庭作业6.37

S=256 N=64时: sumA:这个很简单了,不说了 sumB:如下表. i递增时一直不命中 读到j=1,i=0 即读a[0][1]时 组0存放的是a[48][0] -a[48][3] 接着读a[1][1]时,组16放的是a[49][0]-a[49][3],j递增之后还是一直不命中 组0:a[0][0]a[16][0]a[32][0]a[48][0]a[0][1]组16:a

CSAPP-02程序开发和执行过程

1.最早的程序开发过程 2.汇编语言开发过程 3.高级语言开发程序 参考:袁春风老师课件

CSAPP-01计算机系统基本组成与基本功能

1.冯·诺依曼结构计算机模型 2.现代计算机结构模型 注:忽略做菜的例子 3.计算机系统的抽象层转换 参考:南京大学袁春风老师课件