1. kprobes/kretprobes 介绍

1.1 kprobes 介绍

kprobes 主要用来对内核进行调试追踪, 属于比较轻量级的机制,,本质上是在指定的探测点(比如函数的某行, 函数的入口地址和出口地址,,或者内核的指定地址处)插入一组处理程序.。内核执行到这组处理程序的时候就可以获取到当前正在执行的上下文信息, 比如当前的函数名, 函数处理的参数以及函数的返回值,,也可以获取到寄存器甚至全局数据结构的信息。

1.2 kretprobes 介绍

kretprobes 在 kprobes 的机制上实现,主要用于返回点(比如内核函数或者系统调用的返回值)的探测以及函数执行耗时的计算。

2. bcc实例代码

下面举例来介绍 kprobe/kretprobes 在 BPF C 程序中的使用,本实例的功能为获取系统中的 IPV4 连接信息。

from __future__ import print_function
from bcc import BPF# define BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
BPF_HASH(currsock, u32, struct sock *);
int kprobe__tcp_v4_connect(struct pt_regs *ctx, struct sock *sk)
{u32 pid = bpf_get_current_pid_tgid();// stash the sock ptr for lookup on returncurrsock.update(&pid, &sk);return 0;
};
int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
{int ret = PT_REGS_RC(ctx);u32 pid = bpf_get_current_pid_tgid();struct sock **skpp;skpp = currsock.lookup(&pid);if (skpp == 0) {return 0;  // missed entry}if (ret != 0) {// failed to send SYNC packet, may not have populated// socket __sk_common.{skc_rcv_saddr, ...}currsock.delete(&pid);return 0;}// pull in detailsstruct sock *skp = *skpp;u32 saddr = 0, daddr = 0;u16 dport = 0;bpf_probe_read(&saddr, sizeof(saddr), &skp->__sk_common.skc_rcv_saddr);bpf_probe_read(&daddr, sizeof(daddr), &skp->__sk_common.skc_daddr);bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);// outputbpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport));currsock.delete(&pid);return 0;
}
"""# initialize BPF
b = BPF(text=bpf_text)# header
print("%-6s %-12s %-16s %-16s %-4s" % ("PID", "COMM", "SADDR", "DADDR","DPORT"))def inet_ntoa(addr):dq = ''for i in range(0, 4):dq = dq + str(addr & 0xff)if (i != 3):dq = dq + '.'addr = addr >> 8return dq# filter and format output
while 1:# Read messages from kernel pipetry:(task, pid, cpu, flags, ts, msg) = b.trace_fields()(_tag, saddr_hs, daddr_hs, dport_s) = msg.split(" ")except ValueError:# Ignore messages from other tracerscontinue# Ignore messages from other tracersif _tag != "trace_tcp4connect":continueprint("%-6d %-12.12s %-16s %-16s %-4s" % (pid, task,inet_ntoa(int(saddr_hs, 16)),inet_ntoa(int(daddr_hs, 16)),dport_s))

3. 实例代码分析

3.1 kprobes

语法格式:kprobe__kernel_function_name

其中kprobe__是前缀,用于给内核函数创建一个kprobe(内核函数调用的动态跟踪)。也可通过C语言函数定义一个C函数,然后使用 python 的BPF.attach_kprobe()来关联到内核函数。

本实例中使用 kprobes 定义了这样一个函数:

int  kprobe__tcp_v4_connect(struct pt_regs * ctx,struct sock * sk)
{[...]
}

参数如下:

  • struct pt_regs *ctx:寄存器和BPF文件;
  • struct sock *sktcp_v4_connect 内核函数的第一个参数。

tcp_v4_connect在内核中的定义如下:

int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);

第一个参数总是 struct pt_regs *,其余的参数就是这个内核函数的参数(如果不使用的话,就不用写了)。

3.2 kretprobes

kretprobes 用于动态跟踪内核函数的返回,语法如下:
语法格式:kretprobe__kernel_function_name

其中kretprobe__是前缀,用来创建 kretprobe 对内核函数返回的动态追踪。也可通过C语言函数定义一个C函数,然后使用 python 的BPF.attach_kprobe()来关联到内核函数。

本实例中使用 kretprobes 定义了这样一个函数:

int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
{int ret = PT_REGS_RC(ctx);[...]
}

返回的参数可以在 BPF C 程序中使用PT_REGS_RC()来获得,返回值保存在了ret中。

4. 运行结果

使用如下命令运行实例bcc程序,运行结果如图:

sudo python tcp4connect.py


可以看到 bcc 程序成功获取到了系统 TCP IPv4连接信息,运行结果中标题解释如下:

列标题 含义
PID 进程号
COMM 进程命令行
SADDR 源地址
DADDR 目标地址
DPORT 目标端口

参考链接:
https://lwn.net/Articles/132196/
https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md

kprobes/kretprobes 在 bcc 程序中的使用相关推荐

  1. ebpf之bcc程序入门

    原理 参考:高效入门eBPF_哔哩哔哩_bilibili 环境安装 参考:https://github.com/iovisor/bcc/blob/master/INSTALL.md#ubuntu-so ...

  2. 网络bcc程序测试方案

    网络bcc程序测试方案 1. 具体做法 1.1 准确性测试 1.2 性能测试 2. 数据模拟工具 3. 传统工具举例 3.1 iftop实时流量监控工具(此工具可用来测试网络流量指标程序) 3.2 n ...

  3. 在一个程序中什么算是亮点_VASP 计算问题小结

    本文转载自博主一个人就是一个叠加态,有部分删减修改,文中对相关概念方法做了详细的总结,留坑待填... 1. 第一原理计算的一些心得 1. 第一性原理 第一性原理其实是包括基于密度泛函的从头算和基于Ha ...

  4. 微信小程序中的tabBar设置

    我们先来看一份图,这个设置在官方文档中已经写得很清楚了,我只是做一个总结 注:我写注释是为了方便说明,在小程序中的json文件中是不能用注释的 这个tabBar属于全局属性,因此就在全局配置文件app ...

  5. C#中Winform程序中如何实现多维表头【不通过第三方报表程序】

    问题:C#中Winform程序中如何实现多维表头. 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂.最后在新浪博客看到了一篇比较易懂的文章:[DataGridView二维表头与合并单元格 ...

  6. 在windows程序中嵌入Lua脚本引擎--编写自己的Lua库

    在<在windows程序中嵌入Lua脚本引擎--建立一个简易的"云命令"执行的系统>一文中,我提到了使用Lua的ffi库,可以让我们像写C代码一样写lua程序.这是个非 ...

  7. 在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统

    在<在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎>开始处,我提到某公司被指责使用"云命令"暗杀一些软件.本文将讲述如何去模拟一个 ...

  8. 在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎

    前些天听到一个需求:某业务方需要我们帮忙清理用户电脑上的一些废弃文件.同事完成这个逻辑的方案便是在我们程序中加入了一个很"独立"的业务逻辑:检索和删除某个程序产生的废弃文件.试想, ...

  9. 在vc6控制台程序中如何调用运行ImageMagick命令行工具

    在http://www.imagemagick.org/script/index.php网站下载相应的执行文件,这里以下载ImageMagick-6.6.5-10-Q16-windows-static ...

最新文章

  1. PCL_common模块api代码解析
  2. CentOS6.x配置tomcat搭建JSP应用服务器
  3. NanoPi NEO Air使用六:使用摄像头
  4. 中国燃料电池行业供应规模及需求前景调研报告2021-2027年版
  5. 如何把自己github博客配置到一个腾讯云购买的自定义域名上
  6. 昨天帮同学的学校写了首校歌
  7. Spring AOP之通知类别
  8. 一个游戏大量合服代表什么_一个女人哭了代表什么?这几点帮你分析
  9. 理解sklearn.feature.text中的CountVectorizer和TfidfVectorizer
  10. 「总结」 MLEAutoMaton的各种板子总结
  11. java图像的灰度值获取_java获取图像灰度
  12. Android中自定义View的MeasureSpec使用
  13. 那些小城里的分析大师们为什么发不了财?
  14. 2013年全国各大著名的IT公司薪资待遇大揭密 给出入职场的民工一点建议
  15. windows服务启动tomcat内存溢出问题解决方案
  16. VS2013的C# Winform怎么添加Windows Media Player控件 详细图解 代码示例及运行效果
  17. Java进阶架构实战——Redis在京东到家的订单中的使用
  18. TSQL 实现IRR功能
  19. EasyReport报表工具
  20. Vulkan学习(四):Shader加载 管线设置

热门文章

  1. 第三方支付——微信app支付
  2. (最终作业)面向对象先导课课程总结
  3. linux下helloworld的简单编译过程
  4. 在aptana3中使用scriptDoc__scriptDoc 2.0完全参考
  5. 将应用程序11M内存占用,降至500K [转]
  6. win7与ubuntu 13.04 64位双系统安装介绍
  7. docker mysql容器 修改时区
  8. linux shell 判断文件 修改时间和系统时间差
  9. 各类攻击 单一协议 pcap数据包 下载网站
  10. docker history 查看docker镜像构建过程 还原dockerfile 查看启动参数