Everything about linux

A terminal case of Linux

Has this ever happened to you?

You want to look at a JSON file in your terminal, so you pipe it into jq so you can look at it with colors and stuff.

Cool bear's hot tip
Read more
Fine, we'll relocate our own binary!

Welcome back to the eighteenth and final part of "Making our own executable packer".

In the last article, we had a lot of fun. We already had a "packer" executable, minipak, which joined together stage1 (a launcher), and a compressed version of whichever executable we wanted to pack.

Read more
Running a self-relocatable ELF from memory

Welcome back!

In the last article, we did foundational work on minipak, our ELF packer.

It is now able to receive command-line arguments, environment variables, and auxiliary vectors. It can parse those command-line arguments into a set of options. It can make an ELF file smaller using the LZ4 compression algorithm, and pack it together with stage1, our launcher.

Read more
Everything but ELF

And we're back!

In the last article, we thanked our old code and bade it adieu, for it did not spark joy. And then we made a new, solid foundation, on which we planned to actually make an executable packer.

Read more
Between libcore and libstd

You're still here! Fantastic.

I have good news, and bad news. The good news is, we're actually going to make an executable packer now!

Read more
In the bowels of glibc

Good morning, and welcome back to "how many executables can we run with our custom dynamic loader before things get really out of control".

Read more
A dynamic linker murder mystery

I write a ton of articles about rust. And in those articles, the main focus is about writing Rust code that compiles. Once it compiles, well, we're basically in the clear! Especially if it compiles to a single executable, that's made up entirely of Rust code.

Read more
Thread-local storage

Welcome back and thanks for joining us for the reads notes... the thirteenth installment of our series on ELF files, what they are, what they can do, what does the dynamic linker do to them, and how can we do it ourselves.

Read more
A no_std Rust binary

In Part 11, we spent some time clarifying mechanisms we had previously glossed over: how variables and functions from other ELF objects were accessed at runtime.

Read more
More ELF relocations

In our last installment of "Making our own executable packer", we did some code cleanups. We got rid of a bunch of unsafe code, and found a way to represent memory-mapped data structures safely.

Read more
Dynamic linker speed and correctness

In the last article, we managed to load a program (hello-dl) that uses a single dynamic library (libmsg.so) containing a single exported symbol, msg.

Read more
Dynamic symbol resolution

Let's pick up where we left off: we had just taught elk to load not only an executable, but also its dependencies, and then their dependencies as well.

Read more
Loading multiple ELF objects

Up until now, we've been loading a single ELF file, and there wasn't much structure to how we did it: everyhing just kinda happened in main, in no particular order.

Read more
The simplest shared library

In our last article, we managed to load and execute a PIE (position-independent executable) compiled from the following code:

x86 assembly
; in `samples/hello-pie.asm`

        global _start

        section .text

_start: mov rdi, 1      ; stdout fd
        lea rsi, [rel msg]
        mov rdx, 9      ; 8 chars + newline
        mov rax, 1      ; write syscall
        syscall

        xor rdi, rdi    ; return code 0
        mov rax, 60     ; exit syscall
        syscall

        section .data

msg:    db "hi there", 10
Read more
ELF relocations

The last article, Position-independent code, was a mess. But who could blame us? We looked at the world, and found it to be a chaotic and seemingly nonsensical place. So, in order to blend in, we had to let go of a little bit of sanity.

Read more
Position-independent code

In the last article, we found where code was hiding in our samples/hello executable, by disassembling the whole file and then looking for syscalls.

Read more
Running an executable without exec

In part 1, we've looked at three executables:

  • sample, an assembly program that prints "hi there" using the write system call.
  • entry_point, a C program that prints the address of main using printf
  • The /bin/true executable, probably also a C program (because it's part of GNU coreutils), and which just exits with code 0.
Read more
What's in a Linux executable?

Executables have been fascinating to me ever since I discovered, as a kid, that they were just files. If you renamed a .exe to something else, you could open it in notepad! And if you renamed something else to a .exe, you'd get a neat error dialog.

Read more
Reading files the hard way - Part 1 (node.js, C, rust, strace)

Everybody knows how to use files. You just open up File Explorer, the Finder, or a File Manager, and bam - it's chock-full of files. There's folders and files as far as the eye can see. It's a genuine filapalooza. I have never once heard someone complain there were not enough files on their computer.

Read more
Cross-compilation notes

I'll keep updating this article as I go, just to put stuff in all the same place.

Platforms

Cross-compiling for Linux

Read more
Done scrolling? Go back to the homepage.