0

I can't explain why this code doesn't work.

#include <stdio.h>

int main() {
    char *command[] = { "/bin/sh", NULL };

    asm volatile(
        "movl $11, %%eax\n"      
        "movl %0, %%ebx\n"       
        "movl $0, %%ecx\n"       
        "xorl %%edx, %%edx\n"    
        "int $0x80\n"            
        :
        : "g"(command)
        : "%eax", "%ebx", "%ecx", "%edx"
    );

    perror("execve failed");
    return 1;
}

I wrote this code to make a call to execve and get a shell but when I run it, I get

execve failed: Success

so no errno was entered. And while running in gdb I got the return value, 0xfffffffe -> -2 but in the man page write that if failed -1 is returned and errno is set

"On success, execve() does not return, on error -1 is returned, and errno is set appropriately"

Does someone have any idea what going on?

comepiled with gcc -m32 -o test test.c

gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)
  • 2
    The raw syscall (what you are doing) and the Glibc wrapper functions (`exec*`) are two different things. If you call the raw syscall from assembly, you will have to decode the returned value yourself, and no errno exists. `errno` is purely a glibc concept, the kernel knows nothing about it. The returned value from a raw syscall can be a negative error code. In your case `-2` means `ENOENT`. – Marco Bonelli May 26 '23 at 10:40
  • 2
    The raw `int $0x80` system call doesn't set `errno`, the libc wrapper function has to do that, but you didn't call it. As you saw, the negative return value from the kernel only exists in EAX. Use `strace ./test` to decode it, or do `"=a"(errno)` as an operand to the asm. – Peter Cordes May 26 '23 at 10:40
  • 1
    BTW, the reason it fails is that you passed a pointer to a pointer, not a pointer to a string. `strace` will show you what you passed. – Peter Cordes May 26 '23 at 10:41
  • 1
    I'm very curious about why you do a direct raw syscall using inline assembly? What is the reason for that? What problem, if any, is that supposed to solve? Or it it just plain curiosity? – Some programmer dude May 26 '23 at 10:45
  • you right, I missed it. but why the man 2 execve tell me about the gnu wrapper of the syscall and not the one provided by the kernel – nadav levin May 26 '23 at 10:47
  • doing some pwn ctf challenge for fun and try to check why my syscall don't work when I run the ropchain attack. – nadav levin May 26 '23 at 10:51

0 Answers0