首页 > 其他分享 >android ebpf中的CO-RE学习

android ebpf中的CO-RE学习

时间:2023-10-31 14:38:01浏览次数:47  
标签:CO libbpf execveat RE btf 内核 android

CO-RE原理

因为不同的内核版本的系统内部结构体会有差异,例如struct user_arg_ptr,当内核编译配置中存在CONFIG_COMPAT=y的时候,会在native成员之前增加一个布尔变量is_compat,这样native的偏移就发生的变化。

如果编写的ebpf内核程序需要访问struct user_arg_ptr类型的变量就需要考虑在不同内核版本上的兼容问题,即一次编译到处运行(CO-RE)。libbpf提供CO-RE的支持,libbpf程序编译的时候依赖特定内核的vmlinux.h头文件,这个头文件中包含了内核中所有结构体信息,这些结构体的成员偏移都是固定的。vmlinux.h头文件可以通过bpftool btf dump file /sys/kernel/btf/vmlinux format c生成。

当编译ebpf程序生成字节码的时候,libbpfCO-RE接口函数借助clang,通过__builtin_preserve_access_index记录成员的偏移量。

ebpf字节码加载到内存之前,libbpf会从运行系统的btf文件/sys/kernel/btf/vmlinux中获取实际的内核结构体信息并进行解析,之后对ebpf字节码中的结构体引用进行重定位,这样ebpf就可以获取内核结构体正确的偏移。只有系统内核编译的时候打开CONFIG_DEBUG_INFO_BTF=y才会生成对应的btf文件,否则就需要通过其他方法提取btf文件并重编译libbpf增加对自提取btf文件的加载。

CO-RE使用

这里以bcc中提供的libbpf-tools为例,libbpf-toolsbcc为了支持CO-RE依赖与libbpf编写的一些和bcc tool功能类似的小工具。其中execsnoop通过SEC("tracepoint/syscalls/sys_entry_execve")SEC("tracepoint/syscalls/sys_entry_execveat")execve/execveat系统调用进行hook,因为大多数android设备都没有打开CONFIG_FTRACE_SYSCALLS=y配置,所以并不支持syscalls类型的tracepoint

这里利用kprobe/kretprobe对原程序进行改写,从而能在未开启CONFIG_FTRACE_SYSCALLS=y的设备上运行。这里hook的是do_execveat_common,因为execve/execveat系统调用最后都会调用此函数,并且此函数是导出的。这里注意是struct user_arg_ptrnative成员保存了argv命令行参数指针,struct user_arg_ptr类型变量作为参数传递给do_execveat_common函数。

这里需要注意gcc/clang编译器在编译时,如果函数调用传递的参数是一个结构体,其会将此结构体所有的成员作为单个的参数进行传递,而windows平台的MSVC编译器则是将结构体先拷贝到目标函数栈空间中,然后将对应栈空间中结构体的地址作为参数进行传递。

因为我这里内核配置有CONFIG_COMPAT=y,所以struct user_arg_ptr类型的native成员前有个布尔类型的成员is_compat,那么对应的is_compat就是do_execveat_common函数的第三个参数,native就是第四个参数(没配置CONFIG_COMPAT=y就是第三个参数)。利用libbpf的CO-RE支持函数bpf_core_field_exists可以判断某个成员是否存在,从而判断是取第三个参数还是第四个参数。

最后通过bpf_prob_read_user读取对应的命令行参数

do_execveat_common函数的第二个参数是filename类型的指针,其成员name指向对应可执行文件的全路径。虽然filename在各个linux内核中的结构差异不大,但是为了安全最好所有的内核结构访问都使用libbpfCO-RE支持函数。

如果访问filename类型的name成员不适用CO-RE支持函数,那么就使用bpf_probe_read_kernel,默认为namefilename结构中的偏移为0

如果使用libbpfCO-RE支持函数bpf_core_read访问

这里name就是一个指针,所以可以直接使用bpf_core_read,对于结构体多层嵌套的情况可以使用BPF_CORE_READ访问

