直接执行系统调用

Pie*_*e B 6 system-calls

如果用户有权访问某些内容,他如何直接执行系统调用,例如 geteuid() - 从 bash 获取有效的用户 ID(这只是一个示例),我该怎么做?

PSk*_*cik 13

通过系统调用的用户空间内核空间通信是在内存位置和机器寄存器方面完成的。这远低于 shell 的抽象级别,shell 主要使用文本字符串进行操作。

也就是说,在 bash 中,您可以使用https://github.com/taviso/ctypes.sh插件将文本字符串抽象化到 C 级粒度:

$ . ctypes.sh
$ dlcall -r long geteuid
long:1001
Run Code Online (Sandbox Code Playgroud)

不过,对于这个特定的操作,简单地使用 bash 的魔法$UID变量会更简单、更惯用、更有效。

$ echo "$EUID" #effectively a cached geteuid call
1001
Run Code Online (Sandbox Code Playgroud)


Bas*_*tch 8

要获取 uid,请编写您自己的 C 程序(或一些 shell 插件,如果您的 shell 接受它们;仅供参考zsh可以有插件,称为modules。)或更简单地运行id(1)命令。

对于其他系统调用(在syscalls(2) 中列出),它是相同的:使用某些程序(或某些内置或某些插件)来执行它们。该程序可以直接在汇编程序中编码,并使用SYSCALLSYSENTER机器指令来执行系统调用,或者(并且更常见)它将使用您的C 标准库并使用libc执行该系统调用的函数。可执行文件不需要从 C 源代码中获取(例如,busybox是用汇编程序编码的,Scheme骨骼编译器不使用任何 libc)。但是,libc系统的基石

更改进程的某些可变和可继承属性的系统调用应该是 shell 内置函数(例如cd对于chdir(2)ulimit对于setrlimit(2)等...),因为您可能想要更改 shell 进程本身中的属性(并继承由 shell 启动的未来命令进程)。所以如果cd是一个程序,它只适用于运行该程序的 shell 子进程。

顺便说一句,系统调用只有在从某个进程完成时才有意义。该进程可以是 shell 进程或由 shell 启动的某个子(或后代)进程。

请注意,Unix shell是普通程序。其中有很多(例如zshfishscshes等....)...编写自己的 shell 是一个有趣的练习(这可以简单地完成,请参阅sash示例;也看看这是关于通配的提示)。阅读有关Linux 编程的内容。如果您不满意bash使用另一个 shell(也许使用chsh(1)更改您的登录 shell )或编写自己的shell 。此外,GNU bash与大多数其他 shell自由软件一样。如果你愿意,你可以研究它的源代码并改进它。