Required Tools

Task Tool Category
Writing and compiling Windows code IDE, compiler, SDK, build tools
Debugging binaries User-mode debugger, Windows debugger
Inspecting PE structure PE viewer, hex editor, static analysis tools
Observing runtime behavior Process, file, registry, memory, handle, and DLL inspection tools
Observing network behavior Packet capture and connection inspection tools
Comparing offensive and defensive views Payload generator, logs, telemetry, and monitoring utilities

Introduction to Windows C programming

Windows Headers

The most of Windows C samples include one or more Windows-specific header files. These headers provide the API declarations, constants, macros, structures, and data types needed to call Windows functions.

The main header is Windows.h, which includes many core Win32 API declarations, constants, macros, and data types.

Additional headers are included when a specific API family is needed. For example, the Tool Help API uses TlHelp32.h. This API family is commonly used to take snapshots of processes, threads, modules, and heaps on the system. For example:

#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>

Other common header files are Strsafe.h, Psapi.h, Winternl.h, and Bcrypt.h.

Windows Type Names and Naming Conventions

Windows code also uses many Windows-specific type names. These types are usually aliases over standard C/C++ types, but they make API prototypes easier to read in the Windows ecosystem. For example, instead of always writing unsigned long, void*, or wchar_t*, Windows code commonly uses names such as DWORD, PVOID, HANDLE, LPWSTR, and SIZE_T.

Readers should not memorize every Windows type at once. Instead, they should learn how to read the naming patterns and recognize the types that appear most often. The following are some common Windows data types used throughout Win32 programming. For the full list, refer to Microsoft's Windows Data Types page.

Type Meaning Common Use
BYTE 8-bit unsigned integer Raw bytes, buffers, shellcode bytes, binary data
WORD 16-bit unsigned integer Small numeric values, flags, PE fields
DWORD 32-bit unsigned integer Flags, process IDs, thread IDs, error codes, sizes
LONG 32-bit signed integer Signed values, status fields, structure members
ULONG 32-bit unsigned integer Unsigned values, counters, flags
BOOL Integer boolean value Win32 success/failure return values using TRUE or FALSE
BOOLEAN Byte-sized boolean value Lower-level Windows structures and NT-style code
CHAR 8-bit ANSI character ANSI strings and byte-sized character data
WCHAR 16-bit wide character Unicode UTF-16 strings used by Windows
LPSTR Pointer to a writable ANSI string ANSI string buffers
LPCSTR Pointer to a constant ANSI string Read-only ANSI strings
LPWSTR Pointer to a writable wide string Unicode string buffers
LPCWSTR Pointer to a constant wide string Read-only Unicode strings
PVOID Pointer to an unspecified type, similar to void* Generic memory addresses and buffers
LPVOID Pointer to an unspecified type, similar to void* Generic memory addresses and buffers
HANDLE Handle to a Windows object or resource Files, processes, threads, snapshots, events, mutexes
HMODULE Handle to a loaded module DLL and EXE module handles
SIZE_T Unsigned integer large enough to represent memory sizes Buffer sizes, allocation sizes, memory operations
DWORD_PTR Unsigned pointer-sized integer Storing integer values that must scale between x86 and x64
ULONG_PTR Unsigned pointer-sized integer Pointer arithmetic and pointer-sized values
UINT_PTR Unsigned pointer-sized integer Pointer-sized unsigned values

Examples of Windows Data Types

The following examples show how common Windows data types appear in real variable declarations and what each declaration represents: