gpt4 book ai didi

linux - 如何修复 'SYSCALL execve' : ls complains about a NULL argv[0]

转载 作者:太空宇宙 更新时间:2023-11-04 11:46:09 24 4
gpt4 key购买 nike

我创建了系统调用但未找到。这是我在 asm 中的代码

section .text
global _start
_start:
xor eax,eax

push eax
push dword '//ls'
push dword '/bin'
mov ebx,esp
mov al,0xb
int 0x80
;/bin//ls

当由此构建静态 32 位可执行文件并运行它时,我得到:

A NULL argv[0] was passed through an exec system call.
Aborted (core dumped)

这里发生了什么以及如何解决它?

最佳答案

您的代码按您的预期工作,进行了成功的 execve("/bin//ls", NULL, NULL) 系统调用。

问题在于 GNU lssh 或其他一些程序不同,它在运行空 argv[]< 时选择中止 ()/。通常的约定是将程序名称作为第一个参数传递 (argv[0])。

您的程序使用 /bin//sh 而不是 ls 可以正常工作


execve 的 argv 和 envp args 来自离开 ECX 和 EDX = 0,因为 Linux 选择在进入用户空间之前设置它们。 (这避免了内核信息泄漏,而不是让它们未初始化)。显然,这在将使用包含未知值的寄存器运行的 shellcode 中不起作用。

顺便说一句,Linux execve() does document它支持传递 envp 和/或 argv=NULL 而不是 argv = (char*[]){NULL};(指向 NULL 的指针)。不是为未指向有效内存的 argv 返回 -EFAULT,而是将 NULL 特殊情况作为空数组。


我可以使用 ls (GNU coreutils) 8.31 在 Arch Linux 上重现您的结果

$ nasm -felf32 exec.asm
$ ld -melf_i386 -o exec exec.o

$ ./exec
A NULL argv[0] was passed through an exec system call.
Aborted (core dumped)

您可以使用 strace 来确定消息不是来自您的进程。

$ strace ./exec 
execve("./exec", ["./exec"], 0x7ffd7090ed90 /* 54 vars */) = 0 <=== starting your program
strace: [ Process PID=21152 runs in 32 bit mode. ]

execve("/bin//ls", NULL, NULL) = 0 <==== This is your system call
# then ls starts up normally
strace: [ Process PID=21152 runs in 64 bit mode. ]
brk(NULL) = 0x55b5fbaff000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe1d74c5b0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

... normal dynamically-linked executable startup stuff ...

... until it writes a message to stderr and raises SIGABRT ...
write(2, "A NULL argv[0] was passed throug"..., 55A NULL argv[0] was passed through an exec system call.
) = 55
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid() = 21152
gettid() = 21152
tgkill(21152, 21152, SIGABRT) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=21152, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++
Aborted (core dumped)

如果您查看 ls 的源代码,您可能会看到 abort() 函数调用,尤其是当您搜索它打印的字符串时。

正如我所说,bash 和大多数其他 shell 不这样做。


如果你确实想修复它,你可能想创建一个指针数组 {"/bin//ls", NULL} 并将指向它的指针作为第二个参数传递。

    ...
mov ebx, esp ; path

push eax ; 0
push ebx ; pointer to the filename
mov ecx, esp ; argv = pointer to that array

cdq ; envp = EDX = 0 (broadcast high bit of EAX into EDX)

mov al, 0xb
int 0x80

为了更好的测量,我添加了 EDX 归零。

这对我有用:ls 成功运行。

关于linux - 如何修复 'SYSCALL execve' : ls complains about a NULL argv[0],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57682494/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com