专栏首页Serverless+使用 BPF 改变运行中的程序的函数参数
原创

使用 BPF 改变运行中的程序的函数参数

本文探索使用 BPF 改变运行中的程序的函数参数,挖掘 BPF 的黑魔法。

实验环境

  • Ubuntu 20.04.2 LTS
  • BCC

测试程序

这是我们的示例程序,打印第一个命令行参数:

package main

import (
	"fmt"
	"os"
	"time"
)

//go:noinline
func greet(s string) {
	fmt.Println(s)
}

func main() {
	for {
		greet(os.Args[1])
		time.Sleep(time.Second)
	}
}

注意到我们使用 //go:noinline 修饰了 main.greet 函数,防止被编译器内联,方便进行测试验证。

这是我们的 BPF 程序,尝试修改函数参数为字符串 You are hacked!:

#include <uapi/linux/ptrace.h>

int hack(struct pt_regs *ctx) {
    char text[] = "You are hacked!";
    // read string address
    u64 addr = 0;
    u64* sp = (u64*)ctx->sp;
    bpf_probe_read(&addr, sizeof(addr), sp + 1);
    // overwrite string content
    bpf_probe_write_user((u64*)addr, text, sizeof(text));
    return 0;
}

使用 bpf_probe_write_user 修改用户内存空间的内容,此操作存在风险,因此每当带有此函数的 BPF 程序被加载时,从 dmesg 中都可以看到如下日志:

tracer[609901] is installing a program with bpf_probe_write_user helper that may corrupt user memory!

实验结果

在第一个终端先启动示例程序,每隔一秒打印字符串 hello world!:

$ ./tracee 'hello world!'
hello world!
hello world!
...

在第二个终端再启动 BPF 程序:

$ sudo ./tracer /path/to/tracee 'main.greet'

此时再看看示例程序的输出:

$ ./tracee 'hello world!'
hello world!
hello world!
...
You are hack
You are hack
You are hack
...

修改成功!

结论

本文探索使用 BPF 修改执行中的 Go 程序的函数参数, 由于 Golang 的 ABI 是使用栈来传递函数参数,通过读取栈上的指针地址,使用 bpf_probe_write_user 修改对应地址的内存内容来达成修改函数参数的目的。你可以在这里找到本文的全部代码。

参考

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • Python使用多进程运行含有任意个参数的函数

    许多时候,我们对程序的速度都是有要求的,速度自然是越快越好。对于Python的话,一般都是使用multiprocessing这个库来实现程序的多进程化,例如:

    砸漏
  • Python中函数的参数(参数的使用和作用、形参和实参)

    演练需求:开发一个名字叫sum_num的函数,这个函数能够实现两个数字的求和功能.

    村长python
  • 关于python使用threadpool中的函数单个参数和多个参数用法举例

    1.对单个元素的函数使用线程池: # encoding:utf-8 __author__='xijun.gong' import threadpool de...

    Gxjun
  • 程序运行时间测试 - 使用libc 中 time 函数 实现秒级的运行时间检测

    c 标准库中,有time 函数,可以返回 1970年1月1日 开始到现在的秒数,我们可以调用两次的时间差来计算程序运行时间:

    xuyaowen
  • centOS6中使用crontab定时运行执行jar程序的脚本

    以上所述是小编给大家介绍的centOS6中使用crontab定时运行执行jar程序的脚本,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的...

    砸漏
  • BPF 和 Go: Linux 中的现代内省形式

    本文将向你介绍为什么我们需要像 BPF 这样的东西,并帮助你了解何时及如何使用它,以及它是如何帮助作为工程师的你改进你正在进行的项目的。我们还将研究它与 Go...

    深度学习与Python
  • 张亦鸣 : eBPF 简史 (下篇)

    数日之前,笔者参加某一技术会议之时,为人所安利了一款开源项目,演讲者对其性能颇为称道,称其乃基于近年在内核中炙手可热的 eBPF 技术。

    Linuxer
  • eBPF 概述:第 1 部分:介绍

    有兴趣了解更多关于 eBPF 技术的底层细节?那么请继续移步,我们将深入研究 eBPF 的底层细节,从其虚拟机机制和工具,到在远程资源受限的嵌入式设备上运行跟踪...

    用户7686797
  • 【eBPF笔记中篇】运行原理、交互、event触发 解析(未完)

    从之前的分析已经得知,.c的eBPF程序会通过BCC等工具编译并加载到内核中,但是具体在内核中,ebpf是如何工作的呢?

    历久尝新
  • 调试你的BPF程序

    文章涉及的实验环境和代码可以到这个git repo获取: https://github.com/nevermosby/linux-bpf-learning

    nevermosby
  • 使用EBPF追踪LINUX内核

    我们可以使用BPF对Linux内核进行跟踪,收集我们想要的内核数据,从而对Linux中的程序进行分析和调试。与其它的跟踪技术相比,使用BPF的主要优点是几乎可以...

    Linux阅码场
  • BPF数据传递的桥梁——BPF Map(一)

    https://github.com/nevermosby/linux-bpf-learning/tree/master/bpf/bpf-maps

    nevermosby
  • 一文看懂eBPF|eBPF实现原理

    在上一篇文章中,我们主要简单介绍了什么是 eBPF 和 eBPF 的简单使用,而本文重点介绍 eBPF 的实现原理。

    用户7686797
  • 全面介绍eBPF-概念

    前面介绍了BCC可观测性和BCC网络,但对底层使用的eBPF的介绍相对较少,且官方欠缺对网络方面的介绍。下面对eBPF进行全面介绍。

    charlieroro
  • Service Mesh架构新技能之eBPF入门与实践

    在分享这篇文章之前,先简单和大家说下背景。在之前的文章中作者分享了一些关于Service Mesh微服务架构的文章,在Service Mesh架构中需要通过Si...

    用户5927304
  • eBPF 入门教程

    有兴趣了解更多关于 eBPF 技术的底层细节?那么请继续移步,我们将深入研究 eBPF 的底层细节,从其虚拟机机制和工具,到在远程资源受限的嵌入式设备上运行跟踪...

    米开朗基杨
  • 使用eBPF追踪Linux内核

    我们可以使用BPF对Linux内核进行跟踪,收集我们想要的内核数据,从而对Linux中的程序进行分析和调试。与其它的跟踪技术相比,使用BPF的主要优点是几乎可以...

    Jinrong
  • eBPF文章翻译(1)—eBPF介绍

    Brendan Gregg,他在2017年的linux.conf.au大会上的演讲提到「内核虚拟机eBPF」,表示,”超能力终于来到了Linux操作系统“。让e...

    nevermosby
  • FastAPI(11)- 函数参数类型是列表,但不使用 typing 中的 List,而使用 list,会怎么样?

    用 Python 自带的 list、set、tuple 类,是无法指定序列里面参数的数据类型,所以 FastAPI 并不会针对里面的参数进行数据校验

    小菠萝测试笔记

扫码关注腾讯云开发者

领取腾讯云代金券