如何嵌入内联汇编来调用 sys_unlink?

发布于 2024-10-10 02:01:02 字数 257 浏览 10 评论 0原文

我尝试使用内联汇编调用 sys_unlink,如下所示:

 int sys_unlink(const char *filename) {

    int ret;

    __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));

    return ret;

}

但它不起作用,它总是返回 -14。

我想知道这段代码是否正确,因为我不太了解汇编。

I am try to make a call to sys_unlink using inline assembly, like this:

 int sys_unlink(const char *filename) {

    int ret;

    __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));

    return ret;

}

But it does not work, it always return -14.

I would like to know if this code is correct, as I do not know much assembly.

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

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

发布评论

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

评论(2

时光倒影 2024-10-17 02:01:02

该代码仅适用于 x86(32 位)进程 - 它没有为 x86-64 进程使用正确的系统调用号。使用 asm/unistd.h 中的 __NR_unlink 而不是硬编码的 10

#include <asm/unistd.h>

int sys_unlink(const char *filename)
{
    int ret;

    asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
    return ret;
}

如果您正在编译 32 位进程,则 -14EFAULT,表示您传递的文件名有问题。你怎么称呼它?

That code is only correct for an x86 (32 bit) process - it does not use the right syscall number for an x86-64 process. Use __NR_unlink from asm/unistd.h instead of the hardcoded 10:

#include <asm/unistd.h>

int sys_unlink(const char *filename)
{
    int ret;

    asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
    return ret;
}

If you are compiling a 32 bit process, then -14 is EFAULT, indicating an a problem with the filename you are passing. How are you calling it?

给妤﹃绝世温柔 2024-10-17 02:01:02

我不认为你可以让这项工作甚至仅限于 Linux 下的单个平台:Linux 进行系统调用的现代方法是通过内核提供的存根并通过 VDSO 链接。即使您链接的 libc 也不知道(不需要知道)系统调用约定是什么 - 它只是从 VDSO 中提取引用。它通过隐藏在 environ 之后的神奇参数获取对 VDSO 的引用,然后像任何其他动态库一样对待它。内核根据 CPU 功能选择系统调用约定。

我碰巧知道(因为我尝试这样做!)很难访问这些 VDSO 符号。 glibc 不会为您导出它们(或它们的任何有用句柄)。我看到的唯一可行的方法是检查您自己的 /proc/self/maps 来查找 VDSO,然后使用 dl 函数来获取它(重复一些glibc 设置工作)。

I don't think you can make this work even restricted to a single platform under Linux: The modern way for Linux to make syscalls is via a stub provided by the kernel and linked in via VDSO. Even the libc you are linking against doesn't know (doesn't need to know) what the system call convention is -- it just pulls in a reference from the VDSO. It gets a reference to the VDSO via a magic parameter that's hidden just after environ and then treats it like any other dynamic library. The kernel chooses the system call convention based on the CPU capabilities.

I happen to know (because I tried to do it!) that it's hard to get access to those VDSO symbols. glibc does not export them (or any useful handle to them) for you. About the only workable way I saw was to inspect your own /proc/self/maps to find the VDSO and then use dl functions to get at it (repeating some of the glibc setup work).

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