EpochZero Learn
EpochZero LearnMulti-Domain Tech Learning Hub
Courses
LeaderboardAbout
Dashboard
EpochZero
EpochZero Learn
Multi-Domain Tech Learning Hub

Structured learning for Reverse Engineering, Cloud Security, Cryptography, and Web Development. Articles, videos, tests, and peer discussion.

Learn

  • Learning Path
  • All Articles
  • Video Lessons
  • Podcast
  • eBooks & PDFs
  • Question Banks
  • Cheatsheets
  • MCQ Banks

Tests & Forum

  • All Tests
  • REMA Tests
  • Cloud Tests
  • Forum
  • REMA Forum
  • Cloud Forum
  • Crypto Forum
  • Web Dev Forum

Campus

  • REMA Club
  • Full Stack Dev Club
  • Extension Activity
  • Events
  • CTF Competitions
  • Workshops
  • Industrial Visits

Platform

  • Dashboard
  • Leaderboard
  • About
  • Verify Certificate

© 2026 EpochZero Learn. Educational content for learning purposes.

Course Instructor: Ashish Revar

All articles
Educationmemory-layoutstackheap

Process Memory Layout

How Windows arranges a process in virtual memory — the stack, heap, PE sections, and kernel space — and why understanding this layout is essential for interpreting debugger output and recognising exploitation patterns.

Ashish Revar12 May 202615 min read2 views
Quick Bite

⚡ Quick Bite · 40s

Process Memory Layout: Malware Analysis Fundamentals

Stack, Heap, and PE Section mapping; tracking EBP and ESP for debugging; spotting PAGE_EXECUTE_READWRITE injection indicators in memory.

Watch this 40-second summary before diving into the full article. Sign in to earn 5 leaderboard points.

Virtual Memory Layout of a 32-bit Windows Process

When the Windows loader maps a PE file into memory, it arranges the sections into a virtual address space. Every 32-bit process gets a private 4 GB virtual address space, split between user mode (0x00000000–0x7FFFFFFF) and kernel mode (0x80000000–0xFFFFFFFF).

High address (0xFFFFFFFF)
┌─────────────────────────┐
│      Kernel Space        │  OS kernel — not accessible from user mode
├─────────────────────────┤  (0x80000000)
│         Stack            │  grows downward ↓
│                          │
│    (unallocated)         │
│                          │
│         Heap             │  grows upward ↑
├─────────────────────────┤
│    .bss / .data          │  Global variables
├─────────────────────────┤
│       .text              │  Executable code
├─────────────────────────┤
│      PE Headers          │
└─────────────────────────┘  (0x00400000 — typical ImageBase)
Low address

Refer to REMA eBook 2026, Figure 2.14 for the full virtual memory layout diagram with annotated address ranges.

The Stack

The stack is a LIFO (last-in, first-out) data structure managed automatically by the CPU.

  • Grows downward — from high addresses toward low addresses
  • PUSH decrements ESP by 4, then writes the value
  • POP reads the value, then increments ESP by 4
  • Stores: local variables, saved registers, return addresses, function arguments

Each function call creates a stack frame: a region of the stack holding the function's local variables, the saved EBP, and the return address. When the function returns, its frame is destroyed.

Stack frame layout (after prologue)

High address
┌─────────────────────────┐
│  Arg 2     [EBP+0x0C]   │  ← Passed by caller
│  Arg 1     [EBP+0x08]   │
│  Return Address [EBP+04]│  ← Where to resume after RET
│  Saved EBP [EBP+0x00]   │  ← EBP points here
│  Local var 1 [EBP-0x04] │  ← Current frame begins
│  Local var 2 [EBP-0x08] │
│  Buffer    [EBP-0x??]   │
└─────────────────────────┘  ← ESP points here
Low address

Why this matters for malware analysis

A buffer overflow on the stack writes past the buffer boundary upward — toward the saved EBP and then the return address. When RET executes, the CPU pops the corrupted value into EIP and jumps to attacker-controlled code.

Buffer at [EBP-0x40]
Overflow direction: low → high
Overwrites: local vars → saved EBP → return address

Recognising this layout in a debugger is the basis for understanding every stack exploitation technique.

The Heap

The heap is a pool of memory used for dynamic allocations requested at runtime.

  • Grows upward — from low addresses toward high addresses
  • malloc() / HeapAlloc() — requests heap memory
  • free() / HeapFree() — releases heap memory
  • VirtualAlloc() — large allocations with custom permissions

Malware and the heap

Malware frequently uses the heap to store unpacked payloads. If a binary calls VirtualAlloc with PAGE_EXECUTE_READWRITE, it is allocating a heap region where it can both write data and execute code — a strong indicator of runtime unpacking or shellcode injection.

push  PAGE_EXECUTE_READWRITE     ; flProtect = 0x40
push  MEM_COMMIT                 ; flAllocationType
push  payload_size               ; dwSize
push  0                          ; lpAddress (OS chooses)
call  VirtualAlloc               ; returns base address in EAX
; EAX now points to RWX memory — malware writes shellcode here

Stack vs Heap comparison

PropertyStackHeap
ManagementAutomatic (CPU adjusts ESP)Manual (programmer calls alloc/free)
Growth directionDownward (high → low)Upward (low → high)
LifetimeUntil function returnsUntil explicitly freed
SpeedFast (single SUB ESP)Slower (heap manager search)
Typical abuseBuffer overflow overwrites return addressHeap spray fills memory with shellcode

Loaded DLLs

In addition to the PE sections, a process's memory contains all loaded DLLs mapped into the same address space. In a debugger, the Modules panel (x64dbg: View → Modules) shows every DLL currently mapped.

Malware injected as a DLL appears here — but reflective DLL injection and some advanced techniques can hide from this list. The Volatility dlllist plugin (covered in Unit 5) detects discrepancies between the module list and actual memory mappings.

Interpreting Debugger Output

Understanding the memory layout transforms the register panel from noise into signal:

Register ValueMeaning
EIP in .text rangeNormal code execution
EIP in heap rangeShellcode executing from heap — likely injection
ESP decreasingStack growing — function calls happening
EBP stable across loopLoop executing within same frame
EAX = 0 after API callAPI returned failure — check GetLastError

When EIP points outside .text or any known module, the process is executing injected code. This is the most direct indicator of code injection visible in a debugger.

Sign in to mark this article as read and track your progress.

Related to this topic

Continue learning

Listen

Malware Blueprints in Portable Executable Headers

A deep dive into the Portable Executable (PE) structure used by Windows binaries — how analysts decode executable metadata to uncover malicious intent, compiler behaviour, packing indicators, and execution flow.

Reference material

eBook
REMA eBook 2026
v1.0
Open resource
Cheatsheet
REMA Cheatsheet 2026
v1.0
Open resource
MCQ Bank
REMA MCQ Bank 2026
v1.0
Open resource
Question Bank
REMA Question Bank 2026
v1.0
Open resource

External references

Process Hacker — Memory Map View

Free process monitor. Open any process → Memory tab to see the full virtual memory map with regions, permissions, and mapped files.

tool
x64dbg — Memory Map Panel

In x64dbg: View → Memory Map shows all allocated regions with permissions. RWX regions outside known modules are immediate red flags.

tool
More articlesTest your knowledge