首页
社区
课程
招聘
[求助]关于堆溢出的double free中unlink()绕过的疑惑
发表于: 2018-1-15 15:01 3760

[求助]关于堆溢出的double free中unlink()绕过的疑惑

2018-1-15 15:01
3760
因为个人搞不清楚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]$

请哪位明眼的大大指正一下,究竟怎样才能绕过这个宏里面的检查?(是只针对这个小程序),究竟是哪里出错了

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 822
活跃值: (290)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

原来是64位机器上unsigned  int只有4字节,而struct  s*是8字节,还有一些编译器告警忽略了,多谢大家。

补充:即使绕过,打出的也是原来的链表,这一点在开始时弄错了。

2018-1-19 14:39
0
雪    币: 16501
活跃值: (6387)
能力值: ( LV13,RANK:923 )
在线值:
发帖
回帖
粉丝
3
l
https://bbs.pediy.com/thread-218395.htm
盗图小王子。
2018-1-30 00:13
0
雪    币: 822
活跃值: (290)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢大帅锅~
2018-1-31 14:55
0
游客
登录 | 注册 方可回帖
返回
//