实验报告
实 验(五)
题 目 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分)................ - 5 -
2.2请按照内存地址从低到高的顺序,写出Linux下X64内存映像。(5分) 错误!未定义书签。
2.3请运行“LinkAddress -u 学号 姓名” 按地址循序写出各符号的地址、空间。并按照Linux下X64内存映像标出其所属各区。........................................................................... - 6 -
(5分).................................................................................................................... - 6 -
2.4请按顺序写出LinkAddress从开始执行到main前/后执行的子程序的名字。(gcc与objdump/GDB/EDB)(5分)............................................................................... - 10 -
第3章 各阶段的原理与方法.................................................................................. - 12 -
3.1 阶段1的分析.................................................................................................. - 12 -
3.2 阶段2的分析................................................................................................ - 13 -
3.3 阶段3的分析................................................................................................ - 16 -
3.4 阶段4的分析................................................................................................ - 19 -
3.5 阶段5的分析................................................................................................ - 19 -
第4章 总结.............................................................................................................. - 20 -
4.1 请总结本次实验的收获.................................................................................. - 20 -
4.2 请给出对本次实验内容的建议...................................................................... - 20 -
参考文献.................................................................................................................... - 21 -
理解链接的作用与工作步骤
掌握ELF结构、符号解析与重定位的工作过程
熟练使用Linux工具完成ELF分析与修改
上实验课前,必须认真预习实验指导书(PPT或PDF)
了解实验的目的、实验环境与软硬件工具、实验操作步骤,复习与实验有关的理论知识。
请按顺序写出ELF格式的可执行目标文件的各类信息。
请按照内存地址从低到高的顺序,写出Linux下X64内存映像。
请运行“LinkAddress -u 学号 姓名” 按地址顺序写出各符号的地址、空间。并按照Linux下X64内存映像标出其所属各区。
请按顺序写出LinkAddress从开始执行到main前/后执行的子程序的名字。(gcc与objdump/GDB/EDB)
ELF头
段头部表:将连续的文件映射到运行时的内存段
. init : 定义了_init函数,程序初始化代码会调用它
. text : 已编译程序的机器代码
. rodata : 只读数据,比如printf语句中的格式串和开关语句的跳转表
. data : 已初始化的全局和静态C变量
. bss : 未初始化的全局和静态C变量
. symtab :一个符号表,它存放在程序中定义和引用的函数和全局变量的信息
. debug : 一个调试符号表,其条目时程序中定义的全局变量和类型定义,程序中定义和引用的全局变量,以及原始的C源文件。
. line : 原始C源程序的行号和.text节中机器指令之间的映射
. strtab : 一个字符串表,其内容包括 .symtab 和 .debug节中的符号表,以及节头部中的节名字。
节头部表:描述目标文件的节。
所属区 |
各符号的地址、空间(地址从小到大) |
只读代码段(.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 0x7fd9f7587010 140574134398992 p2 0x435e2420 1130243104 p3 0x7fda07b38010 140574408802320 p4 0x7fd9b7586010 140573060653072 p5 (nil) 0 |
用户栈(运行时创建) |
argc 0x7ffe1beb339c 140729366819740 local 0x7ffe1beb33a0 140729366819744 argv 0x7ffe1beb34c8 140729366820040 argv[0] 7ffe1beb52ec argv[1] 7ffe1beb52fa argv[2] 7ffe1beb52fd argv[3] 7ffe1beb5308 argv[0] 0x7ffe1beb52ec 140729366827756 ./linkaddress argv[1] 0x7ffe1beb52fa 140729366827770 -u argv[2] 0x7ffe1beb52fd 140729366827773 1171000410 argv[3] 0x7ffe1beb5308 140729366827784 env 0x7ffe1beb34f0 140729366820080 env[0] *env 0x7ffe1beb5312 140729366827794 XDG_VTNR=7 env[1] *env 0x7ffe1beb531d 140729366827805 XDG_SESSION_ID=c2 env[2] *env 0x7ffe1beb532f 140729366827823 CLUTTER_IM_MODULE=xim env[3] *env 0x7ffe1beb5345 140729366827845 XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/qwj env[4] *env 0x7ffe1beb5374 140729366827892 GPG_AGENT_INFO=/home/qwj/.gnupg/S.gpg-agent:0:1 env[5] *env 0x7ffe1beb53a4 140729366827940 SHELL=/bin/bash env[6] *env 0x7ffe1beb53b4 140729366827956 TERM=xterm-256color env[7] *env 0x7ffe1beb53c8 140729366827976 VTE_VERSION=4205 env[8] *env 0x7ffe1beb53d9 140729366827993 QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1 env[9] *env 0x7ffe1beb53fc 140729366828028 WINDOWID=52429582 env[10] *env 0x7ffe1beb540e 140729366828046 UPSTART_SESSION=unix:abstract=/com/ubuntu/upstart-session/1000/1676 env[11] *env 0x7ffe1beb5452 140729366828114 GNOME_KEYRING_CONTROL= env[12] *env 0x7ffe1beb5469 140729366828137 GTK_MODULES=gail:atk-bridge:unity-gtk-module env[13] *env 0x7ffe1beb5496 140729366828182 USER=qwj env[14] *env 0x7ffe1beb549f 140729366828191 env[15] *env 0x7ffe1beb5a27 140729366829607 QT_ACCESSIBILITY=1 env[16] *env 0x7ffe1beb5a3a 140729366829626 XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0 env[17] *env 0x7ffe1beb5a74 140729366829684 XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0 env[18] *env 0x7ffe1beb5aa8 140729366829736 SSH_AUTH_SOCK=/run/user/1000/keyring/ssh env[19] *env 0x7ffe1beb5ad1 140729366829777 DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path env[20] *env 0x7ffe1beb5b04 140729366829828 XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg env[21] *env 0x7ffe1beb5b48 140729366829896 PATH=/home/qwj/bin:/home/qwj/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin env[22] *env 0x7ffe1beb5bd3 140729366830035 DESKTOP_SESSION=ubuntu env[23] *env 0x7ffe1beb5bea 140729366830058 QT_IM_MODULE=fcitx env[24] *env 0x7ffe1beb5bfd 140729366830077 QT_QPA_PLATFORMTHEME=appmenu-qt5 env[25] *env 0x7ffe1beb5c1e 140729366830110 XDG_SESSION_TYPE=x11 env[26] *env 0x7ffe1beb5c33 140729366830131 PWD=/home/qwj/hitics/linklab-1171000410 env[27] *env 0x7ffe1beb5c5b 140729366830171 JOB=gnome-session env[28] *env 0x7ffe1beb5c6d 140729366830189 XMODIFIERS=@im=fcitx env[29] *env 0x7ffe1beb5c82 140729366830210 GNOME_KEYRING_PID= env[30] *env 0x7ffe1beb5c95 140729366830229 LANG=zh_CN.UTF-8 env[31] *env 0x7ffe1beb5ca6 140729366830246 GDM_LANG=zh_CN env[32] *env 0x7ffe1beb5cb5 140729366830261 MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path env[33] *env 0x7ffe1beb5ceb 140729366830315 IM_CONFIG_PHASE=1 env[34] *env 0x7ffe1beb5cfd 140729366830333 COMPIZ_CONFIG_PROFILE=ubuntu env[35] *env 0x7ffe1beb5d1a 140729366830362 GDMSESSION=ubuntu env[36] *env 0x7ffe1beb5d2c 140729366830380 SESSIONTYPE=gnome-session env[37] *env 0x7ffe1beb5d46 140729366830406 GTK2_MODULES=overlay-scrollbar env[38] *env 0x7ffe1beb5d65 140729366830437 HOME=/home/qwj env[39] *env 0x7ffe1beb5d74 140729366830452 XDG_SEAT=seat0 env[40] *env 0x7ffe1beb5d83 140729366830467 SHLVL=1 env[41] *env 0x7ffe1beb5d8b 140729366830475 LANGUAGE=zh_CN:zh env[42] *env 0x7ffe1beb5d9d 140729366830493 GNOME_DESKTOP_SESSION_ID=this-is-deprecated env[43] *env 0x7ffe1beb5dc9 140729366830537 UPSTART_INSTANCE= env[44] *env 0x7ffe1beb5ddb 140729366830555 UPSTART_EVENTS=started starting env[45] *env 0x7ffe1beb5dfb 140729366830587 XDG_SESSION_DESKTOP=ubuntu env[46] *env 0x7ffe1beb5e16 140729366830614 LOGNAME=qwj env[47] *env 0x7ffe1beb5e22 140729366830626 QT4_IM_MODULE=fcitx env[48] *env 0x7ffe1beb5e36 140729366830646 XDG_DATA_DIRS=/usr/share/ubuntu:/usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop env[49] *env 0x7ffe1beb5e9a 140729366830746 DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-7GaiE8N1nK env[50] *env 0x7ffe1beb5ed6 140729366830806 LESSOPEN=| /usr/bin/lesspipe %s env[51] *env 0x7ffe1beb5ef6 140729366830838 INSTANCE=Unity env[52] *env 0x7ffe1beb5f05 140729366830853 UPSTART_JOB=unity-settings-daemon env[53] *env 0x7ffe1beb5f27 140729366830887 XDG_RUNTIME_DIR=/run/user/1000 env[54] *env 0x7ffe1beb5f46 140729366830918 DISPLAY=:0 env[55] *env 0x7ffe1beb5f51 140729366830929 XDG_CURRENT_DESKTOP=Unity env[56] *env 0x7ffe1beb5f6b 140729366830955 GTK_IM_MODULE=fcitx env[57] *env 0x7ffe1beb5f7f 140729366830975 LESSCLOSE=/usr/bin/lesspipe %s %s env[58] *env 0x7ffe1beb5fa1 140729366831009 XAUTHORITY=/home/qwj/.Xauthority env[59] *env 0x7ffe1beb5fc2 140729366831042 OLDPWD=/home/qwj/hitics env[60] *env 0x7ffe1beb5fda 140729366831066 _=./linkaddress |
main执行前:
Breakpoint 1 at 0x400598
Breakpoint 2 at 0x4005d0
Breakpoint 3 at 0x4005e0
Breakpoint 4 at 0x4005f0
Breakpoint 5 at 0x400600
Breakpoint 6 at 0x400610
Breakpoint 7 at 0x400620
Breakpoint 8 at 0x400630
Breakpoint 9 at 0x400650
Breakpoint 10 at 0x400680
Breakpoint 11 at 0x4006c0
Breakpoint 12 at 0x400700
Breakpoint 13 at 0x400720
Breakpoint 14 at 0x40074a
Breakpoint 15 at 0x40077b
main执行后:
Breakpoint 16 at 0x400786
Breakpoint 17 at 0x400b10
Breakpoint 18 at 0x400b80
Breakpoint 19 at 0x400b84
每阶段40分,phasex.o 20分,分析20分,总分不超过80分
程序运行结果截图:
分析与设计的过程:
首先readelf -a phase1.o 查看elf文件内容,根据节头信息可知,字符串输出起始地址在 .data 节中偏移量为32的位置。
然后先gcc -m32 -o linkbomb1 main.o phase1.o 链接后,运行linkbomb程序,查看输出的字符串如上图。
最后使用hexedit工具,进入phase1.o ,之后有两种方法:一是直接找到以上的字符串,并将其对应的ascii编码修改;二是根据以上的分析,找到 .data节偏移量为32 的位置,并修改ascii码(很明显两种方法的效果相同)。
学号1171000410对应的ascii码为:31 31 37 31 30 30 30 34 31 30 ,最后再以00表示字符串结束,于是得到以下的修改结果。再次链接并且运行linkbomb1即可输出1171000410
程序运行结果截图:
分析与设计的过程:
首先将文件链接,gcc -m32 -o linkbomb2 main.o phase.o ,然后使用gdb对qmNFFwCm函数进行调试。
单步执行到如图所示的位置,查看寄存器%eax,发现存的正是我们的学号。
再分析strcmp函数,根据ppt给的提示,执行strcmp之前向栈中压入了两个参数,一个是MYID,另一个则是函数传入的参数。因此,整道题的逻辑就是,在do_phase函数的nop部分,执行压栈,并且跳转到qmNFFwCm函数。
根据查询, call 0x804848f <__x86.get_pc_thunk.ax> 和add $0x1b24,%eax
指令,实现了%eax指向_GLOBAL_OFFSET_TABLE,同样的 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 函数跳转到qmNFFwCm函数 。
使用gdb调试可知qmNFFwCm函数的地址为0x08048493 ,而do_phase函数执行到lea -0x19fc(%eax),%eax时%eax的值为0x8048604 ,根据二者的差值,即可跳转%eax减去0x171处的地址。
于是汇编代码如下:
最后将得到的反汇编代码使用hexedit插入第一个nop处即可。
程序运行结果截图:
分析与设计的过程:
首先,分析do_phase的反汇编指令,获取COOKIE字符串。gcc -m32 -o linkbomb3 main.o phase3.o链接之后,使用gdb进行调试, 通过调试指令si即可进入do_phase函数,通过分析do_phase函数,可得到如下的循环部分:
再查看 %ebp-0x17出的内容,即可得到COOKIE字符串。
第二步. 根据符号表,找到映射数组的变量名。
变量类型为COM ,长度为256个字节 ,并且就是do_phase框架中的PHASE3_CODEBOOK 。
由此不难写出phase3.c 程序框架如下:
char JUbhpBDEMv[256];
void do_phase(){
const char char cookie[] = "mdblgtcjae";
for( int i=0; i printf( "%c", JUbhpBDEMv [ (unsigned char)(cookie[i]) ] ); printf( "\n" ); } 第三步。 得到cookie字符串所对应的ASCII码值为:109 100 98 108 103 116 99 106 97 101 ,根据程序输出的顺序,我们只需要在JUbhpBDEMv[] 数组中,并且COOKIE的ASCII码对应的位置输入自己的学号即可,其余位置不输出,可随便填入 phase_patch.c中的代码如下: 最后再将phase_patch.c编译的文件phase_patch.o和main.o 和phase3.o链接在一起,运行linkbomb3即可显示学号1171000410 . 程序运行结果截图: 分析与设计的过程: 程序运行结果截图: 分析与设计的过程: 对链接的作用和工作步骤有了更深的理解; 学会使用readelf工具查看elf可重定位目标文件; 学会使用hexedit对 .o文件进行修改 掌握了链接过程中的符号解析和重定位的过程 注:本章为酌情加分项。 为完成本次实验你翻阅的书籍与网站等 [1] 林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42. [2] 辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999. [3] 赵耀东. 新时代的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5). [4] 谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13. [5] KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064. [6] CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.3.4 阶段4的分析
3.5 阶段5的分析
第4章 总结
4.1 请总结本次实验的收获
4.2 请给出对本次实验内容的建议
参考文献