pwncollege
DojosLeaderboardCommunity
Back to cse365-s2026

Module 4

cse365-s2026
0/108 challenges completed

In this fourth module we will take a look at the fundamentals of computing.

Questions and Discussions (Discord)

  • Chat about the content: Core Material > #computing-101
  • Create a forum post: Getting Started > #getting-started-forum

Your First Program

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.

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 letting 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.

Most of pwn.college's material uses the x86 CPU architecture, which is Zardus' favorite architecture. 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! Let's dig in, and write your first program!

1
LECTURE: Computer Architecture
2
LECTURE: Assembly
3
LECTURE: Registers
4
Your First Register
5
Your First Syscall
6
Exit Codes
7
Building Executables
8
Moving Between Registers

Computer Memory

Wow, you are a budding x86 assembly programmer! You've set registers, triggered system calls, and wrote your first program that cleanly exits. Now, we have one more big concept for you: memory.

You, as (presumably) a human being, have Short Term Memory and Long Term Memory. When performing specific computation, your brain loads information you've previously learned into your short term memory, then acts on that information, then eventually puts new resulting information into your long-term memory. Societally, we also invented other, longer-term forms of storage: oral histories, journals, books, and wikipedia. If there's not enough space in your long-term memory for some information, or the information is not important to commit to long-term memory, you can always go and look it up on wikipedia, have your brain stick it into long-term memory, and pull it into your short-term memory when you need it later.

This multi-level hierarchy of information access from "small but accessible" (your short term memory, which is right there when you need it but only stores 5 to 9 pieces of information to "large but slow" (remembering stuff from your massive long-term memory) to "massive but absolutely glacial" (looking stuff up on wikipedia) is actually the foundation of the Memory Hierarchy of modern computing. We've already learned about the "small but accessible" part of this in the previous module: those are registers, limited but FAST.

More spacious than even all the registers put together, but much much MUCH slower to access, is computer memory, and this is what we'll dig into with this module, giving you a glimpse into another level of the memory hierarchy.

9
LECTURE: Memory
10
Loading From Memory
11
More Loading Practice
12
Dereferencing Pointers
13
Dereferencing Yourself
14
Dereferencing with Offsets
15
Stored Addresses
16
Double Dereference

The Stack

So far, you've been reading from memory addresses that we set up for you. But your program already has a region of memory ready to go: the stack. The stack is pointed to by the rsp register, and it contains useful data about how your program was launched and accumulates other data as the program executes. Let's explore it!

17
The Stack
18
Stack Offsets
19
Program Arguments on the Stack
20
Popping From the Stack

Software Introspection

As you write larger and larger programs, you (yes, even you!) might make mistakes when implementing certain functionality, introducing bugs into your programs. When this happens, you'll need to have a reliable toolbox of resources to understand what is going wrong and fix it. Of course, the exact same techniques can be used to understand what is wrong with code that you didn't write, and fix or exploit it as you might desire!

This module will introduce you to several ways to introspect, debug, and understand software. You'll carry this critical knowledge with you and use it throughout pwn.college, so harken well!

21
LECTURE: Data
Bytes as Hex and Binary
22
Disassembling Programs
23
Tracing Syscalls
24
Starting GDB
25
Quitting GDB
26
Starting Programs in GDB
27
Disassembling in GDB
28
Stepping Through Instructions
29
Reading Register Values
30
Popping Stack Values
31
Examining Memory
32
Examining Stack Pointers
33
Cooperative Debugging

Output and Input

Until now, your program's single interaction with the wider world was changing its exit code when exiting. Of course, more interaction is possible!

In this module, we will learn about the write system call, which is used to write output to the command-line terminal! This is going to be an exciting journey: the logic of this program is going to be both as close as you can possibly get to the hardware itself (e.g., you are writing raw x86 assembly that the CPU directly understands!) and as close as you can possibly get to the Linux operating system (e.g., you are triggering system calls directly!).

34
LECTURE: System Calls
35
Writing Output
36
Chaining Syscalls
37
Writing Strings
38
Reading Data
39
Opening Files
40
Hardcoding the Filename

Control Flow

41
LECTURE: Control Flow
42
Comparing Values
43
Comparing Characters
44
Conditional Control Flow
45
Comparing Strings
46
Reverse the Password
47
Conditionals Without Conditionals
48
Looping

Assembly Assortment

You have a working knowledge of assembly from your journey thus far. Let's broaden it!

This module will explore the effects of a number of different assembly instructions, teaching you to recognize them and not panic in their presence. Generally, each challenge will force you to understand its effect on data and generate data that it will accept. If you can do this, you will get flags!

49
Reverse the Calculation
50
Reverse the Reverse
51
Dealing with Bitwise Operations
52
Loops on Data

Assembly Crash Course

Now that you have the hang of very basic assembly, let's dive in and explore a few different instructions and some additional concepts! The Assembly Crash Course is a romp through a lot of different things you can do in assembly, and will prepare you for the adventures to come!

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.

53
LECTURE: Building Programs
Tip - Debugging Your Assembly
Further Reading
54
set-register
55
set-multiple-registers
56
add-to-register
57
linear-equation-registers
58
integer-division
59
modulo-operation
60
set-upper-byte
61
efficient-modulo
62
byte-extraction
63
bitwise-and
64
check-even
65
memory-read
66
memory-write
67
memory-increment
68
byte-access
69
memory-size-access
70
little-endian-write
71
memory-sum
72
stack-subtraction
73
swap-stack-values
74
average-stack-values
75
absolute-jump
76
relative-jump
77
jump-trampoline
78
conditional-jump
79
indirect-jump
80
average-loop
81
count-non-zero
82
string-lower
83
most-common-byte

Debugging Refresher

A critical part of working with computing is understanding what goes wrong when something inevitably does. This module will build on your prior exposure to GDB with some more debugging of programs: digging in, poking around, and gaining knowledge. This is one of the most critical skills that you will learn in your computing journey, and this module will hopefully help water the seed that we planted before.

As you know, GDB is a very powerful dynamic analysis tool which you can use in order to understand the state of a program throughout its execution. You will become more familiar with some of its capabilities in this module.

84
LECTURE: GDB with Robert
GDB Help
85
Debugging Programs
86
Inspecting Registers
87
Examining Memory
88
Setting Breakpoints
89
GDB Scripting
90
Modifying Data
91
Modifying Execution
92
Broken Functions

Building a Web Server

Now that you know how to write and debug assembly, it is time to do something real! In this module, you will develop the skills needed to build a web server from scratch, starting with a simple program and progressing to handling multiple HTTP GET and POST requests. Good luck!


As you proceed in your journey, remember your system call table.

93
LECTURE: Introduction
94
LECTURE: Linux Processes
95
LECTURE: Network System Calls
96
LECTURE: HTTP Refresh
97
LECTURE: Multiprocessing
98
Exit
99
Socket
100
Bind
101
Listen
102
Accept
103
Static Response
104
Dynamic Response
105
Iterative GET Server
106
Concurrent GET Server
107
Concurrent POST Server
108
Web Server