Linux 系统调用导致分段错误

Linux 系统调用导致分段错误,linux,assembly,x86,32-bit,Linux,Assembly,X86,32 Bit,我正在汇编中编写一个简单的程序,它应该调用setreuid(0,0),然后调用exit()。这是我的密码: section .text ; start code section of assembly global _start _start: xor eax, eax ; setruid call mov al, 0x46 ; get ready for setreuid system call xor ebx, ebx ; arg 1 (0) xor ecx, ecx ; arg 2 (0

我正在汇编中编写一个简单的程序,它应该调用
setreuid(0,0)
,然后调用
exit()
。这是我的密码:

section .text ; start code section of assembly
global _start
_start:
xor eax, eax ; setruid call
mov al,  0x46 ; get ready for setreuid system call
xor ebx, ebx ; arg 1 (0)
xor ecx, ecx ; arg 2 (0)
int 0x80 ; interrupt for setreuid
mov al,  0x01 ; prepare for exit call
int 0x80 ; interrupt for exit <---- 0x0804806c
这将生成程序退出。运行时,我会得到以下信息:

****@debian:~/shellcode$ ./exit
Segmentation fault
****@debian:~/shellcode$ 

实际情况是,setreuid在成功时返回零,在错误时返回-1。您可能是以普通用户的身份运行,不允许该用户设置进程的用户id。由于这个原因,setreuid的返回值是-1,它在二进制中是为eax设置的所有位。通过将al设置为0x01,您只需将最低有效字节设置为1。高位都设置好了,所以实际上在eax中没有传递1。你实际上通过了FFFF01。这不是有效的系统调用,更不用说退出调用了。当它到达第二个int 0x80时,它将继续执行下一条指令,这是不允许读取的。另一件事是,你应该mov ebx,0作为退出调用。碰巧您之前对ebx进行了异或操作,但这是一个潜在的bug,等待发生。

您应该在第二次系统调用之前将eax重新归零。第一个系统调用的返回值就在那里,如果它设置了
mov al,0x01
没有重置的任何位,那么你将调用其他调用。为什么不直接调用
mov eax,0x46
0x01
?@AndrewMedico好主意,我试过了,但它仍然崩溃。@WilliamAndrewMontgomery我试过了,但它仍然有一个分段错误。然后你做了其他错误的事情,例如没有运行程序的当前版本。
****@debian:~/shellcode$ ./exit
Segmentation fault
****@debian:~/shellcode$