最后通过bpf_probe_read_kernel_strname内核指针中读取可执行文件全路径

android平台运行的效果如下

代码已上传github:https://github.com/revercc/libbpf-bootstrap-for-android.git

参考:
https://mp.weixin.qq.com/s/zOgwwvVSMlEQzRXse3SBhw
https://github.com/iovisor/bcc.git

标签:CO,libbpf,execveat,RE,btf,内核,android
From: https://www.cnblogs.com/revercc/p/17800144.html

相关文章

  • Mac 中安装 vue 脚手架后报错 vue: command not found
    解决方案安装node、npm查看npm全局安装位置npmroot-g正确位置/usr/local/lib/node_modules修改位置npmconfigsetprefix/usr/local重新安装脚手架sudonpminstall-g@vue/cli查看vue版本vue-v......
  • dremio 的自服务语义层创建简单说明
    内容来自官方文档,介绍了一些关于dremio的数据语义层的玩法原则分层 通过分层可以确保安全,性能以及可用性,dremio提供了一个对于语义层的最佳实践数据集的注释增强发现以及可理解性 可以通过tag以及文档(wiki)进行数据的描述最佳实践使用1:1的预处理层 此层的数据接近......
  • selenium+python,自动获取cookie登录
     一、通过cookie一直保持自动登录状态1.手动操作原理:保持自动登录状态1.通过cookie信息的唯一标识ID2.登录后一直保持不退出状态,就可以实现自动登录  登录后,session唯一标识:如果当前是登录状态,那就是登录。如果不是登录状态,就不是登录的。如何查看是否登录状态?浏览器......
  • selenium远程调用浏览器(firefox版)
    安装selenium浏览器服务dockerrun--namefirefox-d-p4444:4444-p7900:7900--shm-size="2g"selenium/standalone-firefox:3.141demofromseleniumimportwebdriverfromselenium.webdriverimportDesiredCapabilitiesdriver=webdriver.Remote(#指定......
  • React学习笔记15-13-setState同步异步问题
    先说结论:setState处在同步的逻辑中会异步更新状态,更新真实dom。连续调用setState不会连续进行虚拟dom的对比和页面的更新setState处在异步的逻辑中,同步更新状态,更新真实dom。 1.同步状态先看同步状态/*eslint-disablereact/no-direct-mutation-state*/importRea......
  • 浅析Redis大Key
    一、背景在京东到家购物车系统中,用户基于门店能够对商品进行加车操作。用户与门店商品使用Redis的Hash类型存储,如下代码块所示。不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此Key就会越来越大,从而影响线上业务。userPin:{storeId:{门店下加车的所有商品......
  • Android之WebView显示PDF文档
    参考:https://blog.csdn.net/Android_Cll/article/details/131641229https://cloud.tencent.com/developer/article/2301730Android项目新增js:/app/src/main/assets/wwwroot/index.js我新建了一个wwwroot放里面了。自己看着办。varurl=location.search.substring(1);PDFJS.......
  • 解决pandas.core.frame.DataFrame格式数据与numpy.ndarray格式数据不一致导致无法运算
    解决pandas.core.frame.DataFrame格式数据与numpy.ndarray格式数据不一致导致无法运算问题在数据分析与机器学习中,经常会遇到处理数据的问题。而使用Python进行数据处理和分析时,pandas库和numpy库是常用的工具。其中,pandas库提供了DataFrame数据结构,numpy库提供了ndarray数据结构。......
  • 'ProxyError('Cannot connect to proxy.', NewConnectionError
      MicrosoftVisualC++Redistributableisnotinstalled,thismayleadtotheDLLloadfailure.                Itcanbedownloadedathttps://aka.ms/vs/16/release/vc_redist.x64.exeTraceback(mostrecentcalllast): File"E:/other/lightvit......
  • 编译第三方前端项目时候出现Syntax Error: TypeError: Cannot set properties of unde
    编译第三方的前端项目时候出现下面问题 ERROR Failedtocompilewith1error                                                             ......