Skip to main content

0803 | Windows Internals

Malware Analysis | Windows Internals | Summary:

This room aims to provide an in-depth exploration of Windows operating system internals and common components. Important concepts like Processes, Threads, Virtual Memory, DLLs, PE and the Window API are introduced.


Disclaimer: Please note that this write-up is NOT intended to replace the original room or its content, but rather serve as supplementary material for those who are stuck and need additional guidance.

Learning Objectives

  • Understand and interact with Windows processes and their underlying technologies.
  • Learn about core file formats and how they are used.
  • Interact with Windows internals and understand how the Windows kernel operates.

1 | Introduction

The main focus is on empowering red teams (cybersecurity professionals who simulate attacks) to understand and exploit Windows internals for various purposes, such as evasion and exploitation when crafting offensive tools or exploits. This knowledge is crucial in a corporate setting where Windows machines are prevalent.

2 | Processes

  • A process in Windows refers to the execution of an application, which can contain one or more processes.
  • A process has various components, including
    • a (private) virtual address space,
    • executable code | program
    • open handles to system objects
    • a security context
    • a unique process identifier | process ID
    • environment variables
    • a priority class
    • minimum and maximum working set sizes
    • at least one thread of execution
  • Processes are created when an application runs and are essential for Windows functionality

Attackers can target processes to evade detection and hide malware by using techniques such as Process Injection, Hollowing, or Masquerading.

A process also has lower-level components that reside in the virtual address space

  • code | global variables | heap memory (process heap) | resources (open files | heaps) | environment block | it's threads

These components can be observed in detail using utilities like Process Hacker 2, Process Explorer, or Procmon, which display essential process details such as name, PID, status, user name, and more.

Overall, processes are a fundamental concept in Windows that play a crucial role in the operating system's functionality and security.

3 | Threads

  • a Thread is an executable unit within a process that is scheduled based on device factors such as CPU and memory specifications, priority, and logical factors
  • are essentially "controllers" of process execution
  • Characteristics shared with the parent process
    • code | global variables | resources
  • Unique values and data specific to each thread
    • Stack | stores data relevant to the thread (exceptions, procedure calls...) -Thread Local Storage | allocates storage for a unique data environment
    • Stack Argument | a unique value assigned to each thread
    • Context Structure | holds machine register values maintained by the kernel

Threads are a critical component of processes and can be targeted by attackers for malicious purposes, such as code execution or chaining with other API calls.

4 | Virtual Memory

It allows different processes to use memory as if it were physical memory without the risk of collisions or conflicts between applications.

Each process has its own private virtual address space, which is managed by the memory manager. The memory manager translates virtual addresses to physical addresses and can transfer or page virtual memory to the disk when an application uses more virtual memory than physical memory allocated.

On a 32-bit x86 system, the maximum virtual address space is 4 GB, with (lower | 0x00000000 - 0x7FFFFFFF) half allocated to processes and the other (upper | 0x80000000 - 0xFFFFFFFF) half to OS memory utilization. On a 64-bit modern system, the maximum virtual address space is 256 TB, with a similar allocation layout.

  • are libraries that contain code and data used by multiple programs at the same time
  • they promote modularization, code reuse, efficient memory usage, and reduced disk space, making Windows applications load faster, run faster, and take less disk space.
  • can be targeted by attackers to control aspects of execution or functionality
    • DLL Hijacking (T1574.001)
    • DLL Side-Loading (T1574.002)
    • DLL Injection (T1055.001)
  • DLLs are created like any other project/application, requiring slight syntax modification
  • can be loaded into an application using either load-time dynamic linking or run-time dynamic linking.
    • Load-time dynamic linking | involves explicit calls to the DLL functions from the application, which requires providing a header file and import library
    • Run-time dynamic linking | involves loading the DLL at run time using LoadLibrary or LoadLibraryEx, and then using GetProcAddress to identify and call the exported DLL function
  • Malicious code often uses run-time dynamic linking because it allows for easier transfer of files between memory regions

6 | Portable Executable Format

  • The PE (Portable Executable) format defines
    • the information about the executable and stored data
    • the structure of how data components are stored

PE data components:

  • DOS Header | defines the type of file (MZ --> .exe)
  • DOS Stub | a program run by default at the beginning of a file that prints a compatibility message ("This program cannot be run in DOS mode")
  • PE File Header | defines the format of the file, contains the signature and image file header, and other information headers
    • Image Optional Header | part of PE File Header
      • Data Dictionaries | point to the image data directory structure
  • Section Table | defines the available sections and information in the image

Sections

  • .text (executable code and entry point) | Contains the machine code that will be executed by the CPU
  • .data (initialized data) | Stores initialized variables and strings used by the program
  • .rdata or .idata (imports and DLLs) | Lists the Windows API functions and DLLs imported by the executable
  • .reloc (relocation information) | Provides information about addresses that need to be adjusted when relocating the executable in memory
  • .rsrc (application resources) | Contains application-specific data, such as images, icons, and other resources
  • .debug (debug information) | Stores debugging information used by debuggers
note

The following image (Portable Executable FILE Format) is part of a comprehensive guide named A Comprehensive Guide To PE Structure, The Layman’s Way and belongs to them.

7 | Interacting with Windows Internals

Interacting with Windows Internals

  • can be simplified using Windows API calls
  • the Windows API provides native functionality to interact with the operating system

User Mode and Kernel Mode

info

Quote: "Most Windows internals components require interacting with physical hardware and memory...An application by default normally cannot interact with the kernel or modify physical hardware and requires an interface. This problem is solved through the use of processor modes and access levels...The processor will switch between these modes depending on access and requested mode."

  • Windows processors have two modes
    • user mode (also known as "userland")
      • No direct hardware access
      • Creates a process in a private virtual addresss space
      • Access ONLY to "owned memory locations"
    • kernel mode
      • Direct hardware access
      • Ran in a single shared virtual address space
      • Access to the ENTIRE physical memory
  • System calls or API calls are used to switch between these modes ("Switching Point")

Writing to Memory | Inject arbitrary code into local process

  • Step-1 | Allocate local process memory for our code | OpenProcess for the process handle and VirtualAllocEx to allocate memory
  • Step-2 | Write/copy our code to allocated memory | WriteProcessMemory to write the payload
  • Step-3 | Execute our code from local process memory | CreateRemoteThread to execute the payload from memory