; truefalse-TinyElf64.asm - by Pegasus Epsilon <pegasus@pimpninjas.org>
; (C) 2013 Distribute Unmodified
;
; build with nasm tinytrue64.asm -o tinytrue64 && chmod +x tinytrue64
; result should be 117 bytes
;
; Note that this won't help anything on any filesystem without file
; tails because any file occupies at least a full block on those
; filesystems, and this file's resulting binary is far tinier than a
; single block in any filesystem or drive that I've ever seen.
BITS 64
org 0x400000
elf_ident:
db 0x7F, "ELF" ; EI_MAG = ELF magic
; db 2 ; EI_CLASS = ELFCLASS64 (elf64) -- ignored
; db 1 ; EI_DATA = ELFDATA2LSB (little-endian) -- ignored
; db 1 ; EI_VERSION = EV_CURRENT -- ignored
; db 0 ; null terminator -- ignored
; db 0 ; ABI version -- ignored
; times 7 db 0 ; whee padding
entry: ; let's replace all that wasted space with something useful
pop rdi ;1 rdi = argc
pop rdi ;1 rdi = argv[0]
mov rdx, rdi ;3 rdx = rdi = argv[0]
dec ecx ;2 search for 4,294,967,295 bytes before giving up
repne scasb ;2 rdi = strchrnul(argv[0])
std ;1 search backwards
jmp e_version ;2
elf_hdr:
dw 2 ; Elf64_Half e_type = ET_EXEC -- required
dw 0x3E ; Elf64_Half e_machine = AMD x64 -- required
; dd 1 ; Elf64_Word e_version = 1 -- ignored
e_version:
mov al, '/' ;2 find the last slash
jmp e_ehsize ;2
dq entry ; Elf64_Addr e_entry = entry point -- fudgable
dq prog_hdr - $$ ; Elf64_Off e_phoff = prog_hdr offset -- required
; dq 0 ; Elf64_Off e_shoff = 0 -- ignored
; dd 0 ; Elf64_Word e_flags = 0 -- ignored
; dw prog_hdr - elf_ident ; Elf64_Half e_ehsize = elf_hdr_size -- ignored
e_ehsize:
mov rcx, rdi ;3 copy the final offset into rcx
sub rcx, rdx ;3 voila, rcx = strlen(argv[0])
scasb ;1 reenter the string
repne scasb ;2 rdi = strrchr(argv[0], '/') or argv[0] if no slash
cld ;1 move forward
mov al, 't' ;2 load the 't'
jmp e_shentsize ;2
dw 7 * 8 ; Elf64_Half e_phentsize -- required
dw 1 ; Elf64_Half e_phnum = 1 -- required
; dw 0x40 ; Elf64_Half e_shentsize = 64 -- ignored
; dw 0 ; Elf64_Half e_shnum = 0 -- ignored
; dw 0 ; Elf64_Half e_shstrndx = 0 -- ignored
e_shentsize:
scasb ;1 reenter the string
jmp p_paddr ;2 if slash found
; You can insert arbitrary data here. FYI.
prog_hdr:
dd 1 ; Elf64_Word p_type = 1 -- required
dd 5 ; Elf64_Word p_flags = PF_R | PF_X -- required
dq 4 ; Elf64_Off p_offset = 0 -- fudgable
dq $$ + 4 ; Elf64_Addr p_vaddr = org -- fudgable
; dq $$ ; Elf64_Addr p_paddr = org -- ignored
p_paddr:
jrcxz noslash ;2 if slash not found
scasb ;1 skip the slash
noslash:
scasb ;1 look for the 't'
je true ;2 if 't' found
jmp false ;2 if 't' not found
dq end - $$ - 4 ; Elf64_Xword p_filesz = size of file -- fudgable
dq end - $$ - 4 ; Elf64_Xword p_memsz = size of file -- fudgable
; dq 0x200000 ; Elf64_Xword p_align -- ignored
false:
inc ebx ;2 false returns 1
true:
xor al, al ;2
inc eax ;2 exit with errorlevel
int 0x80 ;2 syscall
end: