flat assembler
Message board for the users of flat assembler.

Index > Linux > 142-byte ELF64 that prints "Hello!"

Author
Thread Post new topic Reply to topic
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 16 Oct 2021, 18:16
Too bored at home. It's Saturday night!

So I try to make smallest ELF64 that prints "Hello!" .
This is the side-by-side comparison with ELF64 hello64.asm FASM's example.

Quote:

142 bytes tiny.bin
216 bytes hello64


This is the hello64.asm:

Code:
format ELF64 executable 3

segment readable executable

entry $

        mov     edx,msg_size
        lea     rsi,[msg]
        mov     edi,1           ; STDOUT
        mov     eax,1           ; sys_write
        syscall

        xor     edi,edi
        mov     eax,60          ; sys_exit
        syscall

segment readable writeable

msg db 'Hello!',0xA
msg_size = $-msg
    


And if you want to encode any string no longer than 7 characters, you can probably use mine:

Code:
ORG 0x400000
        
USE64        
        db 0x7F, "ELF"      ; EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3  
        db 0x02             ; EI_CLASS (2=ELFCLASS64)
        db 0x01             ; EI_DATA (1-ELFDATA2LSB)
        db 0x01             ; EI_VERSION
        db 0x03             ; EI_OSABI
        db 0x00
        db "Hello!",0x0A
        dw 2                ; ET_EXEC               e_type
        dw 0x3E             ;                       e_machine
        dd 1                ;                       e_version
        dq _start - $$ + 0x400000  ;                e_entry
        dq phdr - $$        ;                       e_phoff
        dq 0x00             ;                       e_shoff
        dd 0x00             ;                       e_flags
        dw phdr - $$        ;                       e_ehsize
        dw _start - phdr    ;                       e_phentsize
        dw 0x01             ;                       e_phnum
        dw 0x40             ;                       e_shentsize
        dw 0x00             ;                       e_shnum
        dw 0x00             ;                       e_shstmdx

phdr:
        dd 0x01             ; PT_LOAD               p_type
        dd 0x05             ; PF_X + PF_W + PF_R    p_flags
        dq 0x00             ;                       p_offset
        dq 0x400000         ; 0x400000              p_vaddr
        dq 0x400000         ; 0x400000              p_paddr
        dq _end-_start      ;                       p_filesz
        dq _end-_start      ;                       p_memsz    
        dq 0x100            ;                       p_align             
              
_start:
        mov al, 1         ; sys_write
        mov edi, eax      ; STDOUT = 1
        mov rsi, 0x400009  
        mov dl, 7         ; length = "Hello!\n"
        syscall
        mov al, 60        ; sys_exit
        xor rdi, rdi
        syscall     

_end:
    


That is 74 bytes saving. Just one program header.
Laughing

Anyone with smaller ELF64 than 142 bytes?

Wait.... I did not know we can combine into one segment: 160 bytes!

Code:
format ELF64 executable 3

segment readable writeable executable

msg db 'Hello!',0xA
msg_size = $-msg

entry $

        mov     edx,msg_size
        lea     rsi,[msg]
        mov     edi,1           ; STDOUT
        mov     eax,1           ; sys_write
        syscall

        xor     edi,edi
        mov     eax,60          ; sys_exit
        syscall    
Post 16 Oct 2021, 18:16
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 16 Oct 2021, 20:31
Code:
format ELF64 executable 3

segment readable executable

msg db msg_size, 'Hello!',0xA
msg_size = $ - msg - 1

entry $
        xor     eax, eax
        lea     rsi, [msg]
        lods    byte [rsi]      ; rax = msg_size
        mov     edx, eax
        mov     al, 1
        mov     edi, eax        ; sys_write
        syscall

        xor     edi, edi
        mov     al, 60          ; sys_exit
        syscall                 ; total 152 bytes    
Saturday, eh Very Happy
Post 16 Oct 2021, 20:31
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 16 Oct 2021, 21:04
Code:
        lea rsi,[msg]
        push msg_size
        push 1
        pop rdi
        pop rdx
        mov eax,edi
        syscall    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 16 Oct 2021, 21:04
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 16 Oct 2021, 21:44
bitRAKE wrote:
Code:
        lea rsi,[msg]
        push msg_size
        push 1
        pop rdi
        pop rdx
        mov eax,edi
        syscall    
Code:
ORG 0x400000
        
USE64        
        db 0x7F, "ELF"      ; EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3  
        db 0x02             ; EI_CLASS (2=ELFCLASS64)
        db 0x01             ; EI_DATA (1-ELFDATA2LSB)
        db 0x01             ; EI_VERSION
        db 0x03             ; EI_OSABI
        db 0x00
  @@    db "Hello!",0x0A
  msg_size = $ - @b
        dw 2                ; ET_EXEC               e_type
        dw 0x3E             ;                       e_machine
        dd 1                ;                       e_version
        dq _start - $$ + 0x400000  ;                e_entry
        dq phdr - $$        ;                       e_phoff
        dq 0x00             ;                       e_shoff
        dd 0x00             ;                       e_flags
        dw phdr - $$        ;                       e_ehsize
        dw _start - phdr    ;                       e_phentsize
        dw 0x01             ;                       e_phnum
        dw 0x40             ;                       e_shentsize
        dw 0x00             ;                       e_shnum
        dw 0x00             ;                       e_shstmdx

