Sitemap

Day 32: Threads

3 min readJun 26, 2025

--

They are different from processes guys

Press enter or click to view image in full size
Photo by Steve Johnson on Unsplash

Howdy Nerds! Now that you understand what processes are, let’s talk about threads. Threads are way smaller units of execution that live inside processes. If a process is a running program, then a thread is a specific task or job within that program.

The major difference between processes and threads is how they use memory and other resources. Remember how each process has its own isolated memory space that other processes can’t access? Threads are different. All threads within the same process share the same memory space, the same open files, and the same resources. This sharing makes threads much more lightweight than processes. Creating a new process requires the operating system to set up a completely new memory space, copy file handles, and allocate new resources where whereas creating a new thread is much faster because it just needs a small stack and some register space. However, this sharing also means that if one thread crashes or corrupts memory, it may potentially bring down all the other threads in the same process.

Get Nile Okomo’s stories in your inbox

Join Medium for free to get updates from this writer.

Here’s what the basic structure may look like in code:

struct process {
int pid; // Process ID
char *memory_space; // Shared by all threads in this process
struct file *open_files; // Shared by all threads
struct thread *thread_list; // List of threads in this process
};

struct thread {
int thread_id; // Unique thread identifier
struct registers context; // Thread's own CPU registers
char *stack_pointer; // Thread's own stack
// Everything else is shared with other threads in the process
};

When the operating system switches between threads, something similar to switching between processes happens, but much faster. It saves the current thread’s registers and loads the next thread’s registers. But since threads share memory space, there’s no need to switch memory contexts, which is intrinsically an expensive operation.

Real applications use threads all the time. For instance, your web browser might have one thread handling the user interface, another thread downloading files in the background, and yet another thread rendering web pages. A video game might have one thread for graphics, one for physics calculations, one for artificial intelligence, and one for handling network communication. All these threads can access the same game data in memory, but each focuses on a different aspect of the program. Some applications choose to use multiple processes instead of multiple threads for security reasons. Google Chrome, for example, often runs each tab as a separate process. If a malicious website were to crash one tab, it won’t bring down your entire browser. The trade-off is that processes use more memory and are slower to create, but they provide better isolation.

When you’re analyzing a target application, knowing whether it uses multiple threads or separate processes changes your attack approach. If your target uses multiple threads within a single process, compromising one thread gives you access to the entire process’s memory space. This means that you can potentially read sensitive data like authentication tokens, encryption keys, user passwords, or session cookies, from other threads. Thread-based applications present both opportunities and challenges for exploitation. On one hand, once you gain code execution in any thread, you have access to all the shared memory. Buffer overflow exploits in multi-threaded applications are a good example because they let you access data that other threads are processing. Some vulnerabilities only appear under specific threading conditions, like race conditions where two threads access the same memory simultaneously in an unsafe way. On the other hand, multi-threaded applications often have more complex memory layouts and synchronization mechanisms that may make exploitation more unpredictable.

Modern exploit mitigation techniques also behave differently depending on whether you’re dealing with threads or processes. Address Space Layout Randomization (ASLR) randomizes memory layouts at the process level, so all threads in a process share the same randomized layout. Data Execution Prevention (DEP) and other memory protection mechanisms work at the process level too. Understanding this helps you craft exploits that work reliably across different threading scenarios and explains why certain attack techniques succeed or fail in specific software architectures.

That’s all Nerds!! Hack responsibly and see you tomorrow!!! Get outta here!!!

--

--

Nile Okomo
Nile Okomo

Written by Nile Okomo

Software Engineer | Data Scientist | Ethical Hacker | Book worm | Writer | Chess enthusiast | Musician