背景知识
sk_buff 在内核网络协议栈中代表一个「包」,我们不难想到的是我们只需要创建一对 socket,在上面发送与接收数据包就能完成 sk_buff 的分配与释放,最简单的办法便是用 socketpair 系统调用创建一对 socket,之后对其 read & write 便能完成收发包的工作
总结其核心意思就是:
socketpair创建一对socket;
read&write完成收发包的工作;
结构体首先看sk_buff:
原博客对此的解释是:
data 和 tail 可以这么理解:数据包每经过网络层次模型中的一层都会被添加/删除一个 header (有时还有一个 tail),data 与 tail 便是用以对此进行标识的
也就是网络层、传输层这些都可以发数据包,每一层都有可能加上一些头或者尾巴;
多个sk_buff还会形成双链表:
从Pwn的角度看sk_buff结构
sk_buff分配自特殊的cache,不好用;
但是其数据部分分配自kmalloc_reserve(),最终会走__kmalloc分配路径,因此还是常规cache;
data会在后边有一个“尾巴”——skb_shared_info
:(skb_shared_info
结构体的大小为 320 字节)
实操
模板:
|
调试技巧如下,我们首先重点关注这个sk_buff的data的创建:
现在__alloc_skb
下断点,可以看到这是sk_buff的专用cache:
然后在这里分配skb:
然后是分配data,这里的size就是我们write的长度,之后取对齐、加上skb_shared_info的长度,之后通过kmalloc_reserve函数来分配内存(看a3师傅的博客应该最后还是调用到了__kmalloc函数):
之后初始化sk_buff:
全执行完之后data中会填充进去数据:(甚至原来的数据还有所残留,😀)
sk_buff的释放借助kfree_skb
函数;
data的释放是通过skb_release_data
函数释放;