Skip to content

Instantly share code, notes, and snippets.

@yellowbyte
Last active October 14, 2024 15:56
Show Gist options
  • Save yellowbyte/d91da3c3b0bc3ee6d1d1ac5327b1b4b2 to your computer and use it in GitHub Desktop.
Save yellowbyte/d91da3c3b0bc3ee6d1d1ac5327b1b4b2 to your computer and use it in GitHub Desktop.
how to assemble assembly with NASM assembler to 32-bit or 64-bit ELF binary with or without libc

32-bit ELF binary

how to assemble and link:

nasm -f elf32 -o <filename>.o <filename>.asm
ld -m elf_i386 -o <filename> <filename>.o

template code (hello world):

section .text
global _start

%define system_call int 0x80

_start:
    mov ebx, 0x1
    mov ecx, hello
    mov edx, helloLen
    mov eax, 0x4
    system_call

    xor ebx, ebx
    mov eax, 0x1
    system_call

section .data
    hello db "Hello World", 0xa
    helloLen equ $-hello

64-bit ELF binary

how to assemble and link:

nasm -f elf64 -o <filename>.o <filename>.asm
ld -o <filename> <filename>.o

template code (hello world):

section .text
global _start

_start:
    mov rdi, 0x1
    mov rsi, hello
    mov rdx, helloLen
    mov rax, 0x1
    syscall

    xor rdi, rdi
    mov rax, 0x3c
    syscall

section .data
    hello db "Hello World", 0xa
    helloLen equ $-hello

32-bit ELF binary with libc

how to assemble and link:

nasm -f elf32 -o <filename>.o <filename>.asm
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o <filename> -lc <filename>.o

template code (hello world):

extern puts
extern exit

section .text
global _start

%macro call_func 1
    call %1
    add esp, 0x4
%endmacro

_start:
    push hello
    call_func puts

    mov eax, 0xa
    call exit

section .data
    hello db "Hello World"

64-bit ELF binary with libc

how to assemble and link:

nasm -f elf64 -o <filename>.o <filename>.asm
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o <filename> -lc <filename>.o

template code (hello world):

extern puts
extern exit

section .text
global _start

%macro call_func 1
    call %1
%endmacro

_start:
    mov rdi, hello
    call_func puts

    mov rax, 0xa 
    call exit

section .data
    hello db "Hello World"

NOTE :

  • Assembler Directives: instructions for the assembler (e.g. NASM) and not a part of the ISA
    • extern: declare a symbol which is defined in another module that will later be linked with current one
    • section: identifies the section the code you write will go into. Examples of common ones are .text, .data, and .bss
    • global: defines symbols such that other modules that EXTERN those symbols can correctly reference them after linking
    • macro: a name that represents a snippet of code
    • define: a single-line macro
@yellowbyte
Copy link
Author

yellowbyte commented Oct 12, 2021

Ohh no need to take too much time trying to find it. If you just happen to come across it again in the future, feel free to share :)

@torbjo
Copy link

torbjo commented May 30, 2022

There is (at least) one bug in the "64-bit ELF binary with libc" example:

The argument to 'puts' is passed in an register (not the stack), so the stack pointer should not be adjusted after the call!

Try returning from '_start' instead of calling libc's 'exit()'. Then it will fail miserably because the stack is messed up.

@yellowbyte
Copy link
Author

Oops, thank you for catching that @torbjo !! Code updated.

@metablaster
Copy link

Thank you a lot for this! very useful for a beginner.

@yellowbyte
Copy link
Author

Glad to hear :)

@b1uerry
Copy link

b1uerry commented May 23, 2023

Thanks a lot !

@yellowbyte
Copy link
Author

For sure!!

@LittleAtariXE
Copy link

Awesome resource, I will steal it from you :D, thanks a lot !!!

@yellowbyte
Copy link
Author

yellowbyte commented Aug 21, 2024

For sure! Glad you found it noteworthy to steal ^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment