Skip to the content.

AssemblyLine

Unit Tests Code Style Version AUR Version

An ultra-lightweight C library and binary for generating machine code of x86_64 assembly language and executing on the fly without invoking another compiler, assembler or linker.

How to Install

We have packages in the AUR.
Otherwise clone this repo or get a stable release tarball.

$ ./autogen.sh # when `git clone`d
$ ./configure && \
make  && \
sudo make install

Usage

  1. $ cc your_program.c -lassemblyline to use the library and compile a C program using assemblyline

  2. $ echo -e "mov rax, 0xADE1A1DE\nret" | asmline -r to use our asmline-cli tool
    (Will print ‘the value is 0xade1a1de’)

Jumpstart library

Full code example:

#include <assemblyline.h> // all assemblyline functions
#include <stdint.h>       // uint8_t
#include <stdio.h>        // printf
#include <sys/mman.h>     // mmap

int main() {
  const int buffer_size = 300; // bytes
  uint8_t *mybuffer = mmap(NULL, sizeof(uint8_t) * buffer_size,
                           PROT_READ | PROT_WRITE | PROT_EXEC,
                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

  assemblyline_t al = asm_create_instance(mybuffer, buffer_size);

  asm_assemble_str(al, "mov rax, 0x0\nadd rax, 0x2; adds two");
  asm_assemble_str(al, "sub rax, 0x1; subs one\nret");

  int (*func)() = asm_get_code(al);

  int result = func();
  printf("The result is: %d\n", result);
  // prints "The result is: 1\n"

  asm_destroy_instance(al);
  munmap(mybuffer, buffer_size);
}

Lets dissect the example (and give alternatives):

  1. Include the required header files and preprocessors
     #include <assemblyline.h> // all assemblyline functions
     #include <stdint.h>       // uint8_t
     #include <stdio.h>        // printf
     #include <sys/mman.h>     // mmap
    
  2. Allocate an executable buffer of sufficient size (> 20 bytes) using mmap
     // the machine code will be written to this location
    const int buffer_size = 300; // bytes
    uint8_t *mybuffer = mmap(NULL, sizeof(uint8_t) * buffer_size,
                             PROT_READ | PROT_WRITE | PROT_EXEC,
                             MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    
  3. Create an instance of assemblyline_t and attach mybuffer (or NULL, 0 for internal memory allocation)
     // manual memory allocation
     assemblyline_t al = asm_create_instance(mybuffer, buffer_size);
    
     // assemblyline-managed memory allocation
     assemblyline_t al = asm_create_instance(NULL, 0);
    
  4. Assemble a file or string containing. The machine code will be written to mybuffer (or the internal buffer). Call those functions sequentially; subsequent new machine code will be appended at the end of the last instruction. Separate instructions with \n.
     asm_assemble_file(al, "./path/to/x64_file.asm");
     asm_assemble_str(al, "mov rax, 0x0\nadd rax, 0x2; adds two");
     asm_assemble_str(al, "sub rax, 0x1; subs one\nret");
    
  5. Get the start address of the buffer containing the start of the assembly program
     void (*func)() = asm_get_code(al);
    
     // call the function
     int result = func();
    
  6. Free all memory associated with assembyline (an external buffer is not freed)
     asm_destroy_instance(al);
     munmap(mybuffer, buffer_size);
    


Note: for more information see /src/assemblyline.h or run $ man libassemblyline for more information

Jumpstart Cli-tool: asmline

The general usage is asmline [OPTIONS]... FILE. asmline --help for all options.

; jump.asm
mov rcx, 0x123
jmp 0x4
add rcx, 1
mov rax, rcx
ret

Use -p for printing ASCII-hex to stdout

$ asmline -p jump.asm
b9 23 01 00 00 
eb 04 
48 83 c1 01 
48 89 c8 
c3 

Or pipe directly into it, use -r to run the code:

$ echo -n 'mov rax, 0xC0FFEE\nret' | asmline -pr
b8 ee ff c0 00 
c3 

# the value is 0xc0ffee

See tools/README.md for more info.

Adding new instructions

To add support for new instructions see src/README.md for more info.

Test files

$ make check to run all test suites (repo must be cloned for this to work)

Contributing

We welcome any kind of contribution. Feel free to open issues if something is broken or you’d need feature. Or open up a PR if you’ve enhanced AssemblyLine already and want to see it here.

Acknowledgements

Authors:

This project was supported by: