| 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 |
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 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 |
The following examples show how common Windows data types appear in real variable declarations and what each declaration represents:
DWORD dwVariable = 42; - A 32-bit unsigned integer, on both 32-bit and 64-bit systems, used to represent values from 0 up to (2^32 - 1).SIZE_T cbVariable = sizeof(int); - Used to represent the size of an object. It's a 32-bit unsigned integer on 32-bit systems representing values from 0 up to (2^32 - 1). On the other hand, it's a 64-bit unsigned integer on 64-bit systems representing values from 0 up to (2^64 - 1).PVOID pVariable = &SomeData; - A 32-bit or 4-byte pointer of any data type on 32-bit systems. Alternatively, a 64-bit or 8-byte pointer of any data type on 64-bit systems.HANDLE hFile = CreateFile(...); - A value that specifies a particular object that the operating system is managing (e.g., file, process, thread).HMODULE hModule = GetModuleHandle(...); - A handle to a module. An HMODULE is a handle to a loaded module, such as a DLL or EXE image. In user-mode code, this value is commonly the base address at which the module is loaded into the process.