PE Binary Analysis (Windows)
Analyze Windows Portable Executable (PE) binaries for CTF reversing challenges.
PE Binary Analysis (Windows)
PE (Portable Executable) is the binary format used by Windows executables (.exe), DLLs (.dll), and drivers (.sys). CTF reversing challenges increasingly include Windows binaries. The approach is similar to ELF analysis, but with different tools and conventions.
PE Structure
Magic bytes: 4D 5A (MZ) at offset 0.
PE vs ELF: Key Differences
| Feature | PE (Windows) | ELF (Linux) |
|---|---|---|
| Magic | MZ at offset 0 | \x7fELF at offset 0 |
| Sections | .text, .rdata, .data, .rsrc | .text, .rodata, .data, .plt, .got |
| Imports | Import Address Table (IAT) in .idata | PLT/GOT |
| Strings | Often UTF-16 LE | Typically ASCII |
| Tools | Ghidra, PE-bear, CFF Explorer, dnSpy | Ghidra, readelf, objdump, nm |
Analysis Workflow
Identify the Binary
file suspicious.exe
# PE32 executable ... Intel 80386, for MS Windows
# PE32+ executable ... x86-64, for MS Windows
strings suspicious.exe | grep -iE "(flag|ctf|pass|key|secret)"
strings -e l suspicious.exe # UTF-16 LE (Windows native!)Always run both strings (ASCII) and strings -e l (UTF-16) on Windows binaries. Native Windows apps store most text as UTF-16.
Check for .NET
strings suspicious.exe | grep -i "mscoree\|\.NET"If .NET, use ILSpy or dnSpy — they give near-original C# source. Much easier than native binary reversing.
Static Analysis with Ghidra
For non-.NET binaries, import into Ghidra → Auto-analyze → navigate to entry or WinMain → check Symbol Tree and Defined Strings.
Inspect Resources
sudo apt install icoutils
wrestool -x suspicious.exe -o resources/
binwalk -e suspicious.exeRun with Wine (if needed)
sudo apt install wine
wine suspicious.exe
winedbg suspicious.exePE Inspection with Python
import pefile
pe = pefile.PE('suspicious.exe')
print('Architecture:', pe.FILE_HEADER.Machine)
print('Timestamp:', pe.FILE_HEADER.TimeDateStamp)
for entry in pe.DIRECTORY_ENTRY_IMPORT:
print('Import DLL:', entry.dll.decode())
for imp in entry.imports:
if imp.name:
print(' ', imp.name.decode()).NET Binaries
Many Windows CTF challenges use .NET (C# / VB.NET):
strings suspicious.exe | grep -i "mscoree\|CLSIDFromProgID\|\.NET"
file suspicious.exe
# PE32 executable ... Mono/.Net assemblyCommon Windows API Calls to Watch
Checklist
-
file→ confirm PE format, 32 or 64-bit -
strings -e l→ Unicode strings (Windows native) - Check for .NET: decompile with ILSpy/dnSpy
- Ghidra for non-.NET: decompile, find main/WinMain
- Extract .rsrc with wrestool/binwalk
- Look for: strcmp, CryptDecrypt, base64 functions
- Run in Wine if static analysis is insufficient
Last updated on