如何对系统调用 brk 进行二进制检测? (x86-64 Linux)(也许是 valgrind?)

发布于 2024-12-13 06:29:59 字数 1433 浏览 4 评论 0原文

我想检测 syscall brk (以及其他调用,但这是第一顺序,这对我来说最重要)在给定的二进制文件中(最好是在实际的系统调用/系统输入级别(x86-64 和 x86)制作 sys_brk 呼叫)。

主要目标:

  • 沙箱的一部分,为被监禁的进程提供固定数量的内存
  • 所以,我想摆脱brk 系统调用(最好是下一个顺序的其他调用)并模拟内存分配固定限制固定限制是可用于编程的内存空间。 (您可以将其视为制作一种具有固定可用内存量的沙箱)

如何实现(其中一个)一些示例可能的解决方案(或您的解决方案):

  • 只需将指令更改为 NOP
  • 由于 brk 成功时返回 0,通过设置内存的设置操作来模拟它的成功(注册)状态 ,如 brk 会被成功召唤。
  • 更复杂...带有代码(或函数调用)的工具,可在固定限制下模拟成功的内存分配。
  • 最灵活(在我的情况下可能有点过分)将此系统调用更改为函数调用并将提供的函数添加到二进制文件。

给定的二进制是可以以两种形式之一(最好是两种:))恶意的代码:

  • 共享库 - 在这里我可以在函数调用之前设置环境(例如以受控方式进行 brk 调用)
  • 程序二进制 - 在这种情况下,我们需要为程序提供固定数量的内存(由调用者或在程序“一个系统调用”开始时),因为它无法分配。调用此类程序的示例应包含在答案中。

由于问题与许多其他方面密切相关,我尽力将其作为问题分开,但如果我应该或多或少地指定一些内容,请给我建议。

欢迎提供实施答案、资源链接(书籍、教程)。

(我对Linux以及可靠的解决方案最感兴趣,这样人们准备二进制文件,即使是在汇编程序中,也不必担心代码的执行问题)

I'd like to instrument syscall brk (and other calls but this in first order, it's most important to me) in given binary (preferably on actual syscall/sysenter level (x86-64 and x86) of making sys_brk call).

Main goal:

  • A part of sandbox which gives fixed amount of memory to jailed process
  • So, I'd like to get rid of brk system calls (and most preferably others in next order) and simulate memory allocations under fixed limit. Fixed limit is memory space, available to program. (You can think about it like making a kind of sandbox with fixed amount of available memory)

How to implement (one of) some example possible solutions (or yours solution):

  • just changing instructions to NOP
  • As brk returns 0 on success, simulate it's successes with setting operations that sets memory (register) state , as brk would be called with success.
  • More complex... instrument with code (or function call) which simulates success memory allocations under fixed limit.
  • Most flexible (maybe overkill in my case) to change this syscall into function call and add provided function to binary.

Given binary is code that can be malicious in one of two (most preferably both :) ) forms:

  • shared library - here I can setup environment before function call (for example do brk call in controlled way)
  • program binary - in this case we need to give program fixed amount of memory (by caller, or on begining of program "one syscall"), cause it can not allocate. Example of calling such program should be included in answer.

As problem is highly connected with many other aspects, I tried do my best in separating it as question, but please give me advice if I should specify something more or less.

Answers with implementation, links to resources (books, tutorials) are welcome.

(I am most interested in Linux, and solution that is reliable, so that people preparing binaries, even in assembler, would not have to worry about execution of their code)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱格式化 2024-12-20 06:29:59

LD_PRELOAD 将捕获对 brk() 的 C 调用,但不会捕获实际的系统调用(int/syscall 指令)。没有可移植的方法来捕获这些,但在 Linux 上,ptrace 可以做到这一点。内存也可以通过 mmap() 分配给程序,因此您也需要拦截该调用。

当然,看起来您真正要寻找的是 rlimit()。

LD_PRELOAD will trap C calls to brk(), but it won't trap the actual system call (int/syscall instruction). There's no portable way to trap those, but on Linux, ptrace will do it. Memory can also be allocated to a program by mmap(), so you'll need to intercept that call too.

Of course, what it seems you're really looking for is rlimit().

昨迟人 2024-12-20 06:29:59

是的,我认为你不需要 valgrind 为此。

您可以使用 LD_PRELOAD 或链接器技巧来捕获 brk(2):请参阅以下其他讨论:

函数Linux 中不使用 dlsym 的插入

使用 LD_PRELOAD 机制覆盖 'malloc'

代码可能如下所示:

#include <unistd.h>
#include <dlfcn.h>

/* prototype int brk(void *addr); */

static int (*real_brk)(void *addr) = NULL;

int brk(void * addr) {

    real_brk = dlsym(RTLD_NEXT, "brk");
    if (real_brk == NULL) {
            fprintf(stderr, "error mapping brk: %s\n", dlerror());
            return -1;
    }
    printf("calling brk(2) for %p\n", addr);
    return (real_brk (addr));
}`   

然后LD_PRELOAD 拦截brk(2)

Yeah, I don't think you want valgrind for this.

You can use LD_PRELOAD or linker tricks to capture brk(2): see these other discussions:

Function interposition in Linux without dlsym

Overriding 'malloc' using the LD_PRELOAD mechanism

Code might look like this:

#include <unistd.h>
#include <dlfcn.h>

/* prototype int brk(void *addr); */

static int (*real_brk)(void *addr) = NULL;

int brk(void * addr) {

    real_brk = dlsym(RTLD_NEXT, "brk");
    if (real_brk == NULL) {
            fprintf(stderr, "error mapping brk: %s\n", dlerror());
            return -1;
    }
    printf("calling brk(2) for %p\n", addr);
    return (real_brk (addr));
}`   

and then LD_PRELOAD that to intercept brk(2)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文