From c225906277ec7de12d74e9cc847a8a89dcd4b781 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Tue, 14 Jul 2020 22:20:56 -0600 Subject: [PATCH] Add virus scanning support to Wabbajack and the server, scan all patched executable files --- .../Definitions/GKA_software_license.pdf | Bin 0 -> 28738 bytes .../FileSignatures/Definitions/bsasigs.txt | 3 + .../Definitions/file_sigs_RAW.txt | 547 ++++ .../FileSignatures/SignatureChecker.cs | 45 + Wabbajack.Common/FileSignatures/Signatures.cs | 2358 +++++++++++++++++ Wabbajack.Common/FileSignatures/Signatures.tt | 53 + Wabbajack.Common/Wabbajack.Common.csproj | 9 + Wabbajack.Lib/AInstaller.cs | 8 + Wabbajack.Lib/ClientAPI.cs | 31 +- .../CompilationSteps/IncludePatches.cs | 8 + Wabbajack.Lib/VirusScanner.cs | 44 +- Wabbajack.Server.Test/VirusCheckTests.cs | 39 + Wabbajack.Server.Test/sql/wabbajack_db.sql | 11 + Wabbajack.Server/Controllers/VirusScan.cs | 49 + .../DataLayer/VirusScanResults.cs | 37 + 15 files changed, 3234 insertions(+), 8 deletions(-) create mode 100644 Wabbajack.Common/FileSignatures/Definitions/GKA_software_license.pdf create mode 100644 Wabbajack.Common/FileSignatures/Definitions/bsasigs.txt create mode 100644 Wabbajack.Common/FileSignatures/Definitions/file_sigs_RAW.txt create mode 100644 Wabbajack.Common/FileSignatures/SignatureChecker.cs create mode 100644 Wabbajack.Common/FileSignatures/Signatures.cs create mode 100644 Wabbajack.Common/FileSignatures/Signatures.tt create mode 100644 Wabbajack.Server.Test/VirusCheckTests.cs create mode 100644 Wabbajack.Server/Controllers/VirusScan.cs create mode 100644 Wabbajack.Server/DataLayer/VirusScanResults.cs diff --git a/Wabbajack.Common/FileSignatures/Definitions/GKA_software_license.pdf b/Wabbajack.Common/FileSignatures/Definitions/GKA_software_license.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d9245fc043fcbf67544049e779e25a70bbbbe54 GIT binary patch literal 28738 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 LG&E8w(#Zb _types; + private (Definitions.FileType, byte[])[] _signatures; + + public SignatureChecker(params Definitions.FileType[] types) + { + _types = new HashSet(types); + _signatures = Definitions.Signatures.Where(row => _types.Contains(row.Item1)).ToArray(); + } + + public async Task MatchesAsync(AbsolutePath path) + { + await using var fs = await path.OpenShared(); + foreach (var signature in _signatures) + { + var buffer = new byte[signature.Item2.Length]; + fs.Position = 0; + await fs.ReadAsync(buffer); + if (AreEqual(buffer, signature.Item2)) + return signature.Item1; + } + return null; + } + + private static bool AreEqual(byte[] a, byte[] b) + { + if (a.Length != b.Length) return false; + for (var i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) return false; + } + + return true; + } + + } +} diff --git a/Wabbajack.Common/FileSignatures/Signatures.cs b/Wabbajack.Common/FileSignatures/Signatures.cs new file mode 100644 index 00000000..dcd0482d --- /dev/null +++ b/Wabbajack.Common/FileSignatures/Signatures.cs @@ -0,0 +1,2358 @@ + +namespace Wabbajack.Common.FileSignatures { + public static class Definitions { + public enum FileType { _123, + _386, + _3G2, + _3GG, + _3GP, + _3GP5, + _4XM, + _7Z, + AAC, + ABA, + ABD, + ABI, + ABY, + AC, + AC_, + ACCDB, + ACM, + ACS, + AD, + ADF, + ADP, + ADX, + AIFF, + AIN, + AMR, + ANI, + ANM, + API, + APK, + APR, + APUF, + ARC, + ARF, + ARJ, + ARL, + ASF, + AST, + ASX, + attachment, + AU, + AUT, + AVI, + AW, + AX, + b64, + B85, + BA2, + BAG, + BDR, + BIN, + BLI, + BMP, + BPG, + BSA, + BSB, + BZ2, + CAB, + CAF, + CAL, + CAP, + CAS, + CAT, + CBD, + CBK, + CDA, + CDR, + CFG, + CHI, + CHM, + CIN, + CL5, + CLASS, + CLB, + CMX, + CNV, + COD, + COM, + CPE, + CPI, + CPL, + CPT, + CPX, + CRU, + CRW, + CRX, + CSD, + CSH, + CSO, + CTF, + CTL, + CUR, + DAA, + DAT, + DAX, + DB, + DB3, + DB4, + DBA, + DBB, + DBF, + DBX, + DCI, + DCX, + dex, + DIB, + DLL, + DMG, + DMP, + DMS, + DOC, + DOCX, + DOT, + DPX, + DRV, + DRW, + DS4, + DSF, + DSN, + DSP, + DSS, + DST, + DSW, + DTD, + DUN, + DVF, + DVR, + DW4, + DWG, + E01, + ECF, + EFX, + EML, + ENL, + EPS, + EPUB, + ESD, + ETH, + EVT, + EVTX, + Ex01, + EXE, + EXR, + FBM, + FDB, + FDF, + FITS, + FLAC, + FLI, + FLT, + FLV, + FM, + FON, + FTR, + G64, + GDB, + GED, + GHO, + GHS, + GID, + GIF, + GPG, + GPX, + GRB, + GRP, + GX2, + GZ, + HAP, + HDMP, + HDR, + HLP, + HQX, + HUS, + ICO, + IDX, + IFF, + IFO, + IMG, + IND, + INDD, + INFO, + INS, + IPD, + ISO, + IVR, + JAR, + JB2, + JCEKS, + JFIF, + JG, + JNT, + JP2, + JPE, + JPEG, + JPG, + JTP, + KGB, + KMZ, + KOZ, + KWD, + LBK, + LGC, + LGD, + LHA, + LIB, + LIT, + LNK, + LOG, + LWP, + LZH, + M4A, + M4V, + MANIFEST, + MAR, + MAT, + MDB, + MDF, + MDI, + MID, + MIDI, + MIF, + MKV, + MLS, + MMF, + MNY, + MOF, + MOV, + MP, + MP3, + MP4, + MPG, + MSC, + MSF, + MSG, + MSI, + MSP, + MSV, + MTE, + MTW, + MXD, + MXF, + NRI, + NSF, + NTF, + NVRAM, + OBJ, + OCX, + ODP, + ODT, + OGA, + OGG, + OGV, + OGX, + OLB, + ONE, + ONEPKG, + OPT, + ORG, + OST, + OTF, + OTT, + OXPS, + P10, + PAK, + PAT, + PAX, + PCH, + PCS, + PCX, + PDB, + PDF, + PEC, + PES, + PF, + PFC, + PGD, + PGM, + PIF, + PKR, + PLS, + PMOCCMOC, + PNG, + PPS, + PPT, + PPTX, + PPZ, + PRC, + PSD, + PSP, + PUB, + PUF, + PWI, + PWL, + QBB, + QCP, + QDF, + QEL, + QEMU, + QPH, + QRP, + QSD, + QTS, + QTX, + QXD, + RA, + RAM, + RAR, + RBI, + RDATA, + REG, + RGB, + RM, + RMI, + RMVB, + RPM, + RTD, + RTF, + RVT, + SAM, + SAV, + SCR, + SCT, + SDPX, + SDR, + SH3, + SHD, + SHW, + SIB, + SIL, + SIT, + SKF, + SKR, + SLE, + SLN, + SNM, + SNP, + SOU, + SPF, + SPL, + SPO, + SPVB, + STL, + SUD, + SUO, + SWF, + SXC, + SXD, + SXI, + SXW, + SYS, + SYW, + TAR, + TARZ, + TB2, + TBI, + TBZ2, + TES3, + THP, + TIB, + TIF, + TIFF, + TLB, + TORRENT, + TPL, + TR1, + TTF, + UCE, + UFA, + VBE, + VBX, + VCD, + VCF, + VCW, + VHD, + VLT, + VMD, + VMDK, + VOB, + VOC, + VSD, + VXD, + WAB, + WALLET, + WAV, + WB2, + WB3, + WEBM, + WEBP, + WIM, + WIZ, + WK1, + WK3, + WK4, + WK5, + WKS, + WMA, + WMF, + WMV, + WMZ, + WP, + WP5, + WP6, + WPD, + WPF, + WPG, + WPL, + WPP, + WPS, + WRI, + WS, + WS2, + WSC, + WSF, + XAR, + XCF, + XDR, + XLA, + XLS, + XLSX, + XML, + XPI, + XPS, + XPT, + XXX, + XZ, + ZAP, + ZIP, + ZOO, + } + + public static (FileType, byte[])[] Signatures = { + // Morrowind BSA + (FileType.TES3, new byte[] {0x00, 0x01, 0x00, 0x00}), + + // TES 4-5 and FO 3 BSA + (FileType.BSA, new byte[] {0x42, 0x53, 0x41, 0x00}), + + // FO4 BSA + (FileType.BA2, new byte[] {0x42, 0x54, 0x44, 0x58}), + + // JPEG2000 image files + (FileType.JP2, new byte[] {0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20}), + + // 3GPP multimedia files + (FileType._3GP, new byte[] {0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70}), + + // MPEG-4 v1 + (FileType.MP4, new byte[] {0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D}), + + // 3rd Generation Partnership Project 3GPP + (FileType._3GG, new byte[] {0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70}), + + // 3rd Generation Partnership Project 3GPP + (FileType._3GP, new byte[] {0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70}), + + // 3rd Generation Partnership Project 3GPP + (FileType._3G2, new byte[] {0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70}), + + // Windows Disk Image + (FileType.TBI, new byte[] {0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00}), + + // Bitcoin Core wallet.dat file + (FileType.DAT, new byte[] {0x00, 0x00, 0x00, 0x00, 0x62, 0x31, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), + + // MPEG-4 video_1 + (FileType._3GP5, new byte[] {0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70}), + + // MPEG-4 video_1 + (FileType.M4V, new byte[] {0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70}), + + // MPEG-4 video_1 + (FileType.MP4, new byte[] {0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70}), + + // MPEG-4 video_2 + (FileType.MP4, new byte[] {0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70}), + + // 3GPP2 multimedia files + (FileType._3GP, new byte[] {0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70}), + + // Apple audio and video + (FileType.M4A, new byte[] {0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41}), + + // 3rd Generation Partnership Project 3GPP2 + (FileType._3GG, new byte[] {0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70}), + + // 3rd Generation Partnership Project 3GPP2 + (FileType._3GP, new byte[] {0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70}), + + // 3rd Generation Partnership Project 3GPP2 + (FileType._3G2, new byte[] {0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70}), + + // Windows icon|printer spool file + (FileType.ICO, new byte[] {0x00, 0x00, 0x01, 0x00}), + + // Windows icon|printer spool file + (FileType.SPL, new byte[] {0x00, 0x00, 0x01, 0x00}), + + // MPEG video file + (FileType.MPG, new byte[] {0x00, 0x00, 0x01, 0xB3}), + + // DVD video file + (FileType.MPG, new byte[] {0x00, 0x00, 0x01, 0xBA}), + + // DVD video file + (FileType.VOB, new byte[] {0x00, 0x00, 0x01, 0xBA}), + + // Windows cursor + (FileType.CUR, new byte[] {0x00, 0x00, 0x02, 0x00}), + + // Compucon-Singer embroidery design file + (FileType.XXX, new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), + + // QuattroPro spreadsheet + (FileType.WB2, new byte[] {0x00, 0x00, 0x02, 0x00}), + + // Wii images container + (FileType.TPL, new byte[] {0x00, 0x20, 0xAF, 0x30}), + + // Lotus 1-2-3 (v1) + (FileType.WK1, new byte[] {0x00, 0x00, 0x02, 0x00, 0x06, 0x04, 0x06, 0x00}), + + // Lotus 1-2-3 (v3) + (FileType.WK3, new byte[] {0x00, 0x00, 0x1A, 0x00, 0x00, 0x10, 0x04, 0x00}), + + // Lotus 1-2-3 (v4-v5) + (FileType.WK4, new byte[] {0x00, 0x00, 0x1A, 0x00, 0x02, 0x10, 0x04, 0x00}), + + // Lotus 1-2-3 (v4-v5) + (FileType.WK5, new byte[] {0x00, 0x00, 0x1A, 0x00, 0x02, 0x10, 0x04, 0x00}), + + // Lotus 1-2-3 (v9) + (FileType._123, new byte[] {0x00, 0x00, 0x1A, 0x00, 0x05, 0x10, 0x04}), + + // Quark Express (Intel) + (FileType.QXD, new byte[] {0x00, 0x00, 0x49, 0x49, 0x58, 0x50, 0x52}), + + // Quark Express (Motorola) + (FileType.QXD, new byte[] {0x00, 0x00, 0x4D, 0x4D, 0x58, 0x50, 0x52}), + + // Windows Help file_1 + (FileType.HLP, new byte[] {0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}), + + // TrueType font file + (FileType.TTF, new byte[] {0x00, 0x01, 0x00, 0x00, 0x00}), + + // Microsoft Money file + (FileType.MNY, new byte[] {0x00, 0x01, 0x00, 0x00, 0x4D, 0x53, 0x49, 0x53, 0x41, 0x4D, 0x20, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65}), + + // Microsoft Access 2007 + (FileType.ACCDB, new byte[] {0x00, 0x01, 0x00, 0x00, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x41, 0x43, 0x45, 0x20, 0x44, 0x42}), + + // Microsoft Access + (FileType.MDB, new byte[] {0x00, 0x01, 0x00, 0x00, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x4A, 0x65, 0x74, 0x20, 0x44, 0x42}), + + // Palm Address Book Archive + (FileType.ABA, new byte[] {0x00, 0x01, 0x42, 0x41}), + + // Palm DateBook Archive + (FileType.DBA, new byte[] {0x00, 0x01, 0x42, 0x44}), + + // Netscape Navigator (v4) database + (FileType.DB, new byte[] {0x00, 0x06, 0x15, 0x61, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0xD2, 0x00, 0x00, 0x10, 0x00}), + + // FLIC animation + (FileType.FLI, new byte[] {0x00, 0x11}), + + // Netscape Communicator (v4) mail folder + (FileType.SNM, new byte[] {0x00, 0x1E, 0x84, 0x90, 0x00, 0x00, 0x00, 0x00}), + + // PowerPoint presentation subheader_1 + (FileType.PPT, new byte[] {0x00, 0x6E, 0x1E, 0xF0}), + + // Webex Advanced Recording Format + (FileType.ARF, new byte[] {0x01, 0x00, 0x02, 0x00}), + + // Firebird and Interbase database files + (FileType.FDB, new byte[] {0x01, 0x00, 0x39, 0x30}), + + // Firebird and Interbase database files + (FileType.GDB, new byte[] {0x01, 0x00, 0x39, 0x30}), + + // The Bat! Message Base Index + (FileType.TBI, new byte[] {0x01, 0x01, 0x47, 0x19, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), + + // SQL Data Base + (FileType.MDF, new byte[] {0x01, 0x0F, 0x00, 0x00}), + + // Novell LANalyzer capture file + (FileType.TR1, new byte[] {0x01, 0x10}), + + // Silicon Graphics RGB Bitmap + (FileType.RGB, new byte[] {0x01, 0xDA, 0x01, 0x01, 0x00, 0x03}), + + // Micrografx vector graphic file + (FileType.DRW, new byte[] {0x01, 0xFF, 0x02, 0x04, 0x03, 0x02}), + + // Digital Speech Standard file + (FileType.DSS, new byte[] {0x02, 0x64, 0x73, 0x73}), + + // MapInfo Native Data Format + (FileType.DAT, new byte[] {0x03}), + + // dBASE III file + (FileType.DB3, new byte[] {0x03}), + + // Quicken price history + (FileType.QPH, new byte[] {0x03, 0x00, 0x00, 0x00}), + + // Approach index file + (FileType.ADX, new byte[] {0x03, 0x00, 0x00, 0x00, 0x41, 0x50, 0x50, 0x52}), + + // dBASE IV file + (FileType.DB4, new byte[] {0x04}), + + // Adobe InDesign + (FileType.INDD, new byte[] {0x06, 0x06, 0xED, 0xF5, 0xD8, 0x1D, 0x46, 0xE5, 0xBD, 0x31, 0xEF, 0xE7, 0xFE, 0x74, 0xB7, 0x1D}), + + // Material Exchange Format + (FileType.MXF, new byte[] {0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02}), + + // Generic drawing programs + (FileType.DRW, new byte[] {0x07}), + + // SkinCrafter skin + (FileType.SKF, new byte[] {0x07, 0x53, 0x4B, 0x46}), + + // DesignTools 2D Design file + (FileType.DTD, new byte[] {0x07, 0x64, 0x74, 0x32, 0x64, 0x64, 0x74, 0x64}), + + // dBASE IV or dBFast configuration file + (FileType.DB, new byte[] {0x08}), + + // Excel spreadsheet subheader_1 + (FileType.XLS, new byte[] {0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00}), + + // ZSOFT Paintbrush file_1 + (FileType.PCX, new byte[] {0x0A, 0x02, 0x01, 0x01}), + + // ZSOFT Paintbrush file_2 + (FileType.PCX, new byte[] {0x0A, 0x03, 0x01, 0x01}), + + // ZSOFT Paintbrush file_3 + (FileType.PCX, new byte[] {0x0A, 0x05, 0x01, 0x01}), + + // MultiBit Bitcoin wallet file + (FileType.WALLET, new byte[] {0x0A, 0x16, 0x6F, 0x72, 0x67, 0x2E, 0x62, 0x69, 0x74, 0x63, 0x6F, 0x69, 0x6E, 0x2E, 0x70, 0x72}), + + // Monochrome Picture TIFF bitmap + (FileType.MP, new byte[] {0x0C, 0xED}), + + // DeskMate Document + (FileType.DOC, new byte[] {0x0D, 0x44, 0x4F, 0x43}), + + // Nero CD compilation + (FileType.NRI, new byte[] {0x0E, 0x4E, 0x65, 0x72, 0x6F, 0x49, 0x53, 0x4F}), + + // DeskMate Worksheet + (FileType.WKS, new byte[] {0x0E, 0x57, 0x4B, 0x53}), + + // PowerPoint presentation subheader_2 + (FileType.PPT, new byte[] {0x0F, 0x00, 0xE8, 0x03}), + + // Sibelius Music - Score + (FileType.SIB, new byte[] {0x0F, 0x53, 0x49, 0x42, 0x45, 0x4C, 0x49, 0x55, 0x53}), + + // Easy CD Creator 5 Layout file + (FileType.CL5, new byte[] {0x10, 0x00, 0x00, 0x00}), + + // Windows prefetch file + (FileType.PF, new byte[] {0x11, 0x00, 0x00, 0x00, 0x53, 0x43, 0x43, 0x41}), + + // Lotus Notes database template + (FileType.NTF, new byte[] {0x1A, 0x00, 0x00}), + + // Lotus Notes database + (FileType.NSF, new byte[] {0x1A, 0x00, 0x00, 0x04, 0x00, 0x00}), + + // LH archive (old vers.-type 1) + (FileType.ARC, new byte[] {0x1A, 0x02}), + + // LH archive (old vers.-type 2) + (FileType.ARC, new byte[] {0x1A, 0x03}), + + // LH archive (old vers.-type 3) + (FileType.ARC, new byte[] {0x1A, 0x04}), + + // LH archive (old vers.-type 4) + (FileType.ARC, new byte[] {0x1A, 0x08}), + + // LH archive (old vers.-type 5) + (FileType.ARC, new byte[] {0x1A, 0x09}), + + // Compressed archive file + (FileType.PAK, new byte[] {0x1A, 0x0B}), + + // WinPharoah capture file + (FileType.ETH, new byte[] {0x1A, 0x35, 0x01, 0x00}), + + // WebM video file + (FileType.WEBM, new byte[] {0x1A, 0x45, 0xDF, 0xA3}), + + // Matroska stream file_1 + (FileType.MKV, new byte[] {0x1A, 0x45, 0xDF, 0xA3}), + + // Matroska stream file_2 + (FileType.MKV, new byte[] {0x1A, 0x45, 0xDF, 0xA3, 0x93, 0x42, 0x82, 0x88}), + + // Runtime Software disk image + (FileType.DAT, new byte[] {0x1A, 0x52, 0x54, 0x53, 0x20, 0x43, 0x4F, 0x4D}), + + // WordStar Version 5.0-6.0 document + (FileType.WS, new byte[] {0x1D, 0x7D}), + + // GZIP archive file + (FileType.GZ, new byte[] {0x1F, 0x8B, 0x08}), + + // VLC Player Skin file + (FileType.VLT, new byte[] {0x1F, 0x8B, 0x08}), + + // Compressed tape archive_1 + (FileType.TARZ, new byte[] {0x1F, 0x9D, 0x90}), + + // Compressed tape archive_2 + (FileType.TARZ, new byte[] {0x1F, 0xA0}), + + // MapInfo Sea Chart + (FileType.BSB, new byte[] {0x21}), + + // AIN Compressed Archive + (FileType.AIN, new byte[] {0x21, 0x12}), + + // Unix archiver (ar)-MS Program Library Common Object File Format (COFF) + (FileType.LIB, new byte[] {0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A}), + + // Microsoft Outlook Exchange Offline Storage Folder + (FileType.OST, new byte[] {0x21, 0x42, 0x44, 0x4E}), + + // Cerius2 file + (FileType.MSI, new byte[] {0x23, 0x20}), + + // VMware 4 Virtual Disk description + (FileType.VMDK, new byte[] {0x23, 0x20, 0x44, 0x69, 0x73, 0x6B, 0x20, 0x44}), + + // MS Developer Studio project file + (FileType.DSP, new byte[] {0x23, 0x20, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73}), + + // Adaptive Multi-Rate ACELP Codec (GSM) + (FileType.AMR, new byte[] {0x23, 0x21, 0x41, 0x4D, 0x52}), + + // Skype audio compression + (FileType.SIL, new byte[] {0x23, 0x21, 0x53, 0x49, 0x4C, 0x4B, 0x0A}), + + // Radiance High Dynamic Range image file + (FileType.HDR, new byte[] {0x23, 0x3F, 0x52, 0x41, 0x44, 0x49, 0x41, 0x4E}), + + // VBScript Encoded script + (FileType.VBE, new byte[] {0x23, 0x40, 0x7E, 0x5E}), + + // Brother-Babylock-Bernina Home Embroidery + (FileType.PEC, new byte[] {0x23, 0x50, 0x45, 0x43, 0x30, 0x30, 0x30, 0x31}), + + // Brother-Babylock-Bernina Home Embroidery + (FileType.PES, new byte[] {0x23, 0x50, 0x45, 0x53, 0x30}), + + // SPSS Data file + (FileType.SAV, new byte[] {0x24, 0x46, 0x4C, 0x32, 0x40, 0x28, 0x23, 0x29}), + + // Encapsulated PostScript file + (FileType.EPS, new byte[] {0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, 0x6F}), + + // PDF file + (FileType.PDF, new byte[] {0x25, 0x50, 0x44, 0x46}), + + // PDF file + (FileType.FDF, new byte[] {0x25, 0x50, 0x44, 0x46}), + + // Fuzzy bitmap (FBM) file + (FileType.FBM, new byte[] {0x25, 0x62, 0x69, 0x74, 0x6D, 0x61, 0x70}), + + // BinHex 4 Compressed Archive + (FileType.HQX, new byte[] {0x28, 0x54, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69}), + + // Symantec Wise Installer log + (FileType.LOG, new byte[] {0x2A, 0x2A, 0x2A, 0x20, 0x20, 0x49, 0x6E, 0x73}), + + // Compressed archive + (FileType.LHA, new byte[] {0x2D, 0x6C, 0x68}), + + // Compressed archive + (FileType.LZH, new byte[] {0x2D, 0x6C, 0x68}), + + // RealPlayer video file (V11+) + (FileType.IVR, new byte[] {0x2E, 0x52, 0x45, 0x43}), + + // RealMedia streaming media + (FileType.RM, new byte[] {0x2E, 0x52, 0x4D, 0x46}), + + // RealMedia streaming media + (FileType.RMVB, new byte[] {0x2E, 0x52, 0x4D, 0x46}), + + // RealAudio file + (FileType.RA, new byte[] {0x2E, 0x52, 0x4D, 0x46, 0x00, 0x00, 0x00, 0x12}), + + // RealAudio streaming media + (FileType.RA, new byte[] {0x2E, 0x72, 0x61, 0xFD, 0x00}), + + // NeXT-Sun Microsystems audio file + (FileType.AU, new byte[] {0x2E, 0x73, 0x6E, 0x64}), + + // Thunderbird-Mozilla Mail Summary File + (FileType.MSF, new byte[] {0x2F, 0x2F, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x3C, 0x6D, 0x64, 0x62, 0x3A, 0x6D, 0x6F, 0x72, 0x6B, 0x3A, 0x7A}), + + // MS security catalog file + (FileType.CAT, new byte[] {0x30}), + + // Windows Event Viewer file + (FileType.EVT, new byte[] {0x30, 0x00, 0x00, 0x00, 0x4C, 0x66, 0x4C, 0x65}), + + // GEnealogical Data COMmunication (GEDCOM) file + (FileType.GED, new byte[] {0x30, 0x20, 0x48, 0x45, 0x41, 0x44}), + + // Windows Media Audio-Video File + (FileType.ASF, new byte[] {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11}), + + // Windows Media Audio-Video File + (FileType.WMA, new byte[] {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11}), + + // Windows Media Audio-Video File + (FileType.WMV, new byte[] {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11}), + + // National Transfer Format Map + (FileType.NTF, new byte[] {0x30, 0x31, 0x4F, 0x52, 0x44, 0x4E, 0x41, 0x4E}), + + // MS Write file_1 + (FileType.WRI, new byte[] {0x31, 0xBE}), + + // MS Write file_2 + (FileType.WRI, new byte[] {0x32, 0xBE}), + + // Pfaff Home Embroidery + (FileType.PCS, new byte[] {0x32, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xFF, 0x00}), + + // 7-Zip compressed file + (FileType._7Z, new byte[] {0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C}), + + // Photoshop image + (FileType.PSD, new byte[] {0x38, 0x42, 0x50, 0x53}), + + // Surfplan kite project file + (FileType.SLE, new byte[] {0x3A, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4F, 0x4E}), + + // Advanced Stream Redirector + (FileType.ASX, new byte[] {0x3C}), + + // BizTalk XML-Data Reduced Schema + (FileType.XDR, new byte[] {0x3C}), + + // AOL HTML mail + (FileType.DCI, new byte[] {0x3C, 0x21, 0x64, 0x6F, 0x63, 0x74, 0x79, 0x70}), + + // Windows Script Component + (FileType.WSC, new byte[] {0x3C, 0x3F}), + + // Windows Visual Stylesheet + (FileType.MANIFEST, new byte[] {0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D}), + + // User Interface Language + (FileType.XML, new byte[] {0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x3F, 0x3E}), + + // MMC Snap-in Control file + (FileType.MSC, new byte[] {0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x3F, 0x3E, 0x0D, 0x0A, 0x3C, 0x4D, 0x4D, 0x43, 0x5F, 0x43, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22}), + + // Picasa movie project file + (FileType.MXF, new byte[] {0x3C, 0x43, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x54, 0x69, 0x6D, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x3E}), + + // Csound music + (FileType.CSD, new byte[] {0x3C, 0x43, 0x73, 0x6F, 0x75, 0x6E, 0x64, 0x53, 0x79, 0x6E, 0x74, 0x68, 0x65, 0x73, 0x69, 0x7A}), + + // Adobe FrameMaker + (FileType.FM, new byte[] {0x3C, 0x4D, 0x61, 0x6B, 0x65, 0x72, 0x46, 0x69}), + + // Adobe FrameMaker + (FileType.MIF, new byte[] {0x3C, 0x4D, 0x61, 0x6B, 0x65, 0x72, 0x46, 0x69}), + + // GPS Exchange (v1.1) + (FileType.GPX, new byte[] {0x3C, 0x67, 0x70, 0x78, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E}), + + // BASE85 file + (FileType.B85, new byte[] {0x3C, 0x7E, 0x36, 0x3C, 0x5C, 0x25, 0x5F, 0x30, 0x67, 0x53, 0x71, 0x68, 0x3B}), + + // Quatro Pro for Windows 7.0 + (FileType.WB3, new byte[] {0x3E, 0x00, 0x03, 0x00, 0xFE, 0xFF, 0x09, 0x00, 0x06}), + + // Windows Help file_2 + (FileType.GID, new byte[] {0x3F, 0x5F, 0x03, 0x00}), + + // Windows Help file_2 + (FileType.HLP, new byte[] {0x3F, 0x5F, 0x03, 0x00}), + + // EndNote Library File + (FileType.ENL, new byte[] {0x40, 0x40, 0x40, 0x20, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40}), + + // Generic AutoCAD drawing + (FileType.DWG, new byte[] {0x41, 0x43, 0x31, 0x30}), + + // Steganos virtual secure drive + (FileType.SLE, new byte[] {0x41, 0x43, 0x76}), + + // Harvard Graphics symbol graphic + (FileType.SYW, new byte[] {0x41, 0x4D, 0x59, 0x4F}), + + // AOL config files + (FileType.ABI, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL config files + (FileType.ABY, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL config files + (FileType.BAG, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL config files + (FileType.IDX, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL config files + (FileType.IND, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL config files + (FileType.PFC, new byte[] {0x41, 0x4F, 0x4C}), + + // AOL and AIM buddy list + (FileType.BAG, new byte[] {0x41, 0x4F, 0x4C, 0x20, 0x46, 0x65, 0x65, 0x64}), + + // AOL address book + (FileType.ABY, new byte[] {0x41, 0x4F, 0x4C, 0x44, 0x42}), + + // AOL user configuration + (FileType.IDX, new byte[] {0x41, 0x4F, 0x4C, 0x44, 0x42}), + + // AOL client preferences-settings file + (FileType.IND, new byte[] {0x41, 0x4F, 0x4C, 0x49, 0x44, 0x58}), + + // AOL address book index + (FileType.ABI, new byte[] {0x41, 0x4F, 0x4C, 0x49, 0x4E, 0x44, 0x45, 0x58}), + + // AOL personal file cabinet + (FileType.ORG, new byte[] {0x41, 0x4F, 0x4C, 0x56, 0x4D, 0x31, 0x30, 0x30}), + + // AOL personal file cabinet + (FileType.PFC, new byte[] {0x41, 0x4F, 0x4C, 0x56, 0x4D, 0x31, 0x30, 0x30}), + + // AVG6 Integrity database + (FileType.DAT, new byte[] {0x41, 0x56, 0x47, 0x36, 0x5F, 0x49, 0x6E, 0x74}), + + // RIFF Windows Audio + (FileType.AVI, new byte[] {0x41, 0x56, 0x49, 0x20, 0x4C, 0x49, 0x53, 0x54}), + + // FreeArc compressed file + (FileType.ARC, new byte[] {0x41, 0x72, 0x43, 0x01}), + + // vCard + (FileType.VCF, new byte[] {0x42, 0x45, 0x47, 0x49, 0x4E, 0x3A, 0x56, 0x43}), + + // Speedtouch router firmware + (FileType.BIN, new byte[] {0x42, 0x4C, 0x49, 0x32, 0x32, 0x33}), + + // Speedtouch router firmware + (FileType.BLI, new byte[] {0x42, 0x4C, 0x49, 0x32, 0x32, 0x33}), + + // Speedtouch router firmware + (FileType.RBI, new byte[] {0x42, 0x4C, 0x49, 0x32, 0x32, 0x33}), + + // Bitmap image + (FileType.BMP, new byte[] {0x42, 0x4D}), + + // Bitmap image + (FileType.DIB, new byte[] {0x42, 0x4D}), + + // Palmpilot resource file + (FileType.PRC, new byte[] {0x42, 0x4F, 0x4F, 0x4B, 0x4D, 0x4F, 0x42, 0x49}), + + // Better Portable Graphics + (FileType.BPG, new byte[] {0x42, 0x50, 0x47, 0xFB}), + + // bzip2 compressed archive + (FileType.BZ2, new byte[] {0x42, 0x5A, 0x68}), + + // bzip2 compressed archive + (FileType.TAR, new byte[] {0x42, 0x5A, 0x68}), + + // bzip2 compressed archive + (FileType.BZ2, new byte[] {0x42, 0x5A, 0x68}), + + // bzip2 compressed archive + (FileType.TBZ2, new byte[] {0x42, 0x5A, 0x68}), + + // bzip2 compressed archive + (FileType.TB2, new byte[] {0x42, 0x5A, 0x68}), + + // Mac Disk image (BZ2 compressed) + (FileType.DMG, new byte[] {0x42, 0x5A, 0x68}), + + // Puffer ASCII encrypted archive + (FileType.APUF, new byte[] {0x42, 0x65, 0x67, 0x69, 0x6E, 0x20, 0x50, 0x75, 0x66, 0x66, 0x65, 0x72}), + + // Blink compressed archive + (FileType.BLI, new byte[] {0x42, 0x6C, 0x69, 0x6E, 0x6B}), + + // RagTime document + (FileType.RTD, new byte[] {0x43, 0x23, 0x2B, 0x44, 0xA4, 0x43, 0x4D, 0xA5}), + + // EA Interchange Format File (IFF)_3 + (FileType.IFF, new byte[] {0x43, 0x41, 0x54, 0x20}), + + // WordPerfect dictionary + (FileType.CBD, new byte[] {0x43, 0x42, 0x46, 0x49, 0x4C, 0x45}), + + // ISO-9660 CD Disc Image + (FileType.ISO, new byte[] {0x43, 0x44, 0x30, 0x30, 0x31}), + + // RIFF CD audio + (FileType.CDA, new byte[] {0x43, 0x44, 0x44, 0x41, 0x66, 0x6D, 0x74, 0x20}), + + // Compressed ISO CD image + (FileType.CSO, new byte[] {0x43, 0x49, 0x53, 0x4F}), + + // Windows 7 thumbnail + (FileType.DB, new byte[] {0x43, 0x4D, 0x4D, 0x4D, 0x15, 0x00, 0x00, 0x00}), + + // Corel Binary metafile + (FileType.CLB, new byte[] {0x43, 0x4D, 0x58, 0x31}), + + // COM+ Catalog + (FileType.CLB, new byte[] {0x43, 0x4F, 0x4D, 0x2B}), + + // VMware 3 Virtual Disk + (FileType.VMDK, new byte[] {0x43, 0x4F, 0x57, 0x44}), + + // Corel Photopaint file_1 + (FileType.CPT, new byte[] {0x43, 0x50, 0x54, 0x37, 0x46, 0x49, 0x4C, 0x45}), + + // Corel Photopaint file_2 + (FileType.CPT, new byte[] {0x43, 0x50, 0x54, 0x46, 0x49, 0x4C, 0x45}), + + // Win9x registry hive + (FileType.DAT, new byte[] {0x43, 0x52, 0x45, 0x47}), + + // Crush compressed archive + (FileType.CRU, new byte[] {0x43, 0x52, 0x55, 0x53, 0x48, 0x20, 0x76}), + + // Shockwave Flash file + (FileType.SWF, new byte[] {0x43, 0x57, 0x53}), + + // Calculux Indoor lighting project file + (FileType.CIN, new byte[] {0x43, 0x61, 0x6C, 0x63, 0x75, 0x6C, 0x75, 0x78, 0x20, 0x49, 0x6E, 0x64, 0x6F, 0x6F, 0x72, 0x20}), + + // WhereIsIt Catalog + (FileType.CTF, new byte[] {0x43, 0x61, 0x74, 0x61, 0x6C, 0x6F, 0x67, 0x20}), + + // IE History file + (FileType.DAT, new byte[] {0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x55}), + + // Google Chrome Extension + (FileType.CRX, new byte[] {0x43, 0x72, 0x32, 0x34}), + + // Creative Voice + (FileType.VOC, new byte[] {0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x56, 0x6F, 0x69, 0x63, 0x65, 0x20, 0x46}), + + // PowerISO Direct-Access-Archive image + (FileType.DAA, new byte[] {0x44, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00}), + + // DAX Compressed CD image + (FileType.DAX, new byte[] {0x44, 0x41, 0x58, 0x00}), + + // Palm Zire photo database + (FileType.DB, new byte[] {0x44, 0x42, 0x46, 0x48}), + + // Amiga DiskMasher compressed archive + (FileType.DMS, new byte[] {0x44, 0x4D, 0x53, 0x21}), + + // Amiga disk file + (FileType.ADF, new byte[] {0x44, 0x4F, 0x53}), + + // DST Compression + (FileType.DST, new byte[] {0x44, 0x53, 0x54, 0x62}), + + // DVR-Studio stream file + (FileType.DVR, new byte[] {0x44, 0x56, 0x44}), + + // DVD info file + (FileType.IFO, new byte[] {0x44, 0x56, 0x44}), + + // Elite Plus Commander game file + (FileType.CDR, new byte[] {0x45, 0x4C, 0x49, 0x54, 0x45, 0x20, 0x43, 0x6F}), + + // VideoVCD-VCDImager file + (FileType.VCD, new byte[] {0x45, 0x4E, 0x54, 0x52, 0x59, 0x56, 0x43, 0x44}), + + // Apple ISO 9660-HFS hybrid CD image + (FileType.ISO, new byte[] {0x45, 0x52, 0x02, 0x00, 0x00}), + + // EasyRecovery Saved State file + (FileType.DAT, new byte[] {0x45, 0x52, 0x46, 0x53, 0x53, 0x41, 0x56, 0x45}), + + // DSD Storage Facility audio file + (FileType.DSF, new byte[] {0x44, 0x53, 0x44, 0x20}), + + // MS Document Imaging file + (FileType.MDI, new byte[] {0x45, 0x50}), + + // Expert Witness Compression Format + (FileType.E01, new byte[] {0x45, 0x56, 0x46, 0x09, 0x0D, 0x0A, 0xFF, 0x00}), + + // EnCase Evidence File Format V2 + (FileType.Ex01, new byte[] {0x45, 0x56, 0x46, 0x32, 0x0D, 0x0A, 0x81}), + + // Windows Vista event log + (FileType.EVTX, new byte[] {0x45, 0x6C, 0x66, 0x46, 0x69, 0x6C, 0x65, 0x00}), + + // QuickBooks backup + (FileType.QBB, new byte[] {0x45, 0x86, 0x00, 0x00, 0x06, 0x00}), + + // MS Fax Cover Sheet + (FileType.CPE, new byte[] {0x46, 0x41, 0x58, 0x43, 0x4F, 0x56, 0x45, 0x52}), + + // Fiasco database definition file + (FileType.FDB, new byte[] {0x46, 0x44, 0x42, 0x48, 0x00}), + + // Flash video file + (FileType.FLV, new byte[] {0x46, 0x4C, 0x56}), + + // IFF ANIM file + (FileType.ANM, new byte[] {0x46, 0x4F, 0x52, 0x4D}), + + // EA Interchange Format File (IFF)_1 + (FileType.IFF, new byte[] {0x46, 0x4F, 0x52, 0x4D}), + + // Audio Interchange File + (FileType.AIFF, new byte[] {0x46, 0x4F, 0x52, 0x4D, 0x00}), + + // DAKX Compressed Audio + (FileType.DAX, new byte[] {0x46, 0x4F, 0x52, 0x4D, 0x00}), + + // Shockwave Flash player + (FileType.SWF, new byte[] {0x46, 0x57, 0x53}), + + // Generic e-mail_2 + (FileType.EML, new byte[] {0x46, 0x72, 0x6F, 0x6D}), + + // GIF file + (FileType.GIF, new byte[] {0x47, 0x49, 0x46, 0x38}), + + // GIMP pattern file + (FileType.PAT, new byte[] {0x47, 0x50, 0x41, 0x54}), + + // General Regularly-distributed Information (GRIdded) Binary + (FileType.GRB, new byte[] {0x47, 0x52, 0x49, 0x42}), + + // Show Partner graphics file + (FileType.GX2, new byte[] {0x47, 0x58, 0x32}), + + // Genetec video archive + (FileType.G64, new byte[] {0x47, 0x65, 0x6E, 0x65, 0x74, 0x65, 0x63, 0x20, 0x4F, 0x6D, 0x6E, 0x69, 0x63, 0x61, 0x73, 0x74}), + + // SAS Transport dataset + (FileType.XPT, new byte[] {0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x52, 0x45, 0x43, 0x4F, 0x52, 0x44, 0x2A, 0x2A, 0x2A}), + + // Harvard Graphics presentation file + (FileType.SH3, new byte[] {0x48, 0x48, 0x47, 0x42, 0x31}), + + // TIFF file_1 + (FileType.TIF, new byte[] {0x49, 0x20, 0x49}), + + // TIFF file_1 + (FileType.TIFF, new byte[] {0x49, 0x20, 0x49}), + + // MP3 audio file + (FileType.MP3, new byte[] {0x49, 0x44, 0x33}), + + // Sprint Music Store audio + (FileType.KOZ, new byte[] {0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00}), + + // Canon RAW file + (FileType.CRW, new byte[] {0x49, 0x49, 0x1A, 0x00, 0x00, 0x00, 0x48, 0x45}), + + // TIFF file_2 + (FileType.TIF, new byte[] {0x49, 0x49, 0x2A, 0x00}), + + // TIFF file_2 + (FileType.TIFF, new byte[] {0x49, 0x49, 0x2A, 0x00}), + + // Windows 7 thumbnail_2 + (FileType.DB, new byte[] {0x49, 0x4D, 0x4D, 0x4D, 0x15, 0x00, 0x00, 0x00}), + + // Install Shield compressed file + (FileType.CAB, new byte[] {0x49, 0x53, 0x63, 0x28}), + + // Install Shield compressed file + (FileType.HDR, new byte[] {0x49, 0x53, 0x63, 0x28}), + + // MS Reader eBook + (FileType.LIT, new byte[] {0x49, 0x54, 0x4F, 0x4C, 0x49, 0x54, 0x4C, 0x53}), + + // MS Compiled HTML Help File + (FileType.CHI, new byte[] {0x49, 0x54, 0x53, 0x46}), + + // MS Compiled HTML Help File + (FileType.CHM, new byte[] {0x49, 0x54, 0x53, 0x46}), + + // Inno Setup Uninstall Log + (FileType.DAT, new byte[] {0x49, 0x6E, 0x6E, 0x6F, 0x20, 0x53, 0x65, 0x74}), + + // Inter@ctive Pager Backup (BlackBerry file + (FileType.IPD, new byte[] {0x49, 0x6E, 0x74, 0x65, 0x72, 0x40, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x50, 0x61, 0x67, 0x65}), + + // JARCS compressed archive + (FileType.JAR, new byte[] {0x4A, 0x41, 0x52, 0x43, 0x53, 0x00}), + + // AOL ART file_1 + (FileType.JG, new byte[] {0x4A, 0x47, 0x03, 0x0E}), + + // AOL ART file_2 + (FileType.JG, new byte[] {0x4A, 0x47, 0x04, 0x0E}), + + // VMware 4 Virtual Disk + (FileType.VMDK, new byte[] {0x4B, 0x44, 0x4D}), + + // KGB archive + (FileType.KGB, new byte[] {0x4B, 0x47, 0x42, 0x5F, 0x61, 0x72, 0x63, 0x68}), + + // Win9x printer spool file + (FileType.SHD, new byte[] {0x4B, 0x49, 0x00, 0x00}), + + // Windows shortcut file + (FileType.LNK, new byte[] {0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00}), + + // MS COFF relocatable object code + (FileType.OBJ, new byte[] {0x4C, 0x01}), + + // Tajima emboridery + (FileType.DST, new byte[] {0x4C, 0x41, 0x3A}), + + // Windows help file_3 + (FileType.GID, new byte[] {0x4C, 0x4E, 0x02, 0x00}), + + // Windows help file_3 + (FileType.HLP, new byte[] {0x4C, 0x4E, 0x02, 0x00}), + + // EA Interchange Format File (IFF)_2 + (FileType.IFF, new byte[] {0x4C, 0x49, 0x53, 0x54}), + + // DeluxePaint Animation + (FileType.ANM, new byte[] {0x4C, 0x50, 0x46, 0x20, 0x00, 0x01}), + + // Logical File Evidence Format + (FileType.E01, new byte[] {0x4C, 0x56, 0x46, 0x09, 0x0D, 0x0A, 0xFF, 0x00}), + + // Merriam-Webster Pocket Dictionary + (FileType.PDB, new byte[] {0x4D, 0x2D, 0x57, 0x20, 0x50, 0x6F, 0x63, 0x6B}), + + // Mozilla archive + (FileType.MAR, new byte[] {0x4D, 0x41, 0x52, 0x31, 0x00}), + + // Microsoft-MSN MARC archive + (FileType.MAR, new byte[] {0x4D, 0x41, 0x52, 0x43}), + + // MATLAB v5 workspace + (FileType.MAT, new byte[] {0x4D, 0x41, 0x54, 0x4C, 0x41, 0x42, 0x20, 0x35, 0x2E, 0x30, 0x20, 0x4D, 0x41, 0x54, 0x2D, 0x66, 0x69, 0x6C, 0x65}), + + // MAr compressed archive + (FileType.MAR, new byte[] {0x4D, 0x41, 0x72, 0x30, 0x00}), + + // TargetExpress target file + (FileType.MTE, new byte[] {0x4D, 0x43, 0x57, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x67, 0x6F, 0x6C, 0x69, 0x65, 0x73}), + + // Windows dump file + (FileType.DMP, new byte[] {0x4D, 0x44, 0x4D, 0x50, 0x93, 0xA7}), + + // Windows dump file + (FileType.HDMP, new byte[] {0x4D, 0x44, 0x4D, 0x50, 0x93, 0xA7}), + + // Milestones project management file + (FileType.MLS, new byte[] {0x4D, 0x49, 0x4C, 0x45, 0x53}), + + // Skype localization data file + (FileType.MLS, new byte[] {0x4D, 0x4C, 0x53, 0x57}), + + // TIFF file_3 + (FileType.TIF, new byte[] {0x4D, 0x4D, 0x00, 0x2A}), + + // TIFF file_3 + (FileType.TIFF, new byte[] {0x4D, 0x4D, 0x00, 0x2A}), + + // TIFF file_4 + (FileType.TIF, new byte[] {0x4D, 0x4D, 0x00, 0x2B}), + + // TIFF file_4 + (FileType.TIFF, new byte[] {0x4D, 0x4D, 0x00, 0x2B}), + + // Yamaha Synthetic music Mobile Application Format + (FileType.MMF, new byte[] {0x4D, 0x4D, 0x4D, 0x44, 0x00, 0x00}), + + // VMware BIOS state file + (FileType.NVRAM, new byte[] {0x4D, 0x52, 0x56, 0x4E}), + + // Microsoft cabinet file + (FileType.CAB, new byte[] {0x4D, 0x53, 0x43, 0x46}), + + // OneNote Package + (FileType.ONEPKG, new byte[] {0x4D, 0x53, 0x43, 0x46}), + + // Powerpoint Packaged Presentation + (FileType.PPZ, new byte[] {0x4D, 0x53, 0x43, 0x46}), + + // MS Access Snapshot Viewer file + (FileType.SNP, new byte[] {0x4D, 0x53, 0x43, 0x46}), + + // OLE-SPSS-Visual C++ library file + (FileType.TLB, new byte[] {0x4D, 0x53, 0x46, 0x54, 0x02, 0x00, 0x01, 0x00}), + + // Microsoft Windows Imaging Format + (FileType.WIM, new byte[] {0x4D, 0x53, 0x57, 0x49, 0x4D}), + + // Sony Compressed Voice File + (FileType.CDR, new byte[] {0x4D, 0x53, 0x5F, 0x56, 0x4F, 0x49, 0x43, 0x45}), + + // Sony Compressed Voice File + (FileType.DVF, new byte[] {0x4D, 0x53, 0x5F, 0x56, 0x4F, 0x49, 0x43, 0x45}), + + // Sony Compressed Voice File + (FileType.MSV, new byte[] {0x4D, 0x53, 0x5F, 0x56, 0x4F, 0x49, 0x43, 0x45}), + + // MIDI sound file + (FileType.MID, new byte[] {0x4D, 0x54, 0x68, 0x64}), + + // MIDI sound file + (FileType.MIDI, new byte[] {0x4D, 0x54, 0x68, 0x64}), + + // Yamaha Piano + (FileType.PCS, new byte[] {0x4D, 0x54, 0x68, 0x64}), + + // CD Stomper Pro label file + (FileType.DSN, new byte[] {0x4D, 0x56}), + + // Milestones project management file_1 + (FileType.MLS, new byte[] {0x4D, 0x56, 0x32, 0x31, 0x34}), + + // Milestones project management file_2 + (FileType.MLS, new byte[] {0x4D, 0x56, 0x32, 0x43}), + + // Windows-DOS executable file + (FileType.COM, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.DLL, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.DRV, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.EXE, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.PIF, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.QTS, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.QTX, new byte[] {0x4D, 0x5A}), + + // Windows-DOS executable file + (FileType.SYS, new byte[] {0x4D, 0x5A}), + + // MS audio compression manager driver + (FileType.ACM, new byte[] {0x4D, 0x5A}), + + // Library cache file + (FileType.AX, new byte[] {0x4D, 0x5A}), + + // Control panel application + (FileType.CPL, new byte[] {0x4D, 0x5A}), + + // Font file + (FileType.FON, new byte[] {0x4D, 0x5A}), + + // ActiveX-OLE Custom Control + (FileType.OCX, new byte[] {0x4D, 0x5A}), + + // OLE object library + (FileType.OLB, new byte[] {0x4D, 0x5A}), + + // Screen saver + (FileType.SCR, new byte[] {0x4D, 0x5A}), + + // VisualBASIC application + (FileType.VBX, new byte[] {0x4D, 0x5A}), + + // Windows virtual device drivers + (FileType.VXD, new byte[] {0x4D, 0x5A}), + + // Windows virtual device drivers + (FileType._386, new byte[] {0x4D, 0x5A}), + + // Acrobat plug-in + (FileType.API, new byte[] {0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00}), + + // DirectShow filter + (FileType.AX, new byte[] {0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00}), + + // Audition graphic filter + (FileType.FLT, new byte[] {0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00}), + + // ZoneAlam data file + (FileType.ZAP, new byte[] {0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF}), + + // MS C++ debugging symbols file + (FileType.PDB, new byte[] {0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20}), + + // Visual Studio .NET file + (FileType.SLN, new byte[] {0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C}), + + // Windows Media Player playlist + (FileType.WPL, new byte[] {0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x20, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x20, 0x2D, 0x2D, 0x20}), + + // VMapSource GPS Waypoint Database + (FileType.GDB, new byte[] {0x4D, 0x73, 0x52, 0x63, 0x66}), + + // TomTom traffic data + (FileType.DAT, new byte[] {0x4E, 0x41, 0x56, 0x54, 0x52, 0x41, 0x46, 0x46}), + + // MS Windows journal + (FileType.JNT, new byte[] {0x4E, 0x42, 0x2A, 0x00}), + + // MS Windows journal + (FileType.JTP, new byte[] {0x4E, 0x42, 0x2A, 0x00}), + + // NES Sound file + (FileType.NSF, new byte[] {0x4E, 0x45, 0x53, 0x4D, 0x1A, 0x01}), + + // National Imagery Transmission Format file + (FileType.NTF, new byte[] {0x4E, 0x49, 0x54, 0x46, 0x30}), + + // Agent newsreader character map + (FileType.COD, new byte[] {0x4E, 0x61, 0x6D, 0x65, 0x3A, 0x20}), + + // 1Password 4 Cloud Keychain + (FileType.attachment, new byte[] {0x4F, 0x50, 0x43, 0x4C, 0x44, 0x41, 0x54}), + + // Psion Series 3 Database + (FileType.DBF, new byte[] {0x4F, 0x50, 0x4C, 0x44, 0x61, 0x74, 0x61, 0x62}), + + // OpenType font + (FileType.OTF, new byte[] {0x4F, 0x54, 0x54, 0x4F, 0x00}), + + // Ogg Vorbis Codec compressed file + (FileType.OGA, new byte[] {0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00}), + + // Ogg Vorbis Codec compressed file + (FileType.OGG, new byte[] {0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00}), + + // Ogg Vorbis Codec compressed file + (FileType.OGV, new byte[] {0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00}), + + // Ogg Vorbis Codec compressed file + (FileType.OGX, new byte[] {0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00}), + + // Visio-DisplayWrite 4 text file + (FileType.DW4, new byte[] {0x4F, 0x7B}), + + // Quicken QuickFinder Information File + (FileType.IDX, new byte[] {0x50, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00}), + + // Portable Graymap Graphic + (FileType.PGM, new byte[] {0x50, 0x35, 0x0A}), + + // Quake archive file + (FileType.PAK, new byte[] {0x50, 0x41, 0x43, 0x4B}), + + // Windows memory dump + (FileType.DMP, new byte[] {0x50, 0x41, 0x47, 0x45, 0x44, 0x55}), + + // PAX password protected bitmap + (FileType.PAX, new byte[] {0x50, 0x41, 0x58}), + + // PestPatrol data-scan strings + (FileType.DAT, new byte[] {0x50, 0x45, 0x53, 0x54}), + + // PGP disk image + (FileType.PGD, new byte[] {0x50, 0x47, 0x50, 0x64, 0x4D, 0x41, 0x49, 0x4E}), + + // ChromaGraph Graphics Card Bitmap + (FileType.IMG, new byte[] {0x50, 0x49, 0x43, 0x54, 0x00, 0x08}), + + // PKZIP archive_1 + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Android package + (FileType.APK, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // MacOS X Dashboard Widget + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // MS Office Open XML Format Document + (FileType.DOCX, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // MS Office Open XML Format Document + (FileType.PPTX, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // MS Office Open XML Format Document + (FileType.XLSX, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Java archive_1 + (FileType.JAR, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Google Earth session file + (FileType.KMZ, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // KWord document + (FileType.KWD, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenDocument template + (FileType.ODT, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenDocument template + (FileType.ODP, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenDocument template + (FileType.OTT, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Microsoft Open XML paper specification + (FileType.OXPS, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenOffice documents + (FileType.SXC, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenOffice documents + (FileType.SXD, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenOffice documents + (FileType.SXI, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // OpenOffice documents + (FileType.SXW, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // StarOffice spreadsheet + (FileType.SXC, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Windows Media compressed skin file + (FileType.WMZ, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Mozilla Browser Archive + (FileType.XPI, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // XML paper specification file + (FileType.XPS, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // eXact Packager Models + (FileType.XPT, new byte[] {0x50, 0x4B, 0x03, 0x04}), + + // Open Publication Structure eBook + (FileType.EPUB, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x0A, 0x00, 0x02, 0x00}), + + // ZLock Pro encrypted ZIP + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x01, 0x00}), + + // MS Office 2007 documents + (FileType.DOCX, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00}), + + // MS Office 2007 documents + (FileType.PPTX, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00}), + + // MS Office 2007 documents + (FileType.XLSX, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00}), + + // Java archive_2 + (FileType.JAR, new byte[] {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00}), + + // PKZIP archive_2 + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x05, 0x06}), + + // PKZIP archive_3 + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x07, 0x08}), + + // PKLITE archive + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45}), + + // PKSFX self-extracting archive + (FileType.ZIP, new byte[] {0x50, 0x4B, 0x53, 0x70, 0x58}), + + // Windows Program Manager group file + (FileType.GRP, new byte[] {0x50, 0x4D, 0x43, 0x43}), + + // Norton Disk Doctor undo file + (FileType.DAT, new byte[] {0x50, 0x4E, 0x43, 0x49, 0x55, 0x4E, 0x44, 0x4F}), + + // Microsoft Windows User State Migration Tool + (FileType.PMOCCMOC, new byte[] {0x50, 0x4D, 0x4F, 0x43, 0x43, 0x4D, 0x4F, 0x43}), + + // Dreamcast Sound Format + (FileType.DSF, new byte[] {0x50, 0x53, 0x46, 0x12}), + + // Puffer encrypted archive + (FileType.PUF, new byte[] {0x50, 0x55, 0x46, 0x58}), + + // Quicken data + (FileType.QEL, new byte[] {0x51, 0x45, 0x4C, 0x20}), + + // Qcow Disk Image + (FileType.QEMU, new byte[] {0x51, 0x46, 0x49}), + + // RIFF Qualcomm PureVoice + (FileType.QCP, new byte[] {0x51, 0x4C, 0x43, 0x4D, 0x66, 0x6D, 0x74, 0x20}), + + // Quicken data file + (FileType.ABD, new byte[] {0x51, 0x57, 0x20, 0x56, 0x65, 0x72, 0x2E, 0x20}), + + // Quicken data file + (FileType.QSD, new byte[] {0x51, 0x57, 0x20, 0x56, 0x65, 0x72, 0x2E, 0x20}), + + // Outlook-Exchange message subheader + (FileType.MSG, new byte[] {0x52, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x72, 0x00, 0x79, 0x00}), + + // Shareaza (P2P) thumbnail + (FileType.DAT, new byte[] {0x52, 0x41, 0x5A, 0x41, 0x54, 0x44, 0x42, 0x31}), + + // R saved work space + (FileType.RDATA, new byte[] {0x52, 0x44, 0x58, 0x32, 0x0A}), + + // WinNT Registry-Registry Undo files + (FileType.REG, new byte[] {0x52, 0x45, 0x47, 0x45, 0x44, 0x49, 0x54}), + + // WinNT Registry-Registry Undo files + (FileType.SUD, new byte[] {0x52, 0x45, 0x47, 0x45, 0x44, 0x49, 0x54}), + + // Antenna data file + (FileType.AD, new byte[] {0x52, 0x45, 0x56, 0x4E, 0x55, 0x4D, 0x3A, 0x2C}), + + // Windows animated cursor + (FileType.ANI, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Corel Presentation Exchange metadata + (FileType.CMX, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // CorelDraw document + (FileType.CDR, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Video CD MPEG movie + (FileType.DAT, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Micrografx Designer graphic + (FileType.DS4, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // 4X Movie video + (FileType._4XM, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.AVI, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.CDA, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.QCP, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.RMI, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.WAV, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // Resource Interchange File Format + (FileType.WEBP, new byte[] {0x52, 0x49, 0x46, 0x46}), + + // RIFF Windows MIDI + (FileType.RMI, new byte[] {0x52, 0x4D, 0x49, 0x44, 0x64, 0x61, 0x74, 0x61}), + + // WinNT Netmon capture file + (FileType.CAP, new byte[] {0x52, 0x54, 0x53, 0x53}), + + // WinRAR compressed archive + (FileType.RAR, new byte[] {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00}), + + // Generic e-mail_1 + (FileType.EML, new byte[] {0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x2D, 0x50}), + + // Windows prefetch + (FileType.PF, new byte[] {0x53, 0x43, 0x43, 0x41}), + + // Underground Audio + (FileType.AST, new byte[] {0x53, 0x43, 0x48, 0x6C}), + + // Img Software Bitmap + (FileType.IMG, new byte[] {0x53, 0x43, 0x4D, 0x49}), + + // SMPTE DPX (big endian) + (FileType.SDPX, new byte[] {0x53, 0x44, 0x50, 0x58}), + + // Harvard Graphics presentation + (FileType.SHW, new byte[] {0x53, 0x48, 0x4F, 0x57}), + + // Sietronics CPI XRD document + (FileType.CPI, new byte[] {0x53, 0x49, 0x45, 0x54, 0x52, 0x4F, 0x4E, 0x49}), + + // Flexible Image Transport System (FITS) file + (FileType.FITS, new byte[] {0x53, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x20, 0x20, 0x3D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54}), + + // StuffIt archive + (FileType.SIT, new byte[] {0x53, 0x49, 0x54, 0x21, 0x00}), + + // SmartDraw Drawing file + (FileType.SDR, new byte[] {0x53, 0x4D, 0x41, 0x52, 0x54, 0x44, 0x52, 0x57}), + + // StorageCraft ShadownProtect backup file + (FileType.SPF, new byte[] {0x53, 0x50, 0x46, 0x49, 0x00}), + + // MultiBit Bitcoin blockchain file + (FileType.SPVB, new byte[] {0x53, 0x50, 0x56, 0x42}), + + // SQLite database file + (FileType.DB, new byte[] {0x53, 0x51, 0x4C, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x20, 0x33, 0x00}), + + // DB2 conversion file + (FileType.CNV, new byte[] {0x53, 0x51, 0x4C, 0x4F, 0x43, 0x4F, 0x4E, 0x56}), + + // StuffIt compressed archive + (FileType.SIT, new byte[] {0x53, 0x74, 0x75, 0x66, 0x66, 0x49, 0x74, 0x20}), + + // SuperCalc worksheet + (FileType.CAL, new byte[] {0x53, 0x75, 0x70, 0x65, 0x72, 0x43, 0x61, 0x6C}), + + // Wii-GameCube + (FileType.THP, new byte[] {0x54, 0x48, 0x50, 0x00}), + + // GNU Info Reader file + (FileType.INFO, new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20}), + + // Unicode extensions + (FileType.UCE, new byte[] {0x55, 0x43, 0x45, 0x58}), + + // UFA compressed archive + (FileType.UFA, new byte[] {0x55, 0x46, 0x41, 0xC6, 0xD2, 0xC1}), + + // UFO Capture map file + (FileType.DAT, new byte[] {0x55, 0x46, 0x4F, 0x4F, 0x72, 0x62, 0x69, 0x74}), + + // Visual C PreCompiled header + (FileType.PCH, new byte[] {0x56, 0x43, 0x50, 0x43, 0x48, 0x30}), + + // Visual Basic User-defined Control file + (FileType.CTL, new byte[] {0x56, 0x45, 0x52, 0x53, 0x49, 0x4F, 0x4E, 0x20}), + + // MapInfo Interchange Format file + (FileType.MIF, new byte[] {0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20}), + + // SPSS template + (FileType.SCT, new byte[] {0x57, 0x04, 0x00, 0x00, 0x53, 0x50, 0x53, 0x53, 0x20, 0x74, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74}), + + // RIFF Windows Audio + (FileType.WAV, new byte[] {0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20}), + + // RIFF WebP + (FileType.WEBP, new byte[] {0x57, 0x45, 0x42, 0x50}), + + // Walkman MP3 file + (FileType.DAT, new byte[] {0x57, 0x4D, 0x4D, 0x50}), + + // WordStar for Windows file + (FileType.WS2, new byte[] {0x57, 0x53, 0x32, 0x30, 0x30, 0x30}), + + // WinZip compressed archive + (FileType.ZIP, new byte[] {0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70}), + + // Lotus WordPro file + (FileType.LWP, new byte[] {0x57, 0x6F, 0x72, 0x64, 0x50, 0x72, 0x6F}), + + // Exchange e-mail + (FileType.EML, new byte[] {0x58, 0x2D}), + + // Packet sniffer files + (FileType.CAP, new byte[] {0x58, 0x43, 0x50, 0x00}), + + // XPCOM libraries + (FileType.XPT, new byte[] {0x58, 0x50, 0x43, 0x4F, 0x4D, 0x0A, 0x54, 0x79}), + + // SMPTE DPX file (little endian) + (FileType.DPX, new byte[] {0x58, 0x50, 0x44, 0x53}), + + // MS Publisher + (FileType.BDR, new byte[] {0x58, 0x54}), + + // ZOO compressed archive + (FileType.ZOO, new byte[] {0x5A, 0x4F, 0x4F, 0x20}), + + // Macromedia Shockwave Flash + (FileType.SWF, new byte[] {0x5A, 0x57, 0x53}), + + // MS Exchange configuration file + (FileType.ECF, new byte[] {0x5B, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x6C}), + + // Visual C++ Workbench Info File + (FileType.VCW, new byte[] {0x5B, 0x4D, 0x53, 0x56, 0x43}), + + // Dial-up networking file + (FileType.DUN, new byte[] {0x5B, 0x50, 0x68, 0x6F, 0x6E, 0x65, 0x5D}), + + // Lotus AMI Pro document_1 + (FileType.SAM, new byte[] {0x5B, 0x56, 0x45, 0x52, 0x5D}), + + // VocalTec VoIP media file + (FileType.VMD, new byte[] {0x5B, 0x56, 0x4D, 0x44, 0x5D}), + + // Microsoft Code Page Translation file + (FileType.CPX, new byte[] {0x5B, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73}), + + // Flight Simulator Aircraft Configuration + (FileType.CFG, new byte[] {0x5B, 0x66, 0x6C, 0x74, 0x73, 0x69, 0x6D, 0x2E}), + + // WinAmp Playlist + (FileType.PLS, new byte[] {0x5B, 0x70, 0x6C, 0x61, 0x79, 0x6C, 0x69, 0x73, 0x74, 0x5D}), + + // Lotus AMI Pro document_2 + (FileType.SAM, new byte[] {0x5B, 0x76, 0x65, 0x72, 0x5D}), + + // Husqvarna Designer + (FileType.HUS, new byte[] {0x5D, 0xFC, 0xC8, 0x00}), + + // Jar archive + (FileType.JAR, new byte[] {0x5F, 0x27, 0xA8, 0x89}), + + // EnCase case file + (FileType.CAS, new byte[] {0x5F, 0x43, 0x41, 0x53, 0x45, 0x5F}), + + // EnCase case file + (FileType.CBK, new byte[] {0x5F, 0x43, 0x41, 0x53, 0x45, 0x5F}), + + // Compressed archive file + (FileType.ARJ, new byte[] {0x60, 0xEA}), + + // UUencoded BASE64 file + (FileType.b64, new byte[] {0x62, 0x65, 0x67, 0x69, 0x6E, 0x2D, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34}), + + // Apple Core Audio File + (FileType.CAF, new byte[] {0x63, 0x61, 0x66, 0x66}), + + // Macintosh encrypted Disk image (v1) + (FileType.DMG, new byte[] {0x63, 0x64, 0x73, 0x61, 0x65, 0x6E, 0x63, 0x72}), + + // Virtual PC HD image + (FileType.VHD, new byte[] {0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78}), + + // Photoshop Custom Shape + (FileType.CSH, new byte[] {0x63, 0x75, 0x73, 0x68, 0x00, 0x00, 0x00, 0x02}), + + // Intel PROset-Wireless Profile + (FileType.P10, new byte[] {0x64, 0x00, 0x00, 0x00}), + + // Torrent file + (FileType.TORRENT, new byte[] {0x64, 0x38, 0x3A, 0x61, 0x6E, 0x6E, 0x6F, 0x75, 0x6E, 0x63, 0x65}), + + // Dalvik (Android) executable file + (FileType.dex, new byte[] {0x64, 0x65, 0x78, 0x0A}), + + // Audacity audio file + (FileType.AU, new byte[] {0x64, 0x6E, 0x73, 0x2E}), + + // MS Visual Studio workspace file + (FileType.DSW, new byte[] {0x64, 0x73, 0x77, 0x66, 0x69, 0x6C, 0x65}), + + // Macintosh encrypted Disk image (v2) + (FileType.DMG, new byte[] {0x65, 0x6E, 0x63, 0x72, 0x63, 0x64, 0x73, 0x61}), + + // WinNT printer spool file + (FileType.SHD, new byte[] {0x66, 0x49, 0x00, 0x00}), + + // Free Lossless Audio Codec file + (FileType.FLAC, new byte[] {0x66, 0x4C, 0x61, 0x43, 0x00, 0x00, 0x00, 0x22}), + + // MPEG-4 video file_1 + (FileType.MP4, new byte[] {0x66, 0x74, 0x79, 0x70, 0x33, 0x67, 0x70, 0x35}), + + // Apple Lossless Audio Codec file + (FileType.M4A, new byte[] {0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41, 0x20}), + + // ISO Media-MPEG v4-iTunes AVC-LC + (FileType.FLV, new byte[] {0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56, 0x20}), + + // ISO Media-MPEG v4-iTunes AVC-LC + (FileType.M4V, new byte[] {0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56, 0x20}), + + // MPEG-4 video file_2 + (FileType.MP4, new byte[] {0x66, 0x74, 0x79, 0x70, 0x4D, 0x53, 0x4E, 0x56}), + + // ISO Base Media file (MPEG-4) v1 + (FileType.MP4, new byte[] {0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D}), + + // MPEG-4 video-QuickTime file + (FileType.M4V, new byte[] {0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32}), + + // QuickTime movie_7 + (FileType.MOV, new byte[] {0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20}), + + // Win2000-XP printer spool file + (FileType.SHD, new byte[] {0x67, 0x49, 0x00, 0x00}), + + // GIMP file + (FileType.XCF, new byte[] {0x67, 0x69, 0x6d, 0x70, 0x20, 0x78, 0x63, 0x66}), + + // Win Server 2003 printer spool file + (FileType.SHD, new byte[] {0x68, 0x49, 0x00, 0x00}), + + // Skype user data file + (FileType.DBB, new byte[] {0x6C, 0x33, 0x33, 0x6C}), + + // QuickTime movie_1 + (FileType.MOV, new byte[] {0x6D, 0x6F, 0x6F, 0x76}), + + // QuickTime movie_2 + (FileType.MOV, new byte[] {0x66, 0x72, 0x65, 0x65}), + + // QuickTime movie_3 + (FileType.MOV, new byte[] {0x6D, 0x64, 0x61, 0x74}), + + // QuickTime movie_4 + (FileType.MOV, new byte[] {0x77, 0x69, 0x64, 0x65}), + + // QuickTime movie_5 + (FileType.MOV, new byte[] {0x70, 0x6E, 0x6F, 0x74}), + + // QuickTime movie_6 + (FileType.MOV, new byte[] {0x73, 0x6B, 0x69, 0x70}), + + // Internet Explorer v11 Tracking Protection List + (FileType.TPL, new byte[] {0x6D, 0x73, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x4C, 0x69, 0x73, 0x74}), + + // MultiBit Bitcoin wallet information + (FileType.INFO, new byte[] {0x6D, 0x75, 0x6C, 0x74, 0x69, 0x42, 0x69, 0x74, 0x2E, 0x69, 0x6E, 0x66, 0x6F}), + + // WinNT registry file + (FileType.DAT, new byte[] {0x72, 0x65, 0x67, 0x66}), + + // Sonic Foundry Acid Music File + (FileType.AC, new byte[] {0x72, 0x69, 0x66, 0x66}), + + // RealMedia metafile + (FileType.RAM, new byte[] {0x72, 0x74, 0x73, 0x70, 0x3A, 0x2F, 0x2F}), + + // Allegro Generic Packfile (compressed) + (FileType.DAT, new byte[] {0x73, 0x6C, 0x68, 0x21}), + + // Allegro Generic Packfile (uncompressed) + (FileType.DAT, new byte[] {0x73, 0x6C, 0x68, 0x2E}), + + // PalmOS SuperMemo + (FileType.PDB, new byte[] {0x73, 0x6D, 0x5F}), + + // STL (STereoLithography) file + (FileType.STL, new byte[] {0x73, 0x6F, 0x6C, 0x69, 0x64}), + + // CALS raster bitmap + (FileType.CAL, new byte[] {0x73, 0x72, 0x63, 0x64, 0x6F, 0x63, 0x69, 0x64}), + + // PowerBASIC Debugger Symbols + (FileType.PDB, new byte[] {0x73, 0x7A, 0x65, 0x7A}), + + // PathWay Map file + (FileType.PRC, new byte[] {0x74, 0x42, 0x4D, 0x50, 0x4B, 0x6E, 0x57, 0x72}), + + // TrueType font + (FileType.TTF, new byte[] {0x74, 0x72, 0x75, 0x65, 0x00}), + + // Tape Archive + (FileType.TAR, new byte[] {0x75, 0x73, 0x74, 0x61, 0x72}), + + // OpenEXR bitmap image + (FileType.EXR, new byte[] {0x76, 0x2F, 0x31, 0x01}), + + // Qimage filter + (FileType.FLT, new byte[] {0x76, 0x32, 0x30, 0x30, 0x33, 0x2E, 0x31, 0x30}), + + // MacOS X image file + (FileType.DMG, new byte[] {0x78, 0x01, 0x73, 0x0D, 0x62, 0x62, 0x60}), + + // eXtensible ARchive file + (FileType.XAR, new byte[] {0x78, 0x61, 0x72, 0x21}), + + // ZoomBrowser Image Index + (FileType.INFO, new byte[] {0x7A, 0x62, 0x65, 0x78}), + + // Windows application log + (FileType.LGC, new byte[] {0x7B, 0x0D, 0x0A, 0x6F, 0x20}), + + // Windows application log + (FileType.LGD, new byte[] {0x7B, 0x0D, 0x0A, 0x6F, 0x20}), + + // MS WinMobile personal note + (FileType.PWI, new byte[] {0x7B, 0x5C, 0x70, 0x77, 0x69}), + + // Rich Text Format + (FileType.RTF, new byte[] {0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31}), + + // Corel Paint Shop Pro image + (FileType.PSP, new byte[] {0x7E, 0x42, 0x4B, 0x00}), + + // Easy Street Draw diagram file + (FileType.ESD, new byte[] {0x7E, 0x45, 0x53, 0x44, 0x77, 0xF6, 0x85, 0x3E, 0xBF, 0x6A, 0xD2, 0x11, 0x45, 0x61, 0x73, 0x79, 0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x20, 0x44, 0x72, 0x61, 0x77}), + + // Digital Watchdog DW-TP-500G audio + (FileType.IMG, new byte[] {0x7E, 0x74, 0x2C, 0x01, 0x50, 0x70, 0x02, 0x4D, 0x52}), + + // Relocatable object code + (FileType.OBJ, new byte[] {0x80}), + + // Dreamcast audio + (FileType.ADX, new byte[] {0x80, 0x00, 0x00, 0x20, 0x03, 0x12, 0x04}), + + // Kodak Cineon image + (FileType.CIN, new byte[] {0x80, 0x2A, 0x5F, 0xD7}), + + // Outlook Express address book (Win95) + (FileType.WAB, new byte[] {0x81, 0x32, 0x84, 0xC1, 0x85, 0x05, 0xD0, 0x11}), + + // WordPerfect text + (FileType.WPF, new byte[] {0x81, 0xCD, 0xAB}), + + // PNG image + (FileType.PNG, new byte[] {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}), + + // MS Answer Wizard + (FileType.AW, new byte[] {0x8A, 0x01, 0x09, 0x00, 0x00, 0x00, 0xE1, 0x08}), + + // Hamarsoft compressed archive + (FileType.HAP, new byte[] {0x91, 0x33, 0x48, 0x46}), + + // PGP secret keyring_1 + (FileType.SKR, new byte[] {0x95, 0x00}), + + // PGP secret keyring_2 + (FileType.SKR, new byte[] {0x95, 0x01}), + + // JBOG2 image file + (FileType.JB2, new byte[] {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A}), + + // GPG public keyring + (FileType.GPG, new byte[] {0x99}), + + // PGP public keyring + (FileType.PKR, new byte[] {0x99, 0x01}), + + // Outlook address file + (FileType.WAB, new byte[] {0x9C, 0xCB, 0xCB, 0x8D, 0x13, 0x75, 0xD2, 0x11}), + + // Access Data FTK evidence + (FileType.DAT, new byte[] {0xA9, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), + + // Quicken data + (FileType.QDF, new byte[] {0xAC, 0x9E, 0xBD, 0x8F, 0x00, 0x00}), + + // PowerPoint presentation subheader_3 + (FileType.PPT, new byte[] {0xA0, 0x46, 0x1D, 0xF0}), + + // BGBlitz position database file + (FileType.PDB, new byte[] {0xAC, 0xED, 0x00, 0x05, 0x73, 0x72, 0x00, 0x12}), + + // Win95 password file + (FileType.PWL, new byte[] {0xB0, 0x4D, 0x46, 0x43}), + + // PCX bitmap + (FileType.DCX, new byte[] {0xB1, 0x68, 0xDE, 0x3A}), + + // Acronis True Image_1 + (FileType.TIB, new byte[] {0xB4, 0x6E, 0x68, 0x44}), + + // Windows calendar + (FileType.CAL, new byte[] {0xB5, 0xA2, 0xB0, 0xB3, 0xB3, 0xB0, 0xA5, 0xB5}), + + // InstallShield Script + (FileType.INS, new byte[] {0xB8, 0xC9, 0x0C, 0x00}), + + // MS Write file_3 + (FileType.WRI, new byte[] {0xBE, 0x00, 0x00, 0x00, 0xAB}), + + // Palm Desktop DateBook + (FileType.DAT, new byte[] {0xBE, 0xBA, 0xFE, 0xCA, 0x0F, 0x50, 0x61, 0x6C, 0x6D, 0x53, 0x47, 0x20, 0x44, 0x61, 0x74, 0x61}), + + // MS Agent Character file + (FileType.ACS, new byte[] {0xC3, 0xAB, 0xCD, 0xAB}), + + // Adobe encapsulated PostScript + (FileType.EPS, new byte[] {0xC5, 0xD0, 0xD3, 0xC6}), + + // Jeppesen FliteLog file + (FileType.LBK, new byte[] {0xC8, 0x00, 0x79, 0x00}), + + // Java bytecode + (FileType.CLASS, new byte[] {0xCA, 0xFE, 0xBA, 0xBE}), + + // Acronis True Image_2 + (FileType.TIB, new byte[] {0xCE, 0x24, 0xB9, 0xA2, 0x20, 0x00, 0x00, 0x00}), + + // Java Cryptography Extension keystore + (FileType.JCEKS, new byte[] {0xCE, 0xCE, 0xCE, 0xCE}), + + // Perfect Office document + (FileType.DOC, new byte[] {0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00}), + + // Outlook Express e-mail folder + (FileType.DBX, new byte[] {0xCF, 0xAD, 0x12, 0xFE}), + + // Microsoft Office document + (FileType.DOC, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.DOT, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.PPS, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.PPT, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.XLA, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.XLS, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Office document + (FileType.WIZ, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // CaseWare Working Papers + (FileType.AC_, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Access project file + (FileType.ADP, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Lotus-IBM Approach 97 file + (FileType.APR, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // MSWorks database file + (FileType.DB, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Common Console Document + (FileType.MSC, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Installer package + (FileType.MSI, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Microsoft Installer Patch + (FileType.MSP, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Minitab data file + (FileType.MTW, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // ArcMap GIS project file + (FileType.MXD, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Developer Studio File Options file + (FileType.OPT, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // MS Publisher file + (FileType.PUB, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Revit Project file + (FileType.RVT, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Visual Studio Solution User Options file + (FileType.SOU, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // SPSS output file + (FileType.SPO, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // Visio file + (FileType.VSD, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // MSWorks text document + (FileType.WPS, new byte[] {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}), + + // WinPharoah filter file + (FileType.FTR, new byte[] {0xD2, 0x0A, 0x00, 0x00}), + + // AOL history|typed URL files + (FileType.ARL, new byte[] {0xD4, 0x2A}), + + // AOL history|typed URL files + (FileType.AUT, new byte[] {0xD4, 0x2A}), + + // Windows graphics metafile + (FileType.WMF, new byte[] {0xD7, 0xCD, 0xC6, 0x9A}), + + // Word 2.0 file + (FileType.DOC, new byte[] {0xDB, 0xA5, 0x2D, 0x00}), + + // Corel color palette + (FileType.CPL, new byte[] {0xDC, 0xDC}), + + // eFax file + (FileType.EFX, new byte[] {0xDC, 0xFE}), + + // Amiga icon + (FileType.INFO, new byte[] {0xE3, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}), + + // Win98 password file + (FileType.PWL, new byte[] {0xE3, 0x82, 0x85, 0x96}), + + // MS OneNote note + (FileType.ONE, new byte[] {0xE4, 0x52, 0x5C, 0x7B, 0x8C, 0xD8, 0xA7, 0x4D}), + + // Windows executable file_1 + (FileType.COM, new byte[] {0xE8}), + + // Windows executable file_1 + (FileType.SYS, new byte[] {0xE8}), + + // Windows executable file_2 + (FileType.COM, new byte[] {0xE9}), + + // Windows executable file_2 + (FileType.SYS, new byte[] {0xE9}), + + // Windows executable file_3 + (FileType.COM, new byte[] {0xEB}), + + // Windows executable file_3 + (FileType.SYS, new byte[] {0xEB}), + + // GEM Raster file + (FileType.IMG, new byte[] {0xEB, 0x3C, 0x90, 0x2A}), + + // Word document subheader + (FileType.DOC, new byte[] {0xEC, 0xA5, 0xC1, 0x00}), + + // RedHat Package Manager + (FileType.RPM, new byte[] {0xED, 0xAB, 0xEE, 0xDB}), + + // Windows Script Component (UTF-8)_1 + (FileType.WSF, new byte[] {0xEF, 0xBB, 0xBF, 0x3C}), + + // Windows Script Component (UTF-8)_2 + (FileType.WSC, new byte[] {0xEF, 0xBB, 0xBF, 0x3C, 0x3F}), + + // Bitcoin-Qt blockchain block file + (FileType.DAT, new byte[] {0xF9, 0xBE, 0xB4, 0xD9}), + + // XZ archive + (FileType.XZ, new byte[] {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}), + + // MS Publisher subheader + (FileType.PUB, new byte[] {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}), + + // Thumbs.db subheader + (FileType.DB, new byte[] {0xFD, 0xFF, 0xFF, 0xFF}), + + // MS Publisher file subheader + (FileType.PUB, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x02}), + + // Visual Studio Solution subheader + (FileType.SUO, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x04}), + + // PowerPoint presentation subheader_4 + (FileType.PPT, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00, 0x00}), + + // Excel spreadsheet subheader_2 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x10}), + + // PowerPoint presentation subheader_5 + (FileType.PPT, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x1C, 0x00, 0x00, 0x00}), + + // Excel spreadsheet subheader_3 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x1F}), + + // Developer Studio subheader + (FileType.OPT, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x20}), + + // Excel spreadsheet subheader_4 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x22}), + + // Excel spreadsheet subheader_5 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x23}), + + // Excel spreadsheet subheader_6 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x28}), + + // Excel spreadsheet subheader_7 + (FileType.XLS, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x29}), + + // PowerPoint presentation subheader_6 + (FileType.PPT, new byte[] {0xFD, 0xFF, 0xFF, 0xFF, 0x43, 0x00, 0x00, 0x00}), + + // Symantex Ghost image file + (FileType.GHO, new byte[] {0xFE, 0xEF}), + + // Symantex Ghost image file + (FileType.GHS, new byte[] {0xFE, 0xEF}), + + // Windows executable + (FileType.SYS, new byte[] {0xFF}), + + // Works for Windows spreadsheet + (FileType.WKS, new byte[] {0xFF, 0x00, 0x02, 0x00, 0x04, 0x04, 0x05, 0x54}), + + // QuickReport Report + (FileType.QRP, new byte[] {0xFF, 0x0A, 0x00}), + + // Windows international code page + (FileType.CPI, new byte[] {0xFF, 0x46, 0x4F, 0x4E, 0x54}), + + // Keyboard driver file + (FileType.SYS, new byte[] {0xFF, 0x4B, 0x45, 0x59, 0x42, 0x20, 0x20, 0x20}), + + // WordPerfect text and graphics + (FileType.WP, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // WordPerfect text and graphics + (FileType.WPD, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // WordPerfect text and graphics + (FileType.WPG, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // WordPerfect text and graphics + (FileType.WPP, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // WordPerfect text and graphics + (FileType.WP5, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // WordPerfect text and graphics + (FileType.WP6, new byte[] {0xFF, 0x57, 0x50, 0x43}), + + // JPEG-EXIF-SPIFF images + (FileType.JFIF, new byte[] {0xFF, 0xD8, 0xFF}), + + // JPEG-EXIF-SPIFF images + (FileType.JPE, new byte[] {0xFF, 0xD8, 0xFF}), + + // JPEG-EXIF-SPIFF images + (FileType.JPEG, new byte[] {0xFF, 0xD8, 0xFF}), + + // JPEG-EXIF-SPIFF images + (FileType.JPG, new byte[] {0xFF, 0xD8, 0xFF}), + + // MPEG-4 AAC audio + (FileType.AAC, new byte[] {0xFF, 0xF1}), + + // MPEG-2 AAC audio + (FileType.AAC, new byte[] {0xFF, 0xF9}), + + // Windows Registry file + (FileType.REG, new byte[] {0xFF, 0xFE}), + + // MSinfo file + (FileType.MOF, new byte[] {0xFF, 0xFE, 0x23, 0x00, 0x6C, 0x00, 0x69, 0x00}), + + // DOS system driver + (FileType.SYS, new byte[] {0xFF, 0xFF, 0xFF, 0xFF}), + + + };}} \ No newline at end of file diff --git a/Wabbajack.Common/FileSignatures/Signatures.tt b/Wabbajack.Common/FileSignatures/Signatures.tt new file mode 100644 index 00000000..5849108b --- /dev/null +++ b/Wabbajack.Common/FileSignatures/Signatures.tt @@ -0,0 +1,53 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Linq" #> + +<# + + byte[] StringToByteArray(string hex) { + return Enumerable.Range(0, hex.Length) + .Where(x => x % 2 == 0) + .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) + .ToArray(); + } + + var files = new string[] {"bsasigs.txt", "file_sigs_RAW.txt"}; + var digits = new HashSet("0123456789".ToArray()); + var rows = files + .SelectMany(file => File.ReadAllLines(Path.Combine("./Definitions/", file))) + .Select(row => row.Split(',')) + .SelectMany(row => row[2].Split('|').Select(e => new + { + EnumName = (digits.Contains(e.First()) ? "_" + e : e).Replace(".", ""), + Sig = row[1].Trim().Split(' ').Select(b => "0x"+b), + Description = row[0] + })); + #> +namespace Wabbajack.Common.FileSignatures { + public static class Definitions { + public enum FileType { <# + + foreach (var nrow in rows.Select(r => r.EnumName).Distinct().OrderBy(r => r)) { + #> + <#= nrow #>, + <#} #> + } + + public static (FileType, byte[])[] Signatures = { + <# + foreach (var row in rows) + { + #> + // <#= row.Description #> + (FileType.<#=row.EnumName #>, new byte[] {<#= string.Join(", ", row.Sig)#>}), + + <# + + } + +#> + + };}} \ No newline at end of file diff --git a/Wabbajack.Common/Wabbajack.Common.csproj b/Wabbajack.Common/Wabbajack.Common.csproj index 812548c3..ea60d498 100644 --- a/Wabbajack.Common/Wabbajack.Common.csproj +++ b/Wabbajack.Common/Wabbajack.Common.csproj @@ -34,6 +34,10 @@ TextTemplatingFileGenerator PrimitiveHandlers.cs + + TextTemplatingFileGenerator + Signatures.cs + @@ -60,5 +64,10 @@ PrimitiveHandlers.tt + + True + True + Signatures.tt + \ No newline at end of file diff --git a/Wabbajack.Lib/AInstaller.cs b/Wabbajack.Lib/AInstaller.cs index 9c596c87..2a0a2da4 100644 --- a/Wabbajack.Lib/AInstaller.cs +++ b/Wabbajack.Lib/AInstaller.cs @@ -224,6 +224,14 @@ namespace Wabbajack.Lib { Utils.Log($"NOTE: Invalid Hash for {toPatch.To} after patching {hash} vs {toPatch.Hash}"); } + + if (await VirusScanner.ShouldScan(toFile) && + await ClientAPI.GetVirusScanResult(toFile) == VirusScanner.Result.Malware) + { + await toFile.DeleteAsync(); + Utils.ErrorThrow(new Exception($"Virus scan of patched executable reported possible malware: {toFile.ToString()} ({(long)hash})")); + } + }); } diff --git a/Wabbajack.Lib/ClientAPI.cs b/Wabbajack.Lib/ClientAPI.cs index cd94f577..f1aaf7a3 100644 --- a/Wabbajack.Lib/ClientAPI.cs +++ b/Wabbajack.Lib/ClientAPI.cs @@ -5,7 +5,8 @@ using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; -using Wabbajack.Common; + using Org.BouncyCastle.Crypto.Agreement.Srp; + using Wabbajack.Common; using Wabbajack.Common.Exceptions; using Wabbajack.Common.Serialization.Json; using Wabbajack.Lib.Downloaders; @@ -146,5 +147,33 @@ using Wabbajack.Lib.Downloaders; var results = await client.GetJsonAsync($"{Consts.WabbajackBuildServerUri}mod_upgrade/find/{src.ToHex()}"); return results; } + + public static async Task GetVirusScanResult(AbsolutePath path) + { + var client = await GetClient(); + Utils.Log($"Checking virus result for {path}"); + + var hash = await path.FileHashAsync(); + + using var result = await client.GetAsync($"{Consts.WabbajackBuildServerUri}virus_scan/{hash.ToHex()}", errorsAsExceptions: false); + if (result.StatusCode == HttpStatusCode.OK) + { + var data = await result.Content.ReadAsStringAsync(); + return Enum.Parse(data); + } + + if (result.StatusCode == HttpStatusCode.NotFound) + { + await using var input = await path.OpenRead(); + using var postResult = await client.PostAsync($"{Consts.WabbajackBuildServerUri}virus_scan", errorsAsExceptions: false, content: new StreamContent(input)); + if (postResult.StatusCode == HttpStatusCode.OK) + { + var data = await postResult.Content.ReadAsStringAsync(); + return Enum.Parse(data); + } + throw new HttpException(result); + } + throw new HttpException(result); + } } } diff --git a/Wabbajack.Lib/CompilationSteps/IncludePatches.cs b/Wabbajack.Lib/CompilationSteps/IncludePatches.cs index 3c32b0bb..eeaddaf0 100644 --- a/Wabbajack.Lib/CompilationSteps/IncludePatches.cs +++ b/Wabbajack.Lib/CompilationSteps/IncludePatches.cs @@ -114,6 +114,14 @@ namespace Wabbajack.Lib.CompilationSteps e.Choices = found; } + if (source.File.IsNative && await VirusScanner.ShouldScan(source.File.AbsoluteName)) + { + if (await ClientAPI.GetVirusScanResult(source.File.AbsoluteName) == VirusScanner.Result.Malware) + { + Utils.ErrorThrow(new Exception($"Executable file {source.File.AbsoluteName} ({source.File}) has been marked as malware.")); + } + } + return e; } diff --git a/Wabbajack.Lib/VirusScanner.cs b/Wabbajack.Lib/VirusScanner.cs index d5de9273..de9845ac 100644 --- a/Wabbajack.Lib/VirusScanner.cs +++ b/Wabbajack.Lib/VirusScanner.cs @@ -1,6 +1,9 @@ using System.IO; +using System.Threading; using System.Threading.Tasks; +using Org.BouncyCastle.Bcpg; using Wabbajack.Common; +using Wabbajack.Common.FileSignatures; namespace Wabbajack.Lib { @@ -15,24 +18,51 @@ namespace Wabbajack.Lib Malware = 2 } - public static async Task ScanStream(Stream stream) + public static async Task<(Hash, Result)> ScanStream(Stream stream) { - await using var file = new TempFile(); - await file.Path.WriteAllAsync(stream); + var ms = new MemoryStream(); + await stream.CopyToAsync(ms); + ms.Position = 0; - var process = new ProcessHelper() + var hash = await ms.xxHashAsync(); + ms.Position = 0; + + await using var file = new TempFile(); + try + { + await file.Path.WriteAllAsync(ms); + } + catch (IOException ex) + { + // Was caught before we could fully scan the file due to real-time virus scans + if (ex.Message.ToLowerInvariant().Contains("malware")) + { + return (hash, Result.Malware); + } + } + + var process = new ProcessHelper { Path = (AbsolutePath)@"C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2006.10-0\X86\MpCmdRun.exe", Arguments = new object[] {"-Scan", "-ScanType", "3", "-DisableRemediation", "-File", file.Path}, }; - return (Result)await process.Start(); + return (hash, (Result)await process.Start()); } - public static Task ShouldScan(AbsolutePath path) + private static SignatureChecker ExecutableChecker = new SignatureChecker(Definitions.FileType.DLL, + Definitions.FileType.EXE, + Definitions.FileType.PIF, + Definitions.FileType.QXD, + Definitions.FileType.QTX, + Definitions.FileType.DRV, + Definitions.FileType.SYS, + Definitions.FileType.COM); + + public static async Task ShouldScan(AbsolutePath path) { - + return await ExecutableChecker.MatchesAsync(path) != null; } } } diff --git a/Wabbajack.Server.Test/VirusCheckTests.cs b/Wabbajack.Server.Test/VirusCheckTests.cs new file mode 100644 index 00000000..8683b119 --- /dev/null +++ b/Wabbajack.Server.Test/VirusCheckTests.cs @@ -0,0 +1,39 @@ +using System.Net; +using System.Threading.Tasks; +using Wabbajack.BuildServer.Test; +using Wabbajack.Common; +using Wabbajack.Lib; +using Xunit; +using Xunit.Abstractions; +using Wabbajack.Common; + +namespace Wabbajack.Server.Test +{ + public class VirusCheckTests : ABuildServerSystemTest + { + public VirusCheckTests(ITestOutputHelper output, SingletonAdaptor fixture) : base(output, fixture) + { + } + + [Fact] + public async Task CheckVirus() + { + var tmpFile = new TempFile(); + + var meta = Game.SkyrimSpecialEdition.MetaData(); + var srcFile = meta.GameLocation().Combine(meta.MainExecutable!); + + await srcFile.CopyToAsync(tmpFile.Path); + + using (var s = await tmpFile.Path.OpenWrite()) + { + s.Position = 1000; + s.WriteByte(42); + } + + Assert.True(await VirusScanner.ShouldScan(tmpFile.Path)); + + Assert.Equal(VirusScanner.Result.NotMalware, await ClientAPI.GetVirusScanResult(tmpFile.Path)); + } + } +} diff --git a/Wabbajack.Server.Test/sql/wabbajack_db.sql b/Wabbajack.Server.Test/sql/wabbajack_db.sql index dd3de1a0..87ec6831 100644 --- a/Wabbajack.Server.Test/sql/wabbajack_db.sql +++ b/Wabbajack.Server.Test/sql/wabbajack_db.sql @@ -641,6 +641,17 @@ CREATE TABLE [dbo].[NexusKeys]( ) ON [PRIMARY] GO +/****** Object: Table [dbo].[VirusScanResults] Script Date: 7/14/2020 9:30:59 PM ******/ +CREATE TABLE [dbo].[VirusScanResults]( + [Hash] [bigint] NOT NULL, + [IsMalware] [tinyint] NOT NULL, + CONSTRAINT [PK_VirusScanResults] PRIMARY KEY CLUSTERED + ( + [Hash] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY] +GO + /****** Object: StoredProcedure [dbo].[MergeAllFilesInArchive] Script Date: 3/28/2020 4:58:59 PM ******/ SET ANSI_NULLS ON GO diff --git a/Wabbajack.Server/Controllers/VirusScan.cs b/Wabbajack.Server/Controllers/VirusScan.cs new file mode 100644 index 00000000..7b8878cc --- /dev/null +++ b/Wabbajack.Server/Controllers/VirusScan.cs @@ -0,0 +1,49 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Wabbajack.Common; +using Wabbajack.Lib; +using Wabbajack.Server.DataLayer; +using Wabbajack.Server.Services; + +namespace Wabbajack.BuildServer.Controllers +{ + [ApiController] + [Authorize(Roles = "User")] + public class VirusScan : ControllerBase + { + private ILogger _logger; + private SqlService _sql; + + public VirusScan(ILogger logger, SqlService sql) + { + _logger = logger; + _sql = sql; + } + + [HttpPost] + [Route("/virus_scan")] + public async Task CheckFile() + { + var result = await VirusScanner.ScanStream(Request.Body); + await _sql.AddVirusResult(result.Item1, result.Item2); + return Ok(result.Item2.ToString()); + } + + [HttpGet] + [Route("/virus_scan/{hashAsHex}")] + public async Task CheckHash(string hashAsHex) + { + var result = await _sql.FindVirusResult(Hash.FromHex(hashAsHex)); + if (result == null) + { + return NotFound(); + } + + return Ok(result.ToString()); + } + + } +} diff --git a/Wabbajack.Server/DataLayer/VirusScanResults.cs b/Wabbajack.Server/DataLayer/VirusScanResults.cs new file mode 100644 index 00000000..bd23c476 --- /dev/null +++ b/Wabbajack.Server/DataLayer/VirusScanResults.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Dapper; +using Wabbajack.Common; +using Wabbajack.Lib; + +namespace Wabbajack.Server.DataLayer +{ + public partial class SqlService + { + public async Task FindVirusResult(Hash hash) + { + await using var conn = await Open(); + var results = await conn.QueryFirstOrDefaultAsync<(Hash, bool)>( + @"SELECT Hash, IsMalware FROM dbo.VirusScanResults WHERE Hash = @Hash", + new {Hash = hash}); + if (results == default) + return null; + return results.Item2 ? VirusScanner.Result.Malware : VirusScanner.Result.NotMalware; + } + + public async Task AddVirusResult(Hash hash, VirusScanner.Result result) + { + await using var conn = await Open(); + try + { + var results = await conn.QueryFirstOrDefaultAsync<(Hash, bool)>( + @"INSERT INTO dbo.VirusScanResults (Hash, IsMalware) VALUES (@Hash, @IsMalware)", + new {Hash = hash, IsMalware = result == VirusScanner.Result.Malware}); + } + catch (Exception) + { + // ignored + } + } + } +}