How to Read Disassembly in OllyDbg: A Beginner’s Guide

:high_voltage: OllyDbg Reverse Engineering Series — Part 2 of 60

This article continues the beginner foundation phase of the OllyDbg reverse engineering series.

# Title Link
Part 1 What is Reverse Engineering? Why OllyDbg? What is Reverse Engineering? And Why Am I Using OllyDbg?
Part 2 – You are here OllyDbg Interface Tour – Every Window Explained How to Read Disassembly in OllyDbg: A Beginner’s Guide
Part 3 Number Systems – Hex, Decimal, Binary with Real Examples Hex vs Binary vs Decimal: Explained for Programmers and Reverse Engineers
Part 4 CPU Registers – What They Are and Why They Matter CPU Registers Explained: What They Are and Why They Matter in Reverse Engineering
Part 5 Your First Look at Assembly – Reading Code Like a Reverser How to Read Assembly Code for Reverse Engineering

When I first opened OllyDbg, I had no idea what I was looking at. Four windows staring back at me, a bunch of hex numbers everywhere, some cryptic text like MOV EAX, 1 and PUSH EBP. I just sat there thinking okay, where do I even start?

That’s exactly what this part is about. I’m going to walk through every single window in OllyDbg what it shows, why it exists, and what you’re actually supposed to do with it. No skipping ahead, no assuming you already know things. We start from zero.

Also before anything else: run OllyDbg as Administrator. Right-click the icon → Run as administrator. Some programs won’t load without it and you’ll waste 20 minutes wondering why nothing works. I learned this the hard way.


Step 1: Loading a Program — What Actually Happens

Go to File → Open → pick any .exe. Something simple like notepad.exe works fine for learning.

The moment it loads, OllyDbg freezes the program. Nothing has executed yet. Not even one instruction.

Think of it like a race. The runner (your program) is at the starting line. The gun hasn’t fired. Everything is ready the runner is in position, shoes tied, muscles tensed but nothing has moved. The race hasn’t started.

That frozen starting point has a name: the entry point. It’s the memory address where the CPU would execute the very first instruction if you let the program run.

So right now: program is loaded, frozen at the entry point, completely paused. You’re in full control. That’s the whole point of a debugger.


The Four Windows — A Quick Map Before We Dive In

OllyDbg has four main windows arranged like this:

+---------------------------+------------------+
|                           |                  |
|   DISASSEMBLER            |   REGISTERS      |
|   (top-left)              |   (top-right)    |
|                           |                  |
+---------------------------+------------------+
|                           |                  |
|   MEMORY DUMP             |   STACK          |
|   (bottom-left)           |   (bottom-right) |
|                           |                  |
+---------------------------+------------------+
|  COMMAND BAR                                 |
+----------------------------------------------+

Each window shows a different view of the same running program. Let me go through them one by one.


The Disassembler Window (Top-Left) - The Map of the Program

This is the biggest window. You’ll spend most of your time here.

What it does: it takes the raw machine code bytes of the program and converts them into assembly language so you can actually read what the CPU is going to do. That process - converting machine code into assembly is called disassembly. Hence the name.

It has four columns:

Address  | Hex Bytes    | Assembly Instruction | Comments
00401000 | 55           | PUSH EBP             |
00401001 | 8B EC        | MOV EBP, ESP         |
00401003 | 83 EC 10     | SUB ESP, 10          |
  • Address - where in memory this instruction lives (a hex number like 00401000)
  • Hex Bytes - the raw bytes the CPU actually sees
  • Assembly Instruction - the human-readable translation of those bytes
  • Comments - OllyDbg’s own notes, or ones you add yourself

Think of this window as Google Maps for the program. The actual roads and buildings are the raw bytes in memory. The Disassembler window is the map it shows you where everything is, how the code flows, where the turns and jumps are.

You can click any line, set a breakpoint (more on that below), follow function calls everything starts here.


The Registers Window (Top-Right) - The CPU’s Working Notes

When you’re doing math on paper, you write intermediate values somewhere “hold this 5 here while I calculate something else.” The CPU does the same thing, except instead of paper, it uses registers tiny, ultra-fast storage slots built directly inside the processor.

The Registers window shows you all of them in real time. As you step through code, you watch these values change live.

The main ones:

EAX = 00000001   ← general purpose - holds values, results
EBX = 00000000   ← general purpose
ECX = 00000007   ← general purpose (often used as a counter)
EDX = 00000000   ← general purpose

ESP = 0061FF80   ← top of the stack right now
EBP = 0061FF88   ← base of the current stack frame

EIP = 00401000   ← THE MOST IMPORTANT ONE

EIP is the one to watch. Whatever address is in EIP that’s the next instruction the CPU will execute. OllyDbg follows EIP as you step through code. When you see the program jumping around, that’s EIP changing.

There are also flags single bits (C, Z, S, P, etc.) that say yes/no about the last operation. Like: “was the result zero?” or “did that subtraction go negative?” These matter a lot when code is making decisions. We’ll get deeper into flags in a later part.


The Memory Dump Window (Bottom-Left) X-Ray of RAM

Here’s something important I realized while learning this: when OllyDbg loads a .exe, the program is actually loaded into real memory (RAM). It’s a live process frozen, but live. That’s why everything you see in OllyDbg is real real addresses, real values, real data.

Ghidra is different. Ghidra just reads the file from disk and never runs it. So with Ghidra you get the code structure, but there are no real registers, no live values just a static picture. OllyDbg is walking inside the building. Ghidra is reading the blueprint.

The Memory Dump window is the rawest view of that live memory. It shows you bytes at any address in three columns:

Address  | Hex Bytes                         | ASCII
0061FF70 | 48 65 6C 6C 6F 20 57 6F 72 6C 64  | Hello World

