如何对系统调用 brk 进行二进制检测? (x86-64 Linux)(也许是 valgrind?)
我想检测 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 , asbrk
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
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().
是的,我认为你不需要 valgrind 为此。
您可以使用 LD_PRELOAD 或链接器技巧来捕获 brk(2):请参阅以下其他讨论:
函数Linux 中不使用 dlsym 的插入
使用 LD_PRELOAD 机制覆盖 'malloc'
代码可能如下所示:
然后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:
and then LD_PRELOAD that to intercept brk(2)