-
-
[求助]关于堆溢出的double free中unlink()绕过的疑惑
-
发表于:
2018-1-15 15:01
3775
-
[求助]关于堆溢出的double free中unlink()绕过的疑惑
因为个人搞不清楚unlink()宏里面的检查(__builtin_expect (FD->bk != P || BK->fd != P, 0))是怎么绕过的,所以比葫芦画瓢写了一个小程序,用来复现一下这个宏的检查绕过。没想到还是没弄明白,
代码如下:
#include <stdio.h>
#include <stdlib.h>
unsigned int a[5];//这个是保存链表中指针的数组
unsigned int d;
//以下unlink摘自malloc.c
#define unlink(P,BK,FD){\
/*FD = P->fd;\
BK = P->bk;\ */\
d=a+2;\
FD=d-0x18;\
BK=d-0x10;\
printf("FD->bk:%x\n",FD->bk);\
printf("p:%x\n",P);\
printf("BK->fd:%x\n",BK->fd);\
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))\
printf ("corrupted double-linked list\n");\
else {\
FD->bk = BK;\
BK->fd = FD;\
}\
}
struct s
{
long int b;
long int c;
struct s *fd;
struct s *bk;
};
main ()
{
struct s *FD;
struct s *BK;
struct s *p1 = malloc (sizeof (struct s));
a[0] = p1;
p1->b = 1;
struct s *p2 = malloc (sizeof (struct s));
a[1] = p2;
p2->b = 2;
struct s *p3 = malloc (sizeof (struct s));
p3->b = 3;
a[2] = p3;
printf ("%x\n", p3);
struct s *p4 = malloc (sizeof (struct s));
a[3] = p4;
p4->b = 4;
struct s *p5 = malloc (sizeof (struct s));
a[4] = p5;
p5->b = 5;
p1->fd = p2;
p2->fd = p3;
p3->fd = p4;
p4->fd = p5;
p5->bk = p4;
p4->bk = p3;
p3->bk = p2;
p2->bk = p1;
struct s *p;
p = p1;
while (p != NULL)//输出一次链表
{
printf ("%d->", p->b);
p = p->fd;
}
printf ("\n");
unlink (p3, FD, BK);//调用unlink宏,摘p3
p = p1;
while (p != NULL)//摘完之后,再打印链表
{
printf ("%d->", p->b);
p = p->fd;
}
free (p1);
free (p2);
free (p3);
free (p4);
free (p5);
}
如程序所示,p1->p2->p3->p4->p5是一个链表,目标是用unlink宏把p3摘掉。
程序执行完以后,输出如下:
[test@localhost 4-ReeHY-main]$ ./2
17a2070 //p3
1->2->3->4->5-> //没尝试摘之前的链表
FD->bk:17a2070 //进入宏以后,可以看到,这里FD->bk是和P相等的
p:17a2070
BK->fd:17a2070
//可以看到,这里BK->fd也是和P相等的
corrupted double-linked list //但是,并没有绕过这个检查,下面输出的还是原来的链表
1->2->3->4->5->[test@localhost 4-ReeHY-main]$
请哪位明眼的大大指正一下,究竟怎样才能绕过这个宏里面的检查?(是只针对这个小程序),究竟是哪里出错了
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!