pwncollege
DojosLeaderboardCommunity
Back to cse365-f2025

Module 4

cse365-f2025
0/83 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: Data
4
LECTURE: Registers
5
LECTURE: Memory
6
LECTURE: Control Flow
7
LECTURE: System Calls
8
LECTURE: Building Programs
9
Your First Register
10
Your First Syscall
11
Exit Codes
12
Building Executables
13
Moving Between Registers

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!

14
Tracing Syscalls
15
Starting GDB
16
Starting Programs in GDB

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.

17
Loading From Memory
18
More Loading Practice
19
Dereferencing Pointers
20
Dereferencing Yourself
21
Dereferencing with Offsets
22
Stored Addresses
23
Double Dereference
24
Triple Dereference

Hello Hackers

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!).

25
Writing Output
26
Chaining Syscalls
27
Writing Strings
28
Reading 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.

29
set-register
30
set-multiple-registers
31
add-to-register
32
linear-equation-registers
33
integer-division
34
modulo-operation
35
set-upper-byte
36
efficient-modulo
37
byte-extraction
38
bitwise-and
39
check-even
40
memory-read
41
memory-write
42
memory-increment
43
byte-access
44
memory-size-access
45
little-endian-write
46
memory-sum
47
stack-subtraction
48
swap-stack-values
49
average-stack-values
50
absolute-jump
51
relative-jump
52
jump-trampoline
53
conditional-jump
54
indirect-jump
55
average-loop
56
count-non-zero
57
string-lower
58
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.

59
LECTURE: GDB with Robert
60
Debugging Programs
61
Inspecting Registers
62
Examining Memory
63
Setting Breakpoints
64
GDB Scripting
65
Modifying Data
66
Modifying Execution
67
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.

68
LECTURE: Introduction
69
LECTURE: Linux Processes
70
LECTURE: Network System Calls
71
LECTURE: HTTP Refresh
72
LECTURE: Multiprocessing
73
Exit
74
Socket
75
Bind
76
Listen
77
Accept
78
Static Response
79
Dynamic Response
80
Iterative GET Server
81
Concurrent GET Server
82
Concurrent POST Server
83
Web Server