hex0.hex0 (6387B)
1 # SPDX-FileCopyrightText: 2017 Jeremiah Orians <jeremiah@pdp10.guru> 2 # SPDX-FileCopyrightText: 2023 Andrius Štikonas <andrius@stikonas.eu> 3 # 4 # SPDX-License-Identifier: GPL-3.0-or-later 5 6 ## ELF Header 7 #:ELF_base 8 7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number 9 10 02 ## e_ident[EI_CLASS] Indicating 64 bit 11 01 ## e_ident[EI_DATA] Indicating little endianness 12 01 ## e_ident[EI_VERSION] Indicating original elf 13 14 03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict 15 00 ## e_ident[EI_ABIVERSION] Set at 0 because none cares 16 17 00 00 00 00 00 00 00 ## e_ident[EI_PAD] 18 02 00 ## e_type Indicating Executable 19 3E 00 ## e_machine Indicating AMD64 20 01 00 00 00 ## e_version Indicating original elf 21 22 78 00 60 00 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address) 23 40 00 00 00 00 00 00 00 ## e_phoff Address of program header table 24 00 00 00 00 00 00 00 00 ## e_shoff Address of section header table 25 26 00 00 00 00 ## e_flags 27 40 00 ## e_ehsize Indicating our 64 Byte header 28 29 38 00 ## e_phentsize size of a program header table 30 01 00 ## e_phnum number of entries in program table 31 32 00 00 ## e_shentsize size of a section header table 33 00 00 ## e_shnum number of entries in section table 34 35 00 00 ## e_shstrndx index of the section names 36 37 ## Program Header 38 #:ELF_program_headers 39 01 00 00 00 ## p_type 40 01 00 00 00 ## p_flags: PF-X = 1 41 00 00 00 00 00 00 00 00 ## p_offset 42 43 00 00 60 00 00 00 00 00 ## p_vaddr 44 00 00 60 00 00 00 00 00 ## p_physaddr 45 46 E5 00 00 00 00 00 00 00 ## p_filesz 47 E5 00 00 00 00 00 00 00 ## p_memsz 48 49 01 00 00 00 00 00 00 00 ## Required alignment 50 51 #:ELF_text 52 53 # Where the ELF Header is going to hit 54 # Simply jump to _start 55 # Our main function 56 #:_start (0x600078) 57 58 ; pop_rax # Get the number of arguments 58 5F ; pop_rdi # Get the program name 59 5F ; pop_rdi # Get the actual input name 60 31F6 ; xor_esi,esi # prepare read_only, rsi = 0 61 6A 02 ; push !2 # prepare syscall number 62 58 ; pop_rax # the syscall number for open() 63 99 ; cdq # Extra sure, rdx = 0 64 0F05 ; syscall # Now open that damn file 65 5F ; pop_rdi # Get the actual output name 66 50 ; push_rax # Preserve the file pointer we were given 67 66BE 4102 ; mov_si, @577 # Prepare file as O_WRONLY|O_CREAT|O_TRUNC 68 66BA C001 ; mov_dx, @448 # Prepare file as RWX for owner only (700 in octal) 69 6A 02 ; push !2 # prepare syscall number 70 58 ; pop_rax # the syscall number for open() 71 0F05 ; syscall # Now open that damn file 72 93 ; xchg_ebx,eax # Preserve the file pointer we were given 73 99 ; cdq # rdx = 0 since file descriptor is nonnegative 74 FFC2 ; inc_edx # rdx = 1 (count for read/write) 75 76 #:loop_reset_all (0x600096) 77 31ED ; xor_ebp,ebp # ebp = 0 (no prior hex val) 78 79 # Comment tracking is done with ecx. 80 # ecx is decremented if we hit a 81 # comment (';' or '#') and reset 82 # if we hit a new-line. 83 #:loop_reset_comment (0x600098) 84 52 ; push_rdx 85 59 ; pop_rcx # Set no current comment 86 #:loop_add_comment (0x60009A) 87 FFC9 ; dec_ecx 88 #:loop (0x60009C) 89 90 # Read a byte 91 5F ; pop_rdi # Get infile 92 54 ; push_rsp 93 5E ; pop_rsi # Set buffer 94 # rdx is already set to 1. 95 31C0 ; xor_eax,eax # Set read syscall in rax 96 51 ; push_rcx # Save comment tracking 97 0F05 ; syscall # Do the actual read 98 59 ; pop_rcx # Restore comment tracking 99 57 ; push_rdi # Re-save infile 100 85C0 ; test_eax,eax # Check what we got 101 75 06 ; jne !cont # No EOF 102 103 # Exit successfully 104 B0 3C ; mov_al, !60 # Set exit syscall in rax 105 31FF ; xor_edi,edi # Set return success (rdi = 0) 106 0F05 ; syscall # Exit 107 108 #:cont (0x6000B0) 109 8A06 ; mov_al,[rsi] # Move prog byte in eax 110 111 # New line check 112 3C 0A ; cmp_al, !10 # Check new-line 113 74 E2 ; je !loop_reset_comment # If new-line, end comment handling 114 115 # In comment check 116 85C9 ; test_ecx,ecx # Skip byte if we are in a comment 117 75 E2 ; jne !loop 118 119 # Start comment check 120 3C 23 ; cmp_al, !35 # Start of '#' comment 121 74 DC ; je !loop_add_comment 122 123 3C 3B ; cmp_al, !59 # Start of ';' comment 124 74 D8 ; je !loop_add_comment 125 126 # Start of hex str to int 127 2C 30 ; sub_al, !48 # Subtract ascii '0' from al 128 2C 0A ; sub_al, !10 # Check for value in '0'-'9' 129 72 08 ; jb !write # We have hex value, write it 130 131 2C 07 ; sub_al, !7 # Subtract ('A'-'0') from al 132 24 DF ; and_al, !0xDF # Remove lower case bit 133 3C 07 ; cmp_al, !7 # Check for value 'A'-'F' 134 73 CC ; jae !loop # We have hex value, write it 135 136 #:write (0x6000D0) 137 C1E5 04 ; shl_ebp, !4 # Shift up existing hex digit 138 04 0A ; add_al, !10 # Finish converting ascii to raw value 139 01C5 ; add_ebp,eax # Combine the hex digits 140 141 # Check if this is first digit in hex val 142 F7DB ; neg_ebx # Flip sign of r10 to indicate we got a digit 143 7C C1 ; jl !loop # Negative -> first digit, get another one 144 145 # We have both digits in low byte of ebp, good to write 146 892E ; mov_[rsi],ebp # Move edge to buffer 147 89DF ; mov_edi,ebx # Move outfile to rdi 148 B0 01 ; mov_al, !1 # Set write syscall in rax 149 0F05 ; syscall # Do the write 150 EB B1 ; jmp !loop_reset_all # Start a fresh byte 151 152 #:ELF_end (0x6000E5)