# 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 = 0x400078 78 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 = 0x167 67 01 00 00 00 00 00 00 # p_memsz: u64 = 0x167 67 01 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=120: # ; 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: (130) # 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 a8 00 00 00 ## (162) # ; 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: (181) # cmp r9, r8 4d 39 c1 # jge .L3 0f 8d 67 00 00 00 # (190) # # ; if (*pos == '#') { # mov al , byte [r9] 41 8a 41 00 # cmp al, '#' 3c 23 # jne .L1 0f 85 15 00 00 00 # (202) # ; while (*pos != '\n') pos++; # ; .L2: (202) # inc r9 49 ff c1 # cmp byte [r9], '\n' 41 80 39 0a # jne .L2 0f 85 f3 ff ff ff # (215) # inc r9 49 ff c1 # jmp .L0 e9 d6 ff ff ff # (223) # ; .L1: (223) # ; convert *pos to high word # mov al, byte [r9] 41 8a 01 # 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 49 ff c2 # inc r9 49 ff c1 # ; if (*pos++ == '\n') goto .L1; # cmp byte [r9], '\n' 41 80 39 0a # je .L0 0f 84 95 ff ff ff ## (288) # jmp .L1 ; - 293 e9 ba ff ff ff ## (293) # ; } # .L3: (293) # ; 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 ; 130 - 330 = -200 = 0xffffffffffffff38 e9 38 ff ff ff ## (330) # # die: (330) # mov rax, 60 (sys_exit) 48 c7 c0 3c 00 00 00 # xor rdi, rdi 48 31 ff # syscall 0f 05 # _start+215