Skip to content

Instantly share code, notes, and snippets.

@trevd
Created May 30, 2014 13:28
Show Gist options
  • Save trevd/2feb2eb504e2884f2dec to your computer and use it in GitHub Desktop.
Save trevd/2feb2eb504e2884f2dec to your computer and use it in GitHub Desktop.
simple cat x86 assembly
#define __ASSEMBLY__
#include <asm/unistd.h>
#include <asm/mman.h>
#include <asm/types.h>
# make shit more readable - there'll be no "magic numbers" here
#define NULL 0
# syscall interupt
#define SYSCALL 0x80
# stdin , out and err
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#file access flags
#define O_RDONLY 0
# Pogram exit codes
#define EXIT_SUCCESS 0
#define EXIT_FAILURE_LSTAT 1
#define EXIT_FAILURE_OPEN 2
#define EXIT_FAILURE_MMAP 3
# mmap related
#define MAP_OFFSET_ZERO 0
#define MAX_ERRNO 4095
.section .bss
# reserve 96 bytes for struct_stat
.lcomm struct_stat,96
# st_size is 44 bytes into the structure
#define st_size struct_stat+44
# reserve 4 bytes for out file handle
.lcomm fd, 4
# reserve 4 bytes for the pointer to the memory mapped file
.lcomm mapped_file_ptr, 4
# text section - this is where our code lives
.section .text
# make our entry point knowing to the linker
.global _start
# Program entry point
_start:
# Prologue setup a stack frame
push %ebp
mov %esp, %ebp
# int lstat(const char *path, struct stat *buf);
# lstat( 12(%ebp) , struct_stat )
mov $struct_stat, %ecx
mov 12(%ebp), %ebx
mov $__NR_lstat64, %eax
int $SYSCALL
# test eax and jump if the signed flag is set
# i.e eax = -1
test %eax, %eax
js exit_cannot_lstat_file
# int open(const char *pathname, int flags);
# open ( 12(%ebp) , O_RDONLY )
mov $O_RDONLY, %ecx
mov 12(%ebp), %ebx
mov $__NR_open, %eax
int $SYSCALL
# test eax and jump if the signed flag is set
# i.e eax = -1
test %eax, %eax
js exit_cannot_open_file
# stash the open file handle away.
# we could probably push this onto the stack .. meh!
mov %eax, fd
# void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
# mmap( NULL,st_size,PROT_READ,MAP_SHARED,fd,MAP_OFFSET_ZERO)
# mmap uses the stack for it arguments.
#mov $MAP_OFFSET_ZERO, %eax
#sarl $12, %eax
push $MAP_OFFSET_ZERO #%eax
push fd
push $MAP_PRIVATE
push $PROT_READ
push st_size
push $NULL
mov %esp, %ebx
mov $__NR_mmap, %eax
int $SYSCALL
# on x86_64 it seems like eax starts with ffff...
# testing this full value will set the signed flag
# just test ax instead...
# There's Probably a better way to do this but I don't know it.. yet
cmp $-MAX_ERRNO, %eax
ja exit_cannot_mmap_file
# stash the mapped file pointer
mov %eax, mapped_file_ptr
# tidy up the stack by moving the stack pointer back 24 bytes
add $24, %esp
# move argv[1] into eax for strlen
#mov 12(%ebp), %eax
#call _strlen
# ssize_t write(int fd, const void *buf, size_t count);
# write(STDOUT_FILENO, mapped_file_ptr, size_t st_size)
mov st_size, %edx
mov mapped_file_ptr, %ecx
mov $STDOUT_FILENO, %ebx
mov $__NR_write, %eax
int $SYSCALL
# int munmap(void *addr, size_t length);
# munmap(mapped_file_ptr, st_size);
mov st_size, %ecx
mov mapped_file_ptr, %ebx
mov $__NR_munmap, %eax
int $SYSCALL
# int close(int fd);
# close(fd);
mov fd, %ebx
mov $__NR_close, %eax
int $SYSCALL
exit_success:
mov $EXIT_SUCCESS,%ebx
jmp exit
exit_cannot_lstat_file:
mov $EXIT_FAILURE_LSTAT,%ebx
jmp exit
exit_cannot_open_file:
mov $EXIT_FAILURE_OPEN, %ebx
jmp exit
exit_cannot_mmap_file:
# int close(int fd);
# close(fd);
mov fd, %ebx
mov $__NR_close, %eax
int $SYSCALL
mov $EXIT_FAILURE_MMAP,%ebx
jmp exit
exit:
# void exit(int status);
# see above for EXIT_ status
mov $__NR_exit, %eax
pop %ebp
int $SYSCALL
#undef __ASSEMBLY__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment