小编San*_*mar的帖子

如何在二进制执行期间挂钩所有linux系统调用

我试图修改linux系统调用的默认行为.目前我正试图在实际调用它们之前挂钩并添加一个简单的print语句.我知道GCC链接器的标准'wrap'选项以及它如何用于挂钩包装器链接到GCC链接器选项.这完全适用于open(),fstat(),fwrite()等(我实际上是挂钩libc包装器).

更新:

限制是并非所有系统调用都与此方法相关联.为了说明这一点,让我们采用一个简单的静态编译二进制.当我们尝试添加包装器时,它们会受到我们在main()之后引入的调用的影响(请参阅下面显示的strace输出)

> strace ./sample 

execve("./sample", ["./sample"], [/* 72 vars */]) = 0
uname({sys="Linux", node="kumar", ...})   = 0
brk(0)                                  = 0x71f000
brk(0x7201c0)                           = 0x7201c0
arch_prctl(ARCH_SET_FS, 0x71f880)       = 0
readlink("/proc/self/exe", "/home/admin/sample"..., 4096) = 41
brk(0x7411c0)                           = 0x7411c0
brk(0x742000)                           = 0x742000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbcc54d1000
write(1, "Hello from the wrapped readlink "..., 36Hello from the wrapped …
Run Code Online (Sandbox Code Playgroud)

linux linker gcc system-calls binutils

6
推荐指数
1
解决办法
1411
查看次数

在 libc 源代码中,open() 是从哪里链接的?

我基本上需要为我的目的定制一些linux系统调用接口(比如sys_open)。我非常了解 GNU Linker ld --wrap=符号选项并使用该逻辑来更改 open() libc 包装器。尽管这达到了目的,但我真的很想知道在 libc 源代码中的哪个位置,实际实现开始发挥作用。

以下两个地方是我的主要嫌疑人(注意fcntrl.h只有声明)

  • GLIBC_DIR/io/open.c
  • GLIBC_DIR/ports/sysdeps/unix/sysv/linux/generic/open.c

示例驱动程序:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd;

    if ((fd = open("sample.c", O_RDONLY)) == -1) {
        fprintf(stderr, "file not found\n");
        exit(1);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

相关片段:

main:
  401dd1:       bf 44 90 48 00          mov    $0x489044,%edi
  401dd6:       b8 00 00 00 00          mov    $0x0,%eax
  401ddb:       e8 10 03 03 00          callq  4320f0 <__libc_open> …
Run Code Online (Sandbox Code Playgroud)

linux linker gcc libc system-calls

5
推荐指数
1
解决办法
831
查看次数

如何通知 GCC 不使用特定寄存器

假设我有一个非常大的源代码,并且打算rdx在执行期间完全不使用寄存器,即,在生成汇编代码时,我只想通知我的编译器(GCC)它根本不应该使用rdx

注意:注册rdx只是一个例子。我可以使用任何可用的 Intel x86 寄存器。

我什至很高兴更新编译器的源代码并使用我的自定义 GCC。但是需要对源代码进行哪些更改?

linux compiler-construction gcc cpu-registers

4
推荐指数
2
解决办法
2175
查看次数

为什么在printfs调用期间完成了mmap?

为什么printf()执行sys_mmap()然后将块的内容(1024)复制到sys_write()的新地址空间?

简单静态"hello"程序的Strace如下所示.

> gcc -o hello -static hello.c
> strace ./hello


execve("./hello", ["./hello"], [/* 71 vars */]) = 0
uname({sys="Linux", node="Kumar", ...})   = 0
brk(0)                                  = 0x1ce8000
brk(0x1ce91c0)                          = 0x1ce91c0
arch_prctl(ARCH_SET_FS, 0x1ce8880)      = 0
readlink("/proc/self/exe", "/home/admin/hello", 4096) = 18
brk(0x1d0a1c0)                          = 0x1d0a1c0
brk(0x1d0b000)                          = 0x1d0b000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 28), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7feda2130000
write(1, "Hello", 5Hello)                    = 5
exit_group(0) …
Run Code Online (Sandbox Code Playgroud)

linux system libc elf linux-kernel

2
推荐指数
1
解决办法
210
查看次数