phdr:
        dd 0x01             ; PT_LOAD               p_type
        dd 0x05             ; PF_X + PF_W + PF_R    p_flags
        dq 0x00             ;                       p_offset
        dq 0x400000         ; 0x400000              p_vaddr
        dq 0x400000         ; 0x400000              p_paddr
        dq _end-_start      ;                       p_filesz
        dq _end-_start      ;                       p_memsz    
        dq 0x100            ;                       p_align             
              
_start:
        lea rsi, [@b]
        push msg_size
        push 1
        pop rdi           ; STDOUT = 1
        pop rdx
        mov eax, edi      ; sys_write
        syscall
        xor edi, edi      ; source: xor rdi, rdi
        mov al, 60        ; sys_exit
        syscall
_end:    
143 bytes, but that's if you don't break and clear the upper part. But in the source text, you can also discard another 1 prefix. Then it will be reduced to 141 bytes.
Post 16 Oct 2021, 21:44
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 16 Oct 2021, 21:51
You don't need to set RDI to exit.

And there are some fields in the headers that are never used by the loader so some sort of value abuse could also be used there. But that would rely upon certain versions of the loader to being used in the target system.
Post 16 Oct 2021, 21:51
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1042
Location: Russia
macomics 16 Oct 2021, 23:59
revolution wrote:
You don't need to set RDI to exit.

And there are some fields in the headers that are never used by the loader so some sort of value abuse could also be used there. But that would rely upon certain versions of the loader to being used in the target system.
I agree. Since it is violated, then why finish the program with the code 0, than 1 is worseee...
So, only code optimization has already reduced tiny.bin up to 139 bytes (-3 bytes).
Most likely, the author of the source code tried to preserve alignment by adding (leaving) redundant fields. So his header turned out to be exactly 128 bytes.
Saturday night - there's nothing for everyone to do Very Happy
Post 16 Oct 2021, 23:59
View user's profile Send private message Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 17 Oct 2021, 05:28
Thank you, macomics, bitRAKE and revolution for taking part in this thread.

macomics wrote:
143 bytes, but that's if you don't break and clear the upper part. But in the source text, you can also discard another 1 prefix. Then it will be reduced to 141 bytes.


Thanks for the "xor edi, edi" (instead of using rdi).

May I know what is "@@:" and "@b"? I am new to this, but have seen it multiple times on this forum.
Post 17 Oct 2021, 05:28
View user's profile Send private message Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 17 Oct 2021, 06:05
I managed to squeeze it further down to 129 bytes by omitting some fields.

But "readelf" would report this:
Quote:

Section header string table index: 5 <corrupt: out of range>


The size of headers is 114 bytes.
Quote:

Size of this header: 58 (bytes)
Size of program headers: 56 (bytes)


In case anyone is still interested:
Code:
ORG 0x400000
        
USE64        
        db 0x7F, "ELF"      ; EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3  
        db 0x02             ; EI_CLASS (2=ELFCLASS64)
        db 0x01             ; EI_DATA (1-ELFDATA2LSB)
        db 0x01             ; EI_VERSION
        db 0x03             ; EI_OSABI
        db 0x00
  @@    db "Hello!",0x0A
  msg_size = $ - @b
        dw 2                ; ET_EXEC               e_type
        dw 0x3E             ;                       e_machine
        dd 1                ;                       e_version
        dq _start - $$ + 0x400000  ;                e_entry
        dq phdr - $$        ;                       e_phoff
        dq 0x00             ;                       e_shoff
        dd 0x00             ;                       e_flags
        dw phdr - $$        ;                       e_ehsize
        dw _start - phdr    ;                       e_phentsize
        dw 0x01             ;                       e_phnum
        ;dw 0x40             ;                       e_shentsize
        ;dw 0x00             ;                       e_shnum
        ;dw 0x00             ;                       e_shstmdx

phdr:
        dd 0x01             ; PT_LOAD               p_type
        dd 0x05             ; PF_X + PF_W + PF_R    p_flags
        dq 0x00             ;                       p_offset
        dq 0x400000         ; 0x400000              p_vaddr
        dq 0x400000         ; 0x400000              p_paddr
        dq _end-_start      ;                       p_filesz
        dq _end-_start      ;                       p_memsz    
        dq 0x100            ;                       p_align             
              
_start:
        ;lea esi, [@b]
        mov esi, 0x400009
        mov dl, msg_size
        mov al, 1         ; sys_write
        ;mov dil, 1       ; STDOUT = 1
        syscall
        mov al, 60        ; sys_exit
        syscall
_end:    
    
Post 17 Oct 2021, 06:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 17 Oct 2021, 06:08
FlierMate wrote:
Thanks for the "xor edi, edi" (instead of using rdi).
You can remove it entirely.
Post 17 Oct 2021, 06:08
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.