# ELF header # e_ident: u128 # Magic number: 0x7f454c46 = "\x7fELF" 7f 45 4c 46 02 # EI_CLASS: u8 = ELFCLASS64 01 # EI_DATA: u8 = ELFDATA2LSB 01 # EI_VERSION: u8 = EV_CURRENT 00 # EI_OSABI: u8 = ELFOSABI_NONE 00 # EI_ABIVERSION: u8 = 0 00 00 00 00 00 00 00 # EI_PAD: [u8; 7] # e_type: u16 = E_EXEC 02 00 # e_machine: u16 = EM_X86_64 3e 00 # e_version: u32 = EV_CURRENT 01 00 00 00 # e_entry: u64 = 0x400000 00 00 40 00 00 00 00 00 # e_phoff: u64 = 0x40 40 00 00 00 00 00 00 00 # e_shoff: u64 = 0x0 00 00 00 00 00 00 00 00 # e_flags: u32 = 0 00 00 00 00 # e_ehsize: u16 = 64 40 00 # e_phentsize: u16 = 56 38 00 # e_phnum: u16 = 1 01 00 # e_shentsize: u16 = 0 00 00 # e_shnum: u16 = 0 00 00 # e_shstrndx: u16 = 0 00 00 # End of ELF header # # Program header # p_type: u32 = PT_LOAD 01 00 00 00 # p_flags: u32 = PF_R | PF_X 05 00 00 00 # p_offset: u64 = 0 00 00 00 00 00 00 00 00 # p_vaddr: u64 = 0x400000 00 00 40 00 00 00 00 00 # p_paddr: u64 = 0x0 00 00 00 00 00 00 00 00 # p_filesz: u64 = 0x164 64 01 00 00 00 00 00 00 # p_memsz: u64 = 0x1000 00 10 00 00 00 00 00 00 # p_align: u64 = 0x1000 00 10 00 00 00 00 00 00 # End of program header # # Code segment (offset 0x40, virtual address 0x400000) # # _start: # ; alloca 0x1000 bytes on the stack # mov rbp, rsp 48 89 e5 # sub rsp, 0x1000 48 81 ec 00 10 00 00 # ; read 0x800 bytes from stdin into the stack # .READ: (_start+10) # xor rax, rax 48 31 c0 # mov edi, 0 (stdin) 48 c7 c7 00 00 00 00 # mov rsi, rsp 48 89 e6 # mov rdx, 0x800 48 c7 c2 00 08 00 00 # syscall (sys_read) 0f 05 # cmp rax, 0 48 83 f8 00 # jle die 0f 8e a1 00 00 00 # 203 - 42 = 161 = 0xa1 ## (_start+42) # ; end = r8 # mov r8, rax 49 89 c0 # add r8, rsp 49 01 e0 # ; pos = r9 # mov r9, rsp 49 89 e1 # ; dst = r10 # mov r10, rsp 49 89 e2 # add r10, 0x800 49 81 c2 00 08 00 00 # ; while (pos < end) { # ; .L0: (_start+61) # cmp r9, r8 4d 39 c1 # jge .L3 0f 8d 60 00 00 00 ; 166 - 70 = 96 = 0x60 # (_start+70) # # ; if (*pos == '#') { # mov al , byte [r9] 41 8a 41 00 # cmp al, '#' 3c 23 # jne .L1 ; 100 - 82 = 18 = 0x12 0f 85 12 00 00 00 # (_start+82) # ; while (*pos != '\n') pos++; # ; .L2: (_start+82) # inc r9 49 ff c1 # cmp byte [r9], '\n' 41 80 39 0a # jne .L2 ; 82 - 95 = -13 = 0xfffffffffffffff3 = 0xf3 0f 85 f3 ff ff ff # (_start+95) # jmp .L0 ; 61 - 100 = -39 = 0xfffffffffffffd89 = 0xfd89 e9 89 fd ff ff # (_start+100) # ; .L1: (_start+100) # ; convert *pos to high word # mov bl, al 88 c3 # sub bl, 'a' 80 eb 61 # add bl, 10 80 c3 0a # sub al, '0' 2c 30 # cmp al, 10 3c 0a # cmovge eax, ebx 0f 43 c3 # shl al, 4 c0 e0 04 # ; pos++ # inc r9 49 ff c1 # ; convert *pos to low word # mov bl, byte [r9] 41 8a 19 # mov cl, bl 88 d9 # sub cl, 'a' 80 e9 61 # add cl, 10 80 c1 0a # sub bl, '0' 80 eb 30 # cmp bl, 10 80 fb 0a # cmovge ebx, ecx 0f 4d d9 # ; combine high and low word # or al, bl 08 d8 # ; write the byte to dst # mov byte [r10], al 41 88 02 # inc r10 41 ff c2 # ; if (*pos != '\n') pos++; # cmp byte [r9], '\n' 41 80 39 0a # inc r9 49 ff c1 # je .L0 ; 61 - 161 = -100 = 0xffffffffffffff9c = 0x9c 0f 84 9c ff ff ff ## (_start+161) # jmp .L1 ; 100 - 166 = -66 = 0xffffffffffffffbe = 0xbe e9 be ff ff ff ## (_start+166) # ; } # .L3: (_start+166) # ; write the decoded bytes to stdout # mov rax, 1 (sys_write) 48 c7 c0 01 00 00 00 # mov rdi, 1 (stdout) 48 c7 c7 01 00 00 00 # mov rsi, rsp 48 89 e6 # add rsi, 0x800 48 81 c6 00 08 00 00 # mov rdx, r10 4c 89 d2 # sub rdx, rsi 48 29 f2 # syscall 0f 05 # jmp .READ ; 10 - 203 = -193 = 0xffffffffffffff3f = 0x3f e9 3f ff ff ff ## (_start+203) # # die: (_start+203) # mov rax, 60 (sys_exit) 48 c7 c0 3c 00 00 00 # xor rdi, rdi 48 31 ff # syscall 0f 05 # _start+215