Computers run computer programs to achieve different goals. One program might be your favorite video game, another is the web browser you're using to access this website, and so on.
Though your computer might be running multiple programs at the same time, each CPU will focus on one program at a time (note: this is not fully accurate, but good enough for us for now!). This has analogues in your normal life: you might subscribe to multiple YouTube channels, but at any given moment, you're most likely only watching one episode at a time. However, like a CPU switching between programs, you might indulge changing interests and interleave episodes of different shows.
A program is made of computer code, and this code is made of a huge amount of individual instructions that cause the computer to carry out computation and take certain actions based on the results. Each individual instruction is typically very simple, and only in aggregate do they enable awesome things like let you look at memes on the internet.
This computation is done by the Central Processing Unit (CPU), in tandem with other pieces of hardware inside your computer. Instructions are specified to the CPU in something called Assembly Language, and each CPU architecture uses a different flavor of this language. Any program, no matter what language it is originally written in (e.g., C, C++, Java, Python, etc.), is eventually converted to or interpreted by Assembly instructions.
x86 was created by Intel in the dawn of the PC age, and has continued to evolve over the years. Together, x86 and ARM (a different, less cool architecture) make up the majority of PC CPUs out there.
In this module, we will start out with the simplest x86 program that we can imagine, which we will write in x86 assembly, and build up from there!
To interact with any level you can either run the challenges with an ELF as an argument (e.g., /challenge/run /path/to/your/elf
) or send raw bytes over stdin to this program. You can also use pwntools
:).