# Windows API: A Reverse Engineer's Guide >[!Security] >This information is for educational purposes only. Always analyse malware in a secure, isolated environment like the one we built in our [[Azure Malware Lab Design]] series. Ever stared at a piece of malware in your disassembler and thought, "What on earth is this thing actually doing?" Well, you're not alone! When it comes to Windows malware, almost all the interesting stuff - the sneaky file operations, the process injections, the network communications - happens through the Windows API. It's like the Swiss Army knife of Windows programming, but in malware analysis, it's more like the crime scene investigator's toolkit. I remember my first time trying to understand API calls in a malware sample - it was like trying to read a book where every third word was in a different language. But here's the thing: once you understand the patterns and what to look for, these API calls tell you exactly what the malware is up to. It's like having the malware's playbook right in front of you. In this guide, we're going to crack open the world of Windows APIs from a reverse engineer's perspective. We'll look at everything from the basics to the clever tricks malware authors use to hide their API calls. Whether you're just starting out or you're looking to level up your analysis skills, we've got you covered. ## Core Concepts Right, let's start with the fundamentals. Think of the Windows API as the instruction set that programs use to ask Windows to do things for them. Want to create a file? There's an API for that. Want to inject code into another process? Yep, there's an API for that too (though we might want to be a bit careful with that one!). The Windows API (formerly Win32 API) serves as the primary interface between applications and the Windows operating system. When reverse engineering, you'll encounter these APIs in various forms: ### Understanding Protection Rings Before we dive deeper into User-Mode vs. Kernel-Mode APIs, let's talk about protection rings - think of them as security clearance levels in your favourite spy movie. Windows uses these rings to control what different parts of the system can do: - **Ring 0** (Kernel Mode): This is where the cool kids like the kernel and device drivers hang out. They've got full access to everything - hardware, memory, you name it. It's like having an all-access backstage pass. - **Ring 1 & 2**: These exist in theory, but Windows doesn't really use them. Consider them the VIP section that never got opened. - **Ring 3** (User Mode): This is where you and your applications live most of the time. It's the least privileged level, which is actually a good thing - it helps keep your system safe when applications misbehave. >🔍 **Real-World Context**: When you're browsing the web or writing a document, you're operating in Ring 3. If you need to do something that requires higher privileges (like installing a program), Windows temporarily elevates specific operations through controlled channels. ### User-Mode vs. Kernel-Mode APIs Let's talk about the two main types of APIs you'll encounter. It's a bit like the difference between talking to a restaurant manager (user-mode) versus walking straight into the kitchen and cooking the food yourself (kernel-mode). - **User-Mode APIs**: These are your friendly neighbourhood APIs, the ones you'll find in DLLs like `kernel32.dll`, `user32.dll`, and `advapi32.dll`. They operate in Ring 3 and have to ask permission from kernel-mode components when they need to do anything privileged. It's like having to go through security to access restricted areas. ```cpp // Common user-mode API call seen in malware HANDLE CreateFileA( LPCSTR lpFileName, // File name DWORD dwDesiredAccess, // Access mode DWORD dwShareMode, // Share mode LPSECURITY_ATTRIBUTES lpSecAttr, // Security attributes DWORD dwCreationDisposition, // How to create DWORD dwFlagsAndAttributes, // File attributes HANDLE hTemplateFile // Template file handle ); ``` - **Kernel-Mode APIs**: Lower-level functions that interact directly with the operating system ```cpp // Kernel-mode equivalent (simplified) NTSTATUS NtCreateFile( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, // ... additional parameters ); ``` ### API Resolution Techniques When analysing malware, you'll often see different methods of API resolution: 1. **Static Linking**: The most straightforward method ```cpp // Visible in PE imports LoadLibraryA("kernel32.dll"); GetProcAddress(hModule, "CreateFileA"); ``` 2. **Dynamic Resolution**: Often used to evade detection ```cpp // Common obfuscated resolution technique typedef HANDLE (WINAPI *pCreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); pCreateFileA MyCreateFile = (pCreateFileA)GetProcAddress( GetModuleHandleA("kernel32.dll"), "CreateFileA" ); ``` 3. **API Hashing**: A more sophisticated evasion technique ```cpp // Example of API hashing (commonly seen in shellcode) DWORD HashAPI(LPCSTR apiName) { DWORD hash = 0; while (*apiName) { hash = ROTR32(hash, 13); hash += *apiName; apiName++; } return hash; } ``` ## Common API Patterns in Malware Here's where things get interesting. Malware authors often use specific API combinations to achieve their goals. Let's look at some common patterns: ### Process Injection ```cpp // Classic DLL injection pattern OpenProcess() // Get handle to target process VirtualAllocEx() // Allocate memory in target WriteProcessMemory() // Write DLL path CreateRemoteThread() // Execute LoadLibrary in target ``` >[!tip] When you see this sequence in a disassembler, it's a strong indicator of DLL injection attempts. ### File Operations Malware often needs to interact with the filesystem. Here are common patterns: ```cpp // File creation and writing HANDLE hFile = CreateFileA("malware.bin", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hFile, buffer, size, &bytesWritten, NULL); // File searching WIN32_FIND_DATA findData; HANDLE hFind = FindFirstFileA("*.doc", &findData); ``` >[!tip] Look for file operations that might indicate dropping additional payloads or searching for valuable data. ### Registry Operations Registry manipulation is common in malware for persistence and configuration: ```cpp // Common registry persistence technique HKEY hKey; RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey); RegSetValueExA(hKey, "Malware", 0, REG_SZ, (BYTE*)"C:\\malware.exe", strlen("C:\\malware.exe") + 1); ``` ### Network Communication Malware often uses networking APIs for command and control (C2): ```cpp // Basic socket creation SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(sock, (struct sockaddr*)&addr, sizeof(addr)); // WinHTTP API usage (common in modern malware) HINTERNET hSession = WinHttpOpen(L"User Agent", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); ``` ## Advanced Techniques and Anti-Analysis ### API Hooking Malware might hook APIs to intercept calls: ```cpp // Basic API hook example BOOL InstallHook(LPCSTR module, LPCSTR func, PVOID hook) { PVOID original = GetProcAddress(GetModuleHandleA(module), func); // Install detour... return TRUE; } ``` ### Anti-Debug Techniques Common anti-debugging API calls: ```cpp // Basic anti-debug checks IsDebuggerPresent(); CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebugged); // More sophisticated timing-based detection LARGE_INTEGER freq, start, end; QueryPerformanceCounter(&start); __debugbreak(); // Time this instruction QueryPerformanceCounter(&end); ``` ## Resources and Analysis Tools When you're diving into Windows API analysis, having the right resources at your fingertips can make all the difference. Here's something brilliant that you'll want to bookmark right away: ### MalAPI.io - Your Windows API Detective Think of https://malapi.io as the MITRE ATT&CK Framework meets GTFOBins, but specifically for Windows APIs. It's an absolute goldmine for malware analysts and reverse engineers. Here's why it's so valuable: - Maps APIs to malicious usage patterns - Shows you real-world malware samples that use each API - Provides detailed documentation and usage examples - Links APIs to specific MITRE ATT&CK techniques For example, if you're analysing a sample and spot a suspicious *VirtualAllocEx* call, you can hop over to malapi.io and see: - Exactly how malware authors typically abuse this API - Which malware families are known to use it - What legitimate uses look like versus suspicious patterns - Related APIs you should be watching for >[!tip] >When you're analysing a new piece of malware, keep malapi.io open in another window. As you spot API calls, quickly cross-reference them to see if they match known malicious patterns. ### Other Essential Resources 1. **Process Monitor (ProcMon)** - Real-time file system, Registry, and process/thread activity - Filter by process, operation, or result 2. **API Monitor** - Detailed API call tracking - Support for both 32-bit and 64-bit processes ### Debugging Tools 1. **WinDbg** ```shell bp kernel32!CreateFileA "dt _UNICODE_STRING @rdx" ``` 2. **x64dbg** - Set breakpoints on API calls - Analyse arguments and return values ## Common Analysis Patterns When reverse engineering, look for these patterns: ### Process Creation and Manipulation ```cpp // Common sequence for process hollowing CreateProcessA(target, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); NtUnmapViewOfSection(pi.hProcess, imageBase); VirtualAllocEx(pi.hProcess, imageBase, imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); WriteProcessMemory(pi.hProcess, imageBase, newImage, imageSize, NULL); SetThreadContext(pi.hThread, &ctx); ResumeThread(pi.hThread); ``` ### Memory Operations ```cpp // Common sequence for reflective loading VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Parse PE headers // Perform relocations // Resolve imports // Execute entry point ``` ## Best Practices for Analysis When you're analysing potential malware, keep these tips in mind: 1. **Start Broad, Go Deep** - First, look for known patterns - Then analyse unusual API combinations - Finally, dive into the details of each call 2. **Context is King** - Don't just look at individual APIs - Watch for patterns and sequences - Consider the bigger picture 3. **Document Everything** - Record all API patterns you find - Note variations from known patterns - Share findings with the community ## Malware Family Patterns Speaking of malicious behavior, one of the most fascinating aspects of Windows API analysis is how different malware families leave their own unique "fingerprints" through their API usage patterns. While we cover the basics of API usage here, we've got a whole separate deep dive into how specific malware families use these APIs in [[Windows API Malware Patterns]]. It's pretty eye-opening to see how different families have their own favourite APIs and techniques! ## Conclusion Understanding the Windows API is crucial for effective malware analysis. By recognising common patterns and techniques, you can quickly identify malicious behaviour and understand how malware operates. Keep this guide handy during your analysis sessions, and remember: malware authors are constantly evolving their techniques, so keep learning and adapting your analysis approaches.