如何检测Windows系统中所有可执行文件(含无扩展名及多格式)
You’re spot-on about GetBinaryType—it’s strictly limited to EXE and COM files, which doesn’t cover DLL, SYS, MSI, VXD, and other executable formats, especially when files don’t have their correct extensions. The fix here is to directly parse the file’s raw byte signatures, since every executable type has a unique header pattern that identifies it regardless of the filename.
Step 1: Detect PE Format Files (EXE, DLL, SYS, VXD, etc.)
Most Windows-native executables (EXE, DLL, SYS, VXD, OCX, etc.) use the Portable Executable (PE) format. Here’s how to verify it:
- All PE files start with the DOS signature
MZ(hex bytes0x4D 0x5A). - At offset
0x3Cin the DOS header, there’s a 4-byte value pointing to the start of the PE signature. - The PE signature is
PE\0\0(hex bytes0x50 0x45 0x00 0x00).
Example PE Detection Code
#include <fstream> #include <cstdint> #include <iostream> bool isPEFile(const std::string& filePath) { std::ifstream file(filePath, std::ios::binary); if (!file.is_open()) return false; // Check DOS signature (MZ) uint8_t dosSig[2]; file.read(reinterpret_cast<char*>(dosSig), 2); if (dosSig[0] != 0x4D || dosSig[1] != 0x5A) return false; // Jump to PE header offset file.seekg(0x3C); uint32_t peOffset; file.read(reinterpret_cast<char*>(&peOffset), 4); // Verify PE signature (PE\0\0) file.seekg(peOffset); uint8_t peSig[4]; file.read(reinterpret_cast<char*>(peSig), 4); return (peSig[0] == 0x50 && peSig[1] == 0x45 && peSig[2] == 0x00 && peSig[3] == 0x00); }
Step 2: Detect MSI Installer Files
MSI files are OLE Compound Documents, which have a distinct 8-byte signature at the very start of the file: D0 CF 11 E0 A1 B1 1A E1.
Example MSI Detection Code
bool isMSIFile(const std::string& filePath) { std::ifstream file(filePath, std::ios::binary); if (!file.is_open()) return false; uint8_t msiSig[8]; file.read(reinterpret_cast<char*>(msiSig), 8); return (msiSig[0] == 0xD0 && msiSig[1] == 0xCF && msiSig[2] == 0x11 && msiSig[3] == 0xE0 && msiSig[4] == 0xA1 && msiSig[5] == 0xB1 && msiSig[6] == 0x1A && msiSig[7] == 0xE1); }
Combine Checks for Your Use Case
Replace your original test code with a combined check that covers all the formats you care about:
#include <iostream> #include <string> int main() { std::string filePath = "1.dll"; if (isPEFile(filePath)) { std::cout << "This is a PE-format executable (EXE/DLL/SYS/VXD, etc.)" << std::endl; } else if (isMSIFile(filePath)) { std::cout << "This is an MSI installer file" << std::endl; } else { std::cout << "Not a recognized executable file" << std::endl; } return 0; }
Quick Tips
- No extension lock-in: This method checks the actual file content, so even a DLL named
fake.txtwill be correctly identified. - Add error handling: Make sure to account for files that are too small to contain the signature (e.g., a 5-byte file can’t be a PE or MSI) or files that can’t be read due to permissions.
- Other formats: If you need to detect scripts like BAT/CMD, you’d check for common starting patterns (e.g.,
@echo off), though binary signatures are always more reliable.
内容的提问来源于stack exchange,提问作者mamady madani

