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地址+8
    printf("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-i386

Disassembly of section .text:

00000000 <cbLxqPqM>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	53                   	push   %ebx
   4:	83 ec 04             	sub    $0x4,%esp
   7:	e8 fc ff ff ff       	call   8 <cbLxqPqM+0x8>
   c:	81 c3 02 00 00 00    	add    $0x2,%ebx
  12:	83 ec 08             	sub    $0x8,%esp
  15:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
  1b:	50                   	push   %eax
  1c:	ff 75 08             	pushl  0x8(%ebp)
  1f:	e8 fc ff ff ff       	call   20 <cbLxqPqM+0x20>
  24:	83 c4 10             	add    $0x10,%esp
  27:	85 c0                	test   %eax,%eax
  29:	75 10                	jne    3b <cbLxqPqM+0x3b>
  2b:	83 ec 0c             	sub    $0xc,%esp
  2e:	ff 75 08             	pushl  0x8(%ebp)
  31:	e8 fc ff ff ff       	call   32 <cbLxqPqM+0x32>
  36:	83 c4 10             	add    $0x10,%esp
  39:	eb 01                	jmp    3c <cbLxqPqM+0x3c>
  3b:	90                   	nop
  3c:	8b 5d fc             	mov    -0x4(%ebp),%ebx
  3f:	c9                   	leave  
  40:	c3                   	ret    

00000041 <do_phase>:
  41:	55                   	push   %ebp
  42:	89 e5                	mov    %esp,%ebp
  44:	e8 fc ff ff ff       	call   45 <do_phase+0x4>
  49:	05 01 00 00 00       	add    $0x1,%eax
  4e:	90                   	nop
  4f:	90                   	nop
  50:	90                   	nop
  51:	90                   	nop
  52:	90                   	nop
  53:	90                   	nop
  54:	90                   	nop
  55:	90                   	nop
  56:	90                   	nop
  57:	90                   	nop
  58:	90                   	nop
  59:	90                   	nop
  5a:	90                   	nop
  5b:	90                   	nop
  5c:	90                   	nop
  5d:	90                   	nop
  5e:	90                   	nop
  5f:	90                   	nop
  60:	90                   	nop
  61:	90                   	nop
  62:	90                   	nop
  63:	90                   	nop
  64:	90                   	nop
  65:	90                   	nop
  66:	90                   	nop
  67:	90                   	nop
  68:	90                   	nop
  69:	90                   	nop
  6a:	90                   	nop
  6b:	90                   	nop
  6c:	90                   	nop
  6d:	90                   	nop
  6e:	90                   	nop
  6f:	5d                   	pop    %ebp
  70:	c3                   	ret    

Disassembly of section .text.__x86.get_pc_thunk.ax:

00000000 <__x86.get_pc_thunk.ax>:
   0:	8b 04 24             	mov    (%esp),%eax
   3:	c3                   	ret    

Disassembly of section .text.__x86.get_pc_thunk.bx:

00000000 <__x86.get_pc_thunk.bx>:
   0:	8b 1c 24             	mov    (%esp),%ebx
   3:	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-i386


Disassembly of section .text:

00000000 <do_phase>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	53                   	push   %ebx
   4:	83 ec 24             	sub    $0x24,%esp
   7:	e8 fc ff ff ff       	call   8 <do_phase+0x8>
   c:	81 c3 02 00 00 00    	add    $0x2,%ebx
  12:	65 a1 14 00 00 00    	mov    %gs:0x14,%eax
  18:	89 45 f4             	mov    %eax,-0xc(%ebp)
  1b:	31 c0                	xor    %eax,%eax
  1d:	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),%edx
  41:	8b 45 e4             	mov    -0x1c(%ebp),%eax
  44:	01 d0                	add    %edx,%eax
  46:	0f b6 00             	movzbl (%eax),%eax
  49:	0f b6 c0             	movzbl %al,%eax
  4c:	8b 93 00 00 00 00    	mov    0x0(%ebx),%edx
  52:	0f b6 04 02          	movzbl (%edx,%eax,1),%eax
  56:	0f be c0             	movsbl %al,%eax
  59:	83 ec 0c             	sub    $0xc,%esp
  5c:	50                   	push   %eax
  5d:	e8 fc ff ff ff       	call   5e <do_phase+0x5e>
  62:	83 c4 10             	add    $0x10,%esp
  65:	83 45 e4 01          	addl   $0x1,-0x1c(%ebp)
  69:	8b 45 e4             	mov    -0x1c(%ebp),%eax
  6c:	83 f8 09             	cmp    $0x9,%eax
  6f:	76 cd                	jbe    3e <do_phase+0x3e>
  71:	83 ec 0c             	sub    $0xc,%esp
  74:	6a 0a                	push   $0xa
  76:	e8 fc ff ff ff       	call   77 <do_phase+0x77>
  7b:	83 c4 10             	add    $0x10,%esp
  7e:	90                   	nop
  7f:	8b 45 f4             	mov    -0xc(%ebp),%eax
  82:	65 33 05 14 00 00 00 	xor    %gs:0x14,%eax
  89:	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),%ebx
  93:	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),%ebx
   3:	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   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	e8 fc ff ff ff       	call   4 <transform_code+0x4>