The ASCII column on the right is where things get interesting. If the program has a string sitting in memory a password, a URL, an error message you’ll see it there as readable text. The hex bytes and ASCII are showing the same data, just in two different formats.

This is the window malware analysts use to find hidden strings, hardcoded keys, and data the program is quietly working with.


The Stack Window (Bottom-Right) - The Return Address Book

Think of a stack of plates. You put a plate on top, you take one from the top. Last in, first out. That’s exactly how the CPU stack works.

The Stack window shows what’s currently on that stack. Two columns:

Address  | Value
0061FF80 | 00401250   ← return address
0061FF84 | 00000005   ← some value pushed earlier

The most important thing stored on the stack is return addresses. Here’s what that means:

Let’s say you have a function at address 123. Inside that function, it calls another function at 234. Before jumping to 234, the CPU pushes 123 onto the stack it’s saying “remember, we came from here.” When function 234 finishes, it pops that address back and jumps to 123. The program knows exactly where to return.

The ESP register (which you saw in the Registers window) always points to the top of the stack. One more thing: the stack grows downward in memory higher addresses at the bottom, lower addresses at the top. It’s confusing at first. Just accept it for now, it’ll make more sense as you use it.


The Command Bar - Quick Calculator Inside OllyDbg

At the very bottom of OllyDbg there’s a small input bar. This is the command bar.

It’s basically a mini calculator that lives inside the debugger. While you’re reversing and you see a hex value like 2B3F1A and want to know what that is in decimal you just type ? 2B3F1A and get the answer right there without leaving OllyDbg.

You might wonder: the Memory Dump window already shows ASCII, so why do you need the command bar for conversions? Fair question. The Memory Dump shows ASCII for whatever is in memory. The command bar is for on-the-spot math and lookups while you’re analyzing code in the Disassembler for values that appear in instructions, not in memory.

It’s a small feature but you’ll use it constantly once you’re actually reversing.


Breakpoints - The Most Important Concept in Debugging

A program might have millions of instructions. You can’t step through all of them. You need to say: “pause exactly HERE.”

That’s a breakpoint.

It’s like bookmarking page 347 in a 500-page book. Instead of reading every page to get there, you flip straight to 347 and start reading from there.

How to use it in OllyDbg:

  1. Click any line in the Disassembler window
  2. Press F2 - the line turns red. Breakpoint is set.
  3. Press F9 - the program runs at full speed
  4. When it hits that red line it freezes. You’re now exactly where you wanted to be.

Press F2 again on the same line to remove the breakpoint.

This is how malware analysts say “I want to pause exactly when this program tries to make a network connection” they find that instruction, hit F2, hit F9, and land right there.


Stepping Through Code - Three Keys You’ll Use 90% of the Time

You’ve hit your breakpoint. The program is frozen exactly where you want. Now what? You want to go one instruction at a time and watch what happens.

Three keys:

F8 - Step Over

Executes the current instruction and moves to the next one. If the current instruction is a CALL (a function call) F8 runs that entire function internally and brings you back to the line after the call. You never go inside the function. It just happens silently.

F7 - Step Into

Same as F8 for normal instructions. But if the current instruction is a CALL F7 takes you inside the function. You follow it in and step through it line by line.

F9 - Run

Runs at full speed until the next breakpoint (or the program ends).

The simplest way I think about it:

CALL to some function is like a tunnel in the road.

F8 = you drive through the tunnel normally, come out the other side
F7 = you stop and walk through the tunnel slowly, looking at every brick
F9 = you put your foot down and drive until the next red light (breakpoint)

Both F7 and F8 move one instruction at a time. The difference only matters when you hit a CALL. F8 goes over it, F7 goes into it.


What I Found Confusing (And Now Don’t)

“Why do I need the command bar if Memory Dump already shows ASCII?”
Memory Dump shows ASCII for data in memory. Command bar is for converting values you see in the Disassembler like immediate values in instructions. Different use case.

“Is OllyDbg actually running the program?”
Yes and no. When you load a .exe, it’s loaded into actual RAM as a live process but it’s frozen. It only executes when you press F8, F7, or F9. It’s a real running process that you’re holding on pause.

“What’s the difference between OllyDbg and Ghidra again?”
Ghidra reads the file from disk static, no execution. OllyDbg loads the program into memory and runs it under your control dynamic, live. Both are useful for different things.


What We Learned Glossary

Term What It Means
Entry Point The memory address where a program’s first instruction lives — where OllyDbg freezes it on load
Disassembler Window The main window shows machine code converted to readable assembly, with 4 columns
Registers Window Shows CPU registers (EAX, EBX, EIP, ESP etc.) and their live values
EIP Instruction Pointer the register that tells the CPU which instruction to execute next
Memory Dump Window Raw view of RAM shows bytes as hex and ASCII side by side
Stack Window Shows the current stack mostly return addresses and local variables
ESP Stack Pointer always points to the top of the stack
Command Bar Input bar at the bottom of OllyDbg for quick hex/decimal/ASCII conversions
Breakpoint A marker on a specific instruction that tells OllyDbg to pause when execution reaches it
F2 Set or remove a breakpoint on the selected line
F7 (Step Into) Execute one instruction follow into function calls
F8 (Step Over) Execute one instruction skip over function calls
F9 (Run) Run at full speed until the next breakpoint

Coming Up Next

In Part 3, we’re going to tackle number systems hex, decimal, and binary. You’re seeing hex everywhere in OllyDbg right now and probably just accepting it without fully understanding it. Part 3 fixes that.

→ Part 3: Number Systems - Hex, Decimal, Binary with Real Examples

← Part 1: What is Reverse Engineering? And Why Am I Using OllyDbg?