Linux中的un
在此输入正文link
glibc2.27中的unlink源码分析
#define unlink(AV, P, BK, FD) { \
//判断chunk p的大小,是否与下一个chunk 的prev_size相等
if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \
malloc_printerr ("corrupted size vs. prev_size"); \
//让FD指向p的下一个chunk,BK指向p的上一个chunk
FD = P->fd; \
BK = P->bk; \
//以上是,chunk的大小在small bin范围内的断链操作
//以下是,large bin,的断链操作,首先判断FD的bk,与BK的fd是否同时指向p
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
malloc_printerr ("corrupted double-linked list"); \
else { \
//首先进行初步断链,使FD的bk指向BK的fd,BK的fd指向FD,只是堆fd,bk的断链操作
FD->bk = BK; \
BK->fd = FD; \
//以下使堆bk_nextsize,fd_nextsize的断链操作(large bin有两个双向链表,fd,bk用来
//进行FIFO操作,bk_nextsize,fd_nextsize是根据堆块的大小进行排序的链表)
//以下第一个if判断p的chunk是否在small范围内
if (!in_smallbin_range (chunksize_nomask (P)) \
&& __builtin_expect (P->fd_nextsize != NULL, 0)) { \
//判断chunk p的下一个chunk的上一个节点,以及上一个chunk的下一个节点是不是p
if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \
|| __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \
malloc_printerr ("corrupted double-linked list (not small)"); \
//以下是luoarge bin的断链操作,首先判断chunk p的下下一个chunk的fd_nextsize是否为空
if (FD->fd_nextsize == NULL) { \
//p的下下一个chunk的fd_nextsize为空
if (P->fd_nextsize == P) \
//判断是否只有一个chunk p,是则如下
FD->fd_nextsize = FD->bk_nextsize = FD; \
else { \
//不是以下操作,四个指针,正常的双向链表的断链操作
FD->fd_nextsize = P->fd_nextsize; \
FD->bk_nextsize = P->bk_nextsize; \
P->fd_nextsize->bk_nextsize = FD; \
P->bk_nextsize->fd_nextsize = FD; \
} \
} else { \
//p的下下一个chunk的fd_nextsize不为空,直接断链
P->fd_nextsize->bk_nextsize = P->bk_nextsize; \
P->bk_nextsize->fd_nextsize = P->fd_nextsize; \
} \
} \
} \
}
堆溢出漏洞利用,过检测方式的理解
设目标为target
则p = target;
要求FD = p->fd,BK = p->bk,FD->bk = target,BK->fd = targe,求p->fd,与p->bk;("=",为等于号)
解:
设p->fd = x,p->bk = y;
则 BK->fd = y + 0x10,FD->bk = x + 0x18;
又因为:BK = p->bk, FD = p->fd,且FD->bk = target,BK->fd = targe;
因此可解得,x =targe - 0x18,y = targe - 0x10;
所以:p->fd=targe - 0x18,p->bk = targe - 0x10
此篇博客是我自己对unlink的理解,如果觉得有问题请指出(glibc版本2.27);
网友评论