~~~~~~//映射__x86.get_pc_thunk.ax         其offset为0x00000004     info为0x00001a02
   8:	05 01 00 00 00       	add    $0x1,%eax
//映射_GLOBAL_OFFSET_TABLE_    其offset为0x00000009     info为0x00001b0a 
   d:	8b 55 0c             	mov    0xc(%ebp),%edx                   //%edx为mode
  10:	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,%edx
  1a:	83 fa 07             	cmp    $0x7,%edx
  1d:	77 68                	ja     87 <.L2>
  1f:	c1 e2 02             	shl    $0x2,%edx
  22:	8b 94 02 c0 00 00 00 	mov    0xc0(%edx,%eax,1),%edx
//映射.rodata段                              其offset为0x00000025     info为0x00000509
  29:	01 c2                	add    %eax,%edx
  2b:	ff e2                	jmp    *%edx

0000002d <.L3>:
  2d:	f7 55 08             	notl   0x8(%ebp)
  30:	eb 59                	jmp    8b <.L2+0x4>

00000032 <.L5>:
  32:	8b 55 0c             	mov    0xc(%ebp),%edx
  35:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x00000038    其info为0x00001509
  3c:	83 e0 03             	and    $0x3,%eax
  3f:	89 c1                	mov    %eax,%ecx
  41:	d3 7d 08             	sarl   %cl,0x8(%ebp)
  44:	eb 45                	jmp    8b <.L2+0x4>

00000046 <.L6>:
  46:	8b 55 0c             	mov    0xc(%ebp),%edx
  49:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
~~~~~~//映射UJXJSd        其offset为0x0000004c    其info为0x00001509
  50:	f7 d0                	not    %eax
  52:	21 45 08             	and    %eax,0x8(%ebp)
  55:	eb 34                	jmp    8b <.L2+0x4>

00000057 <.L7>:
  57:	8b 55 0c             	mov    0xc(%ebp),%edx
  5a:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x0000005d    其info为0x00001509
  61:	c1 e0 08             	shl    $0x8,%eax
  64:	09 45 08             	or     %eax,0x8(%ebp)
  67:	eb 22                	jmp    8b <.L2+0x4>

00000069 <.L8>:
  69:	8b 55 0c             	mov    0xc(%ebp),%edx
  6c:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
~~~~~~//映射UJXJSd        其offset为0x0000006f    其info为0x00001509
  73:	31 45 08             	xor    %eax,0x8(%ebp)
  76:	eb 13                	jmp    8b <.L2+0x4>

00000078 <.L9>:
  78:	8b 55 0c             	mov    0xc(%ebp),%edx
  7b:	8b 84 90 00 00 00 00 	mov    0x0(%eax,%edx,4),%eax
//映射UJXJSd        其offset为0x0000007e    其info为0x00001509
  82:	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                   	nop
  8b:	8b 45 08             	mov    0x8(%ebp),%eax
  8e:	5d                   	pop    %ebp
  8f:	c3                   	ret    

00000090 <generate_code>:
  90:	55                   	push   %ebp
  91:	89 e5                	mov    %esp,%ebp
  93:	53                   	push   %ebx
  94:	83 ec 10             	sub    $0x10,%esp
  97:	e8 fc ff ff ff       	call   98 <generate_code+0x8>
~~~~~~//映射__x86.get_pc_thunk.bx    其offset为0x00000098  其info为0x00001d02
  9c:	81 c3 02 00 00 00    	add    $0x2,%ebx
//映射_GLOBAL_OFFSET_TABLE_     其offset为0x0000009e    其info为0x00001b0a
  a2:	8b 45 08             	mov    0x8(%ebp),%eax
  a5:	88 83 00 00 00 00    	mov    %al,0x0(%ebx)
//映射CODE      其offset为0x000000a7    其info为0x00001809
  ab:	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为0x00001809
  bb:	0f be c0             	movsbl %al,%eax
  be:	ff 75 f8             	pushl  -0x8(%ebp)
  c1:	50                   	push   %eax
  c2:	e8 fc ff ff ff       	call   c3 <generate_code+0x33>
//映射transform_code    其offset为0x000000c3   其info为0x00001902
  c7:	83 c4 08             	add    $0x8,%esp
  ca:	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),%eax
  d7:	83 f8 0a             	cmp    $0xa,%eax
  da:	76 d8                	jbe    b4 <generate_code+0x24>
  dc:	90                   	nop
  dd:	8b 5d fc             	mov    -0x4(%ebp),%ebx
  e0:	c9                   	leave  
  e1:	c3                   	ret    
   ktkk) q

000000e2 <encode>:
  e2:	55                   	push   %ebp
  e3:	89 e5                	mov    %esp,%ebp
  e5:	53                   	push   %ebx
  e6:	83 ec 14             	sub    $0x14,%esp
  e9:	e8 fc ff ff ff       	call   ea <encode+0x8>
//映射__x86.get_pc_thunk.bx    其offset为0x000000ea   其info为0x00001d02
  ee:	81 c3 02 00 00 00    	add    $0x2,%ebx
~~~~~~//映射_GLOBAL_OFFSET_TABLE_  其offset为0x000000f0   其info为0x00001b0a
  f4:	83 ec 0c             	sub    $0xc,%esp
  f7:	ff 75 08             	pushl  0x8(%ebp)
  fa:	e8 fc ff ff ff       	call   fb <encode+0x19>
//映射strlen    其offset为0x000000fb   其info为0x00001f04
  ff:	83 c4 10             	add    $0x10,%esp
 102:	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),%edx
 111:	8b 45 08             	mov    0x8(%ebp),%eax
 114:	01 d0                	add    %edx,%eax
 116:	0f b6 00             	movzbl (%eax),%eax
 119:	0f be c0             	movsbl %al,%eax
 11c:	0f b6 94 03 00 00 00 	movzbl 0x0(%ebx,%eax,1),%edx
//映射mvEQni    其offset为0x00000120   其info为0x00001609
 123:	00 
 124:	0f b6 83 00 00 00 00 	movzbl 0x0(%ebx),%eax
~~~~~~//映射CODE 其offset为0x00000127  其info为0x00001809
 12b:	89 d1                	mov    %edx,%ecx
 12d:	31 c1                	xor    %eax,%ecx
 12f:	8b 55 f0             	mov    -0x10(%ebp),%edx
 132:	8b 45 08             	mov    0x8(%ebp),%eax
 135:	01 d0                	add    %edx,%eax
 137:	83 e1 7f             	and    $0x7f,%ecx
 13a:	89 ca                	mov    %ecx,%edx
 13c:	88 10                	mov    %dl,(%eax)
 13e:	8b 55 f0             	mov    -0x10(%ebp),%edx
 141:	8b 45 08             	mov    0x8(%ebp),%eax
 144:	01 d0                	add    %edx,%eax
 146:	0f b6 00             	movzbl (%eax),%eax
 149:	3c 1f                	cmp    $0x1f,%al
 14b:	7e 0f                	jle    15c <encode+0x7a>
 14d:	8b 55 f0             	mov    -0x10(%ebp),%edx
 150:	8b 45 08             	mov    0x8(%ebp),%eax
 153:	01 d0                	add    %edx,%eax
 155:	0f b6 00             	movzbl (%eax),%eax
 158:	3c 7f                	cmp    $0x7f,%al
 15a:	75 0b                	jne    167 <encode+0x85>
 15c:	8b 55 f0             	mov    -0x10(%ebp),%edx
 15f:	8b 45 08             	mov    0x8(%ebp),%eax
 162:	01 d0                	add    %edx,%eax
 164:	c6 00 20             	movb   $0x20,(%eax)
 167:	83 45 f0 01          	addl   $0x1,-0x10(%ebp)
 16b:	8b 45 f0             	mov    -0x10(%ebp),%eax
 16e:	3b 45 f4             	cmp    -0xc(%ebp),%eax
 171:	7c 9b                	jl     10e <encode+0x2c>
 173:	8b 45 f4             	mov    -0xc(%ebp),%eax
 176:	8b 5d fc             	mov    -0x4(%ebp),%ebx
 179:	c9                   	leave  
 17a:	c3                   	ret    

0000017b <do_phase>:
 17b:	55                   	push   %ebp
 17c:	89 e5                	mov    %esp,%ebp
 17e:	53                   	push   %ebx
 17f:	83 ec 04             	sub    $0x4,%esp
 182:	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为0x00001b0a
 18d:	68 ca 00 00 00       	push   $0xca
 192:	e8 fc ff ff ff       	call   193 <do_phase+0x18>
//映射generate_code   其offset为0x00000193  其info为0x00001c02
 197:	83 c4 04             	add    $0x4,%esp
 19a:	83 ec 0c             	sub    $0xc,%esp
 19d:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
//映射BUF   其offset为0x0000019f  其info为0x00001709
 1a3:	50                   	push   %eax
 1a4:	e8 fc ff ff ff       	call   1a5 <do_phase+0x2a>
//映射encode   其offset为0x000001a5  其info为0x00001e02
 1a9:	83 c4 10             	add    $0x10,%esp
 1ac:	83 ec 0c             	sub    $0xc,%esp
 1af:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
//映射BUF        其offset为0x000001b1  其info为0x00001709
 1b5:	50                   	push   %eax
 1b6:	e8 fc ff ff ff       	call   1b7 <do_phase+0x3c>
//映射puts        其offset为0x000001b7  其info为0x00002104
 1bb:	83 c4 10             	add    $0x10,%esp
 1be:	90                   	nop
 1bf:	8b 5d fc             	mov    -0x4(%ebp),%ebx
 1c2:	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),%eax
   3:	c3                   	ret    

Disassembly of section .text.__x86.get_pc_thunk.bx:

00000000 <__x86.get_pc_thunk.bx>:
   0:	8b 1c 24             	mov    (%esp),%ebx
   3:	c3                   	ret    

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

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值