A 32-bit ARM Linux program written in assembly using customasm.
It converts lowercase characters to uppercase, leaving other characters untouched.
The idea behind this project was to produce a working Linux binary without relying on any tool that contains knowledge about Linux or any specific CPU. Surprisingly enough, all that's needed to achieve this is:
- An agnostic assembler
- The ELF specification (to produce a working executable)
- The instruction set specification for the target architecture (for the actual program)
- The Linux system call specification (to communicate with the kernel)
Here's the corresponding tools and resources I ended up using:
- First python, then the amazing customasm project
- In-depth: ELF - The Extensible & Linkable Format by stacksmashing
- The THUMB instruction set reference document
- The Linux system call table for ARM 32-bit
I also used some bits of the following ARM documents:
- The ARM instruction set reference document
- The ARM-THUMB procedure call standard
- The quick reference card for THUMB
First install qemu and customasm:
# Install qemu, unless you're already on a raspberry pi
$ sudo apt install qemu-user
# Install customasm, or download from: https://github.com/hlorenzi/customasm/releases
$ cargo install customasm
Then assemble the upper
binary:
# Assemble with customasm and give executable access
$ customasm upper.asm -o upper && chmod +x upper
customasm v0.11.4 (x86_64-unknown-linux-gnu)
assembling `upper.asm`...
writing `upper`...
success
And try it out:
# Run with qemu explicitely
$ qemu-arm upper --help
Usage: upper [OPTION]
Transform lowercase ascii characters to uppercase.
Other ascii characters are left untouched.
Data is read from stdin and written to stdout.
--help display this help and exit
# Or implicitely
$ echo "1.. 2.. This is a test.." | ./upper
1.. 2.. THIS IS A TEST..
# The binary is actually quite small, less than half a KB
wc -c upper
475 upper
# customasm can also produce an annotated binary
$ customasm upper.asm -f annotated -p
customasm v0.11.4 (x86_64-unknown-linux-gnu)
assembling `upper.asm`...
success
outp | addr | data
0:0 | 0 | 7f ; #d 0x7f
1:0 | 1 | 45 4c 46 ; "ELF"
...