sinbeard's Trove of Disassembly and Tinkering

Knowing is not enough; we must apply. Willing is not enough; we must do.

16 January 2021

windows systems programming week 1

by canderson

Primarily as a result of Flare-On and learning game hacking techniques, I’ve been more interested in learning Windows things lately. As a result, I’ve picked up a couple books - Windows Kernel Programming, and Windows System Programming, both by Pavel Yosifovich. They are really clearly written and provide excellent on modern Windows programming I also grabbed a quick class on System Programming. These pages will serve as my notes and a general reference.

Foundations

Process

Is a set of resources used to execute a program. It consists of the following:

Virtual Memory

Each process thinks it has a chunk of flat linear memory. Virtual memory may map to physical memory or be stored on disk. It is managed in chunks called Pages, which on Windows has a default size of 4 kb. Processes access memory regardless of where the memory resides. The memory manager handles mapping of virtual to physical pages, and they can’t (and need not) know the actual physical address of a given address in virtual memory.

32-bit processes have a 2 gb address space for the user, from 0 to 0x7fffffff. System space is from 0x80000000 to 0xffffffff. Kernel code all shares one large memory space.

64-bit has a 128 tb user address space. Same size for system space. 64-bit has an address space of… a lot, so most of the address space is unmapped.

Windows 8 and earlier (x64) support 8 tb user/kernel space.

Threads

An entity that is scheduled by the kernel to execute code. A thread maintains:

User vs Kernel Mode

Windows Subsystem APIs

Application Development Basics

Visual Studio is the most efficient tool for building System applications on Windows.

The Sysinternals (TODO: Add link) tools are incredibly useful for tinkering with applications.

Coding Conventions

Coding is done primarily using C, and some C++ is used where it makes sense to use it. Windows API functions can be prefixed with a :: to indicate global scope. It makes it easier to spot Windows API calls. Further, applications should compile successfully in 32 and 64 bit. Can also build and test in Debug and Release.

Hello World Example

From the Windows System Programming Fundamentals slides for Module 2

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

int main() 
{
    SYSTEM_INFO si;
    ::GetNativeSystemInfo(&si);
    printf("Number of Logical Processors: %u\n", si.dwNumberOfProcessors);
    printf("Page size: %u Bytes\n", si.dwPageSize);
    printf("Processor Mask: 0x%zX\n", si.dwActiveProcessorMask);
    printf("Minimum process address: 0x%p\n", si.lpMinimumApplicationAddress);
    printf("Maximum process address: 0x%p\n", si.lpMaximumApplicationAddress);
    return 0;
}

Handling Errors

Many Windows API functions return a boolean (BOOL type) to indicate success or failure. Typically, FALSE (0) indicates and error, and any other value indicates a success.


Appendix

Show Error Code

From Windows System Programming book

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("Usage: ShowError <number>\n");
        return 0;
    }

    int message = atoi(argv[1]);

    LPWSTR text;
    DWORD chars = ::FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | // FormatMessage allocates the buffer
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr, message, 0,
        (LPWSTR)&text,
        0, nullptr);

	if(chars > 0)
	{
        printf("Message %d: %ws\n", message, text);
        ::LocalFree(text);
	}
    else
    {
        printf("No such error exists!\n");
    }
    return 0;
}
tags: