Detect-It-Easy/help/Binary.md

29 KiB
Executable file

Binary Class Reference

The Binary class provides low-level file analysis and manipulation capabilities. This class is used when no other specialized class matches the file format.

Table of Contents

File Information

getSize()

qint64 getSize() - Get the size of the file in bytes.

var fileSize = Binary.getSize();

compare()

bool compare(QString sSignature, qint64 nOffset=0) - Compares bytes with a hexadecimal string signature.

The signature may contain both lowercase and uppercase hexadecimal digits. Spaces are skipped: AA BB = AABB Text may be matched using single quotes: "01'Test'01"

Special Symbols:

  • # - Absolute jump (e.g., "68########55")
  • $ - Relative jump (e.g., "E8$$$$$$$$55")

Wildcard Parameters:

Parameter Description
.. Represent any byte
?? Represent any byte
** Not null
%% ANSI character
%& ANSI number
!% Not ANSI character
_% Not ANSI and not null

Examples:

// Compare file header (nOffset=0)
if (Binary.compare("'7z'BCAF271C")) {
    sVersion = Binary.readByte(6) + "." + Binary.readByte(7);
    bDetected = true;
}

// Compare from specific offset
if (Binary.compare("'WAVEfmt '", 8)) {
    bDetected = true;
}

// JPEG file detection with JFIF header
if (Binary.compare("FFD8FFE0....'JFIF'00")) {
    bDetected = true;
    sVersion = Binary.readByte(11) + "." + Binary.readByte(12);
}

// SQLite database detection
if (Binary.compare("'SQLite format 3'00")) {
    sName = "SQLite 3 database";
    bDetected = true;
}

// RIFF/WAV file detection
if (Binary.compare("'RIFF'........'WAVE'")) {
    sFormat = "WAV Audio File";
    bDetected = true;
}

// Python compiled module detection
if (Binary.compare("?? 0D 0D 0A") && Binary.read_uint16(0x02) == 0x0A0D) {
    var magicValue = Binary.read_uint16(0);
    if (magicValue == 62211) {
        sVersion = "Python 3.6";
        bDetected = true;
    }
}

compareEP()

bool compareEP(QString sSignature, qint64 nOffset=0) - Compare bytes at the Entry Point.

Parameters:

  • sSignature - The hexadecimal signature to compare
  • nOffset - Offset from the entry point (default: 0)

Examples:

if (Binary.compareEP("2C81", 8)) {
    sVersion = "1.98";
}

if (Binary.compareEP("EB016860E8000000008B1C2483C312812BE8B10600FE4BFD822C24")) {
    bDetected = true;
}

Search Functions

findSignature()

qint64 findSignature(qint64 nOffset, qint64 nSize, QString sSignature) - Search for a signature in the file.

Returns: Offset in the file if found, -1 otherwise.

findString()

qint64 findString(qint64 nOffset, qint64 nSize, QString sString) - Search for a string in the file.

Returns: Offset in the file if found, -1 otherwise.

findByte()

qint64 findByte(qint64 nOffset, qint64 nSize, quint8 nValue) - Search for a byte value in the file.

Returns: Offset in the file if found, -1 otherwise.

findWord()

qint64 findWord(qint64 nOffset, qint64 nSize, quint16 nValue) - Search for a 16-bit word in the file.

Returns: Offset in the file if found, -1 otherwise.

findDword()

qint64 findDword(qint64 nOffset, qint64 nSize, quint32 nValue) - Search for a 32-bit double word in the file.

Returns: Offset in the file if found, -1 otherwise.

isSignaturePresent()

bool isSignaturePresent(qint64 nOffset, qint64 nSize, QString sSignature) - Check if a signature exists in a file region.

Uses the same signature format as compare().

Data Reading Methods

Basic Integer Types

8-bit Values

quint8 readByte(qint64 nOffset) - Read an unsigned byte value.

qint8 readSByte(qint64 nOffset) - Read a signed byte value.

16-bit Values

quint16 readWord(qint64 nOffset) - Read an unsigned 16-bit word.

qint16 readSWord(qint64 nOffset) - Read a signed 16-bit word.

32-bit Values

quint32 readDword(qint64 nOffset) - Read an unsigned 32-bit double word.

qint32 readSDword(qint64 nOffset) - Read a signed 32-bit double word.

64-bit Values

quint64 readQword(qint64 nOffset) - Read an unsigned 64-bit quad word.

qint64 readSQword(qint64 nOffset) - Read a signed 64-bit quad word.

Enhanced Reading Methods

Integer Types with Endianness Support

quint8 read_uint8(qint64 nOffset) - Read unsigned 8-bit integer.

qint8 read_int8(qint64 nOffset) - Read signed 8-bit integer.

quint16 read_uint16(qint64 nOffset, bool bIsBigEndian=false) - Read unsigned 16-bit integer.

qint16 read_int16(qint64 nOffset, bool bIsBigEndian=false) - Read signed 16-bit integer.

quint32 read_uint24(qint64 nOffset, bool bIsBigEndian=false) - Read unsigned 24-bit integer.

qint32 read_int24(qint64 nOffset, bool bIsBigEndian=false) - Read signed 24-bit integer.

quint32 read_uint32(qint64 nOffset, bool bIsBigEndian=false) - Read unsigned 32-bit integer.

qint32 read_int32(qint64 nOffset, bool bIsBigEndian=false) - Read signed 32-bit integer.

quint64 read_uint64(qint64 nOffset, bool bIsBigEndian=false) - Read unsigned 64-bit integer.

qint64 read_int64(qint64 nOffset, bool bIsBigEndian=false) - Read signed 64-bit integer.

Floating Point Types

float read_float(qint64 nOffset, bool bIsBigEndian=false) - Read 32-bit float.

double read_double(qint64 nOffset, bool bIsBigEndian=false) - Read 64-bit double.

float read_float16(qint64 nOffset, bool bIsBigEndian=false) - Read 16-bit half precision float.

float read_float32(qint64 nOffset, bool bIsBigEndian=false) - Read 32-bit single precision float.

double read_float64(qint64 nOffset, bool bIsBigEndian=false) - Read 64-bit double precision float.

Binary Coded Decimal (BCD)

quint8 read_bcd_uint8(qint64 nOffset) - Read 8-bit BCD value.

quint16 read_bcd_uint16(qint64 nOffset, bool bIsBigEndian=false) - Read 16-bit BCD value.

quint32 read_bcd_uint32(qint64 nOffset, bool bIsBigEndian=false) - Read 32-bit BCD value.

quint64 read_bcd_uint64(qint64 nOffset, bool bIsBigEndian=false) - Read 64-bit BCD value.

Special Data Types

QString read_UUID_bytes(qint64 nOffset) - Read UUID as raw bytes.

QString read_UUID(qint64 nOffset, bool bIsBigEndian=false) - Read formatted UUID.

QList<QVariant> readBytes(qint64 nOffset, qint64 nSize, bool bReplaceZeroWithSpace=false) - Read raw bytes as array.

String Operations

Basic String Reading

QString getString(qint64 nOffset, qint64 nMaxSize=50) - Read a null-terminated string.

Parameters:

  • nOffset - File offset to read from
  • nMaxSize - Maximum string length in bytes (default: 50)

Example:

var sString = Binary.getString(0x100, 32);  // Read max 32 bytes from offset 0x100
var sString = Binary.getString(60);         // Read max 50 bytes from offset 60

// Detect UTF-8 BOM in text files
var sText = Binary.getString(0, Math.min(Binary.getSize(), 3));
if (/^\xef\xbb\xbf/.test(sText)) {
    sName = "UTF-8 text with BOM";
}

// Check line ending types
var size = Binary.getSize() < 4096 ? Binary.getSize() : 4096;
var pos = Binary.findByte(0, size, 10); // Look for LF (0x0A)
if (pos !== -1) {
    // Check if CRLF or just LF
    var hasCR = (pos != 0 && Binary.readByte(pos - 1) == 13) || 
                (pos + 1 < Binary.getSize() && Binary.readByte(pos + 1) == 13);
    sLineEnding = hasCR ? "CRLF" : "LF";
} else if (Binary.findByte(0, size, 13) != -1) {
    sLineEnding = "CR"; // Mac classic
}

Encoding-Specific String Reading

QString read_ansiString(qint64 nOffset, qint64 nMaxSize=50) - Read ANSI encoded string.

QString read_unicodeString(qint64 nOffset, qint64 nMaxSize=50) - Read Unicode (UTF-16) string.

QString read_utf8String(qint64 nOffset, qint64 nMaxSize=50) - Read UTF-8 encoded string.

QString read_ucsdString(qint64 nOffset) - Read UCSD Pascal-style string (length-prefixed).

Advanced String Reading

QString read_codePageString(qint64 nOffset, qint64 nMaxByteSize=256, QString sCodePage="System") - Read string with specific code page encoding.

Supported Code Pages:

System, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5,
ISO-8859-7, ISO-8859-9, ISO-8859-10, ISO-8859-13, ISO-8859-14,
ISO-8859-15, ISO-8859-16, ISO-8859-6, ISO-8859-8, Shift_JIS, EUC-JP,
EUC-KR, ISO-2022-JP, UTF-8, UTF-16BE, UTF-16LE, UTF-16, UTF-32,
UTF-32BE, UTF-32LE, GBK, GB18030, GB2312, Big5, Big5-HKSCS,
windows-1250 through windows-1258, KOI8-R, KOI8-U, IBM850, IBM866,
IBM874, TIS-620, macintosh, hp-roman8, TSCII, WINSAMI2, windows-949,
iscii-dev, iscii-bng, iscii-pnj, iscii-gjr, iscii-ori, iscii-tml,
iscii-tlg, iscii-knd, iscii-mlm

String Search Functions

qint64 find_ansiString(qint64 nOffset, qint64 nSize, QString sString) - Search for ANSI string.

qint64 find_unicodeString(qint64 nOffset, qint64 nSize, QString sString) - Search for Unicode string.

qint64 find_utf8String(qint64 nOffset, qint64 nSize, QString sString) - Search for UTF-8 string.

String Utility Functions

QString upperCase(QString sString) - Convert string to uppercase.

QString lowerCase(QString sString) - Convert string to lowercase.

QString cleanString(QString sString) - Clean and normalize string content.

Hash and Checksum Functions

CRC Functions

QString calculateCRC32(qint64 nOffset, qint64 nSize) - Calculate CRC32 hash as hex string.

quint16 crc16(qint64 nOffset, qint64 nSize, quint16 nInit=0) - Calculate CRC16 checksum.

quint32 crc32(qint64 nOffset, qint64 nSize, quint32 nInit=0) - Calculate CRC32 checksum.

Cryptographic Hashes

QString calculateMD5(qint64 nOffset, qint64 nSize) - Calculate MD5 hash of file region.

Other Checksums

quint32 adler32(qint64 nOffset, qint64 nSize) - Calculate Adler-32 checksum.

double calculateEntropy(qint64 nOffset, qint64 nSize) - Calculate entropy (bits per byte, max 8.0).

File Format Detection

Text Format Detection

bool isPlainText() - Check if file contains plain text.

bool isUTF8Text() - Check if file contains UTF-8 encoded text.

bool isUnicodeText() - Check if file contains Unicode text.

bool isText() - Check if file contains any text format.

Example:

if (Binary.isPlainText()) {
    sName = "Plain text file";
    
    // Check for specific encodings
    if (Binary.isUTF8Text()) {
        sOptions = "UTF-8";
    } else if (Binary.isUnicodeText()) {
        sOptions = "Unicode";
    }
    
    bDetected = true;
}

JPEG Detection and Analysis

bool isJpeg() - Check if file is JPEG format.

QString getJpegComment() - Extract JPEG comment field.

QString getJpegDqtMD5() - Get MD5 hash of JPEG quantization tables.

bool isJpegChunkPresent(qint32 nID) - Check for specific JPEG chunk.

bool isJpegExifPresent() - Check if JPEG contains EXIF data.

QString getJpegExifCameraName() - Extract camera name from EXIF data.

Example:

if (Binary.isJpeg()) {
    sName = "JPEG image";
    
    // Extract comment if present
    var comment = Binary.getJpegComment();
    if (comment.length > 0) {
        sOptions = "comment: " + comment;
    }
    
    // Check for EXIF data
    if (Binary.isJpegExifPresent()) {
        var cameraName = Binary.getJpegExifCameraName();
        if (cameraName.length > 0) {
            sOptions += ", camera: " + cameraName;
        }
    }
    
    // Get quantization table hash for identification
    var dqtHash = Binary.getJpegDqtMD5();
    if (dqtHash.length > 0) {
        sOptions += ", DQT hash: " + dqtHash.substring(0, 8);
    }
    
    bDetected = true;
}

Compression Detection

qint64 detectZLIB(qint64 nOffset, qint64 nSize) - Detect ZLIB compressed data.

qint64 detectGZIP(qint64 nOffset, qint64 nSize) - Detect GZIP compressed data.

qint64 detectZIP(qint64 nOffset, qint64 nSize) - Detect ZIP compressed data.

Compression Support

QList<QString> getListOfCompressionMethods() - Get available compression methods.

QList<QVariant> decompressBytes(qint64 nOffset, qint64 nSize, QString sCompressionMethod) - Decompress data.

qint64 getCompressedDataSize(qint64 nOffset, qint64 nSize, QString sCompressionMethod) - Get compressed data size.

Utility Functions

File Path Operations

QString getFileDirectory() - Get directory containing the file.

QString getFileBaseName() - Get base filename without path or extension.

QString getFileCompleteSuffix() - Get complete file extension.

QString getFileSuffix() - Get primary file extension.

Memory and Address Operations

qint64 RVAToOffset(qint64 nRVA) - Convert Relative Virtual Address to file offset.

qint64 VAToOffset(qint64 nVA) - Convert Virtual Address to file offset.

qint64 OffsetToVA(qint64 nOffset) - Convert file offset to Virtual Address.

qint64 OffsetToRVA(qint64 nOffset) - Convert file offset to Relative Virtual Address.

qint64 getImageBase() - Get image base address.

Entry Point and Overlay Operations

qint64 getEntryPointOffset() - Get entry point file offset.

qint64 getAddressOfEntryPoint() - Get entry point virtual address.

qint64 getOverlayOffset() - Get overlay data offset.

qint64 getOverlaySize() - Get overlay data size.

bool isOverlayPresent() - Check if file has overlay data.

bool compareOverlay(QString sSignature, qint64 nOffset=0) - Compare overlay data signature.

Data Conversion

quint32 swapBytes(quint32 nValue) - Swap byte order of 32-bit value.

Example: 0x11223344 becomes 0x44332211

QString bytesCountToString(quint64 nValue, quint32 nBase=1024) - Convert byte count to human readable string.

QString getSignature(qint64 nOffset, qint64 nSize) - Get hex signature from file region.

Example:

if (Binary.getSignature(0, 4) == "AA5411DD") {
    bDetected = true;
}

// SQLite version detection from header
var nSQLiteVersionNumber = Binary.read_uint32(0x60, true); // Big-endian
var nMajor = Math.floor(nSQLiteVersionNumber / 1000000);
var nMinor = Math.floor((nSQLiteVersionNumber - nMajor * 1000000) / 1000);
var nRelease = nSQLiteVersionNumber - (nMajor * 1000000) - (nMinor * 1000);
sVersion = nMajor + "." + nMinor + "." + nRelease;

// Extract JPEG dimensions and version
if (Binary.compare("FFD8FFE0....'JFIF'00")) {
    sVersion = Binary.readByte(11) + "." + Binary.readByte(12);
    
    // Search for Start Of Frame to get dimensions
    var nOffset = 2;
    while (nOffset < Binary.getSize()) {
        var wTag = Binary.read_uint16(nOffset, true); // Big-endian
        if (wTag >= 0xFFC0 && wTag <= 0xFFC3) {
            var width = Binary.read_uint16(nOffset + 7, true);
            var height = Binary.read_uint16(nOffset + 5, true);
            sOptions = width + "x" + height;
            break;
        }
        nOffset += 2;
    }
}

Architecture and Build Detection

bool is16() - Check if file is 16-bit architecture.

bool is32() - Check if file is 32-bit architecture.

bool is64() - Check if file is 64-bit architecture.

bool isReleaseBuild() - Check if file is a release build.

bool isDebugBuild() - Check if file is a debug build.

File Properties and Validation

bool isSigned() - Check if file is digitally signed.

bool isOverlay() - Check if current context is overlay data.

bool isResource() - Check if current context is resource data.

bool isDebugData() - Check if current context is debug data.

bool isFilePart() - Check if current context is part of a file.

Validation Functions

bool isChecksumCorrect() - Verify file checksum.

bool isEntryPointCorrect() - Verify entry point validity.

bool isSectionAlignmentCorrect() - Verify section alignment.

bool isFileAlignmentCorrect() - Verify file alignment.

bool isHeaderCorrect() - Verify file header.

bool isRelocsTableCorrect() - Verify relocations table.

bool isImportTableCorrect() - Verify import table.

bool isExportTableCorrect() - Verify export table.

bool isResourcesTableCorrect() - Verify resources table.

bool isSectionsTableCorrect() - Verify sections table.

Scan Mode Detection

bool isDeepScan() - Check if deep scan mode is enabled.

bool isHeuristicScan() - Check if heuristic scan mode is enabled.

bool isRecursiveScan() - Check if recursive scan mode is enabled.

bool isAggressiveScan() - Check if aggressive scan mode is enabled.

bool isVerbose() - Check if verbose mode is enabled.

Performance and Debugging

bool isProfiling() - Check if profiling mode is enabled.

qint64 startTiming() - Start performance timing.

qint64 endTiming(qint64 nHandle, const QString &sInfo) - End performance timing.

qint64 getStartOffset() - Get physical offset in file.

Example:

// Profiling flag should be set
var nProfiling = Binary.startTiming();
// ... slow code execution ...
var nTime = Binary.endTiming(nProfiling, "PROFILING");

Disassembly Functions

qint32 getDisasmLength(qint64 nAddress) - Get length of instruction at address.

QString getDisasmString(qint64 nAddress) - Get disassembly string for instruction.

qint64 getDisasmNextAddress(qint64 nAddress) - Get address of next instruction.

System Information

QString getOperationSystemName() - Get operating system name.

QString getOperationSystemVersion() - Get operating system version.

QString getOperationSystemOptions() - Get operating system options.

QString getFileFormatName() - Get file format name.

QString getFileFormatVersion() - Get file format version.

QString getFileFormatOptions() - Get file format options.

Message and Header Information

QList<QString> getFormatMessages() - Get format-specific messages.

QString getHeaderString() - Get header information as string.

Section-based Operations

bool isSignatureInSectionPresent(quint32 nNumber, QString sSignature) - Check signature in specific section.

Real-World Detection Examples

This section contains practical examples from the DIE signature database showing how to use Binary class methods for file format detection.

Archive Formats

ZIP Archive Detection

// Basic ZIP detection
if (Binary.compare("'PK'0304") || Binary.compare("'PK'0506") || Binary.compare("'PK'0708")) {
    sName = "ZIP archive";
    bDetected = true;
}

// Enhanced ZIP detection with central directory
if (Binary.compare("'PK'0102")) {
    sName = "ZIP archive (central directory)";
    bDetected = true;
}

7-Zip Archive Detection

if (Binary.compare("'7z'BCAF271C")) {
    sName = "7-Zip archive";
    sVersion = Binary.readByte(6) + "." + Binary.readByte(7);
    bDetected = true;
}

RAR Archive Detection

if (Binary.compare("'Rar!'1A0700")) {
    sName = "RAR archive";
    sVersion = "1.5-4.x";
    bDetected = true;
} else if (Binary.compare("'Rar!'1A070100")) {
    sName = "RAR archive";
    sVersion = "5.0+";
    bDetected = true;
}

Image Formats

JPEG Image Detection

if (Binary.compare("FFD8FFE0....'JFIF'00")) {
    sName = "JPEG image";
    bDetected = true;
    
    // Extract version
    sVersion = Binary.readByte(11) + ".";
    if (Binary.readByte(12) < 10) {
        sVersion += "0";
    }
    sVersion += Binary.readByte(12);
    
    // Find dimensions in Start of Frame marker
    var nOffset = 2;
    while (nOffset < Binary.getSize()) {
        var wTag = Binary.read_uint16(nOffset, true);
        if (wTag >= 0xFFC0 && wTag <= 0xFFC3) {
            var width = Binary.read_uint16(nOffset + 7, true);
            var height = Binary.read_uint16(nOffset + 5, true);
            sOptions = width + "x" + height;
            
            // Detect color space
            switch (Binary.readByte(nOffset + 9)) {
                case 1: sOptions += ", greyscale"; break;
                case 3: sOptions += ", YCbCr"; break;
                case 4: sOptions += ", CMYK"; break;
            }
            break;
        }
        var nLength = Binary.read_uint16(nOffset + 2, true);
        nOffset += nLength + 2;
    }
}

PNG Image Detection

if (Binary.compare("89'PNG'0D0A1A0A")) {
    sName = "PNG image";
    bDetected = true;
    
    // Extract dimensions from IHDR chunk
    if (Binary.compare("'IHDR'", 12)) {
        var width = Binary.read_uint32(16, true);
        var height = Binary.read_uint32(20, true);
        var bitDepth = Binary.readByte(24);
        var colorType = Binary.readByte(25);
        
        sOptions = width + "x" + height + ", " + bitDepth + " bit";
        
        switch (colorType) {
            case 0: sOptions += ", grayscale"; break;
            case 2: sOptions += ", RGB"; break;
            case 3: sOptions += ", palette"; break;
            case 4: sOptions += ", grayscale+alpha"; break;
            case 6: sOptions += ", RGBA"; break;
        }
    }
}

Audio Formats

WAV Audio Detection

if (Binary.compare("'RIFF'........'WAVE'")) {
    sName = "WAV Audio File";
    bDetected = true;
    
    // Parse chunks to extract format information
    var nOffset = 12;
    while (nOffset < Binary.getSize() - 8) {
        var chunkId = Binary.getString(nOffset, 4);
        var chunkSize = Binary.read_uint32(nOffset + 4, false); // Little-endian
        
        if (chunkId == "fmt ") {
            var audioFormat = Binary.read_uint16(nOffset + 8, false);
            var numChannels = Binary.read_uint16(nOffset + 10, false);
            var sampleRate = Binary.read_uint32(nOffset + 12, false);
            var bitsPerSample = Binary.read_uint16(nOffset + 22, false);
            
            sOptions = sampleRate + " Hz, " + numChannels + " channel";
            if (numChannels > 1) sOptions += "s";
            sOptions += ", " + bitsPerSample + " bit";
            
            switch (audioFormat) {
                case 1: sOptions += ", PCM"; break;
                case 3: sOptions += ", IEEE float"; break;
                case 6: sOptions += ", A-law"; break;
                case 7: sOptions += ", μ-law"; break;
            }
            break;
        }
        
        nOffset += 8 + chunkSize;
        if (chunkSize % 2) nOffset++; // Pad to even boundary
    }
}

Database Formats

SQLite Database Detection

if (Binary.compare("'SQLite format 3'00")) {
    sName = "SQLite 3 database";
    bDetected = true;
    
    // Extract version information
    var nSQLiteVersionNumber = Binary.read_uint32(0x60, true);
    var nMajor = Math.floor(nSQLiteVersionNumber / 1000000);
    var nMinor = Math.floor((nSQLiteVersionNumber - nMajor * 1000000) / 1000);
    var nRelease = nSQLiteVersionNumber - (nMajor * 1000000) - (nMinor * 1000);
    sVersion = nMajor + "." + nMinor + "." + nRelease;
    
    // Check text encoding
    switch (Binary.read_uint32(0x38, true)) {
        case 1: sOptions = "UTF-8"; break;
        case 2: sOptions = "UTF-16LE"; break;
        case 3: sOptions = "UTF-16BE"; break;
    }
    
    // Application ID (if present)
    var nAppID = Binary.read_uint32(0x44, true);
    if (nAppID && Binary.isVerbose()) {
        sOptions += ", AppID:" + nAppID.toString(16);
    }
}

Programming Languages

Python Compiled Module Detection

if (Binary.compare("?? 0D 0D 0A") && Binary.read_uint16(0x02) == 0x0A0D) {
    sName = "Python compiled module";
    bDetected = true;
    
    var magicValue = Binary.read_uint16(0);
    switch (magicValue) {
        case 20121: sVersion = "1.5-1.5.2"; break;
        case 50428: sVersion = "1.6"; break;
        case 50823: sVersion = "2.0-2.0.1"; break;
        case 60202: sVersion = "2.1-2.1.2"; break;
        case 62211: sVersion = "3.6"; break;
        case 62061: sVersion = "2.4b1"; break;
        case 3394: sVersion = "3.8"; break;
        case 3413: sVersion = "3.9"; break;
        case 3439: sVersion = "3.10"; break;
        case 3495: sVersion = "3.11"; break;
        case 3531: sVersion = "3.12"; break;
        // Add more versions as needed
    }
    
    // Extract timestamp (compilation time)
    var timestamp = Binary.read_uint32(4, false);
    if (timestamp > 0) {
        var date = new Date(timestamp * 1000);
        sOptions = "compiled " + date.toISOString().split('T')[0];
    }
}

Text Format Detection

Plain Text with Encoding Detection

if (Binary.isPlainText()) {
    sName = "Plain text";
    bDetected = true;
    
    var sText = Binary.getString(0, Math.min(Binary.getSize(), 3));
    
    // Check for UTF-8 BOM
    if (Binary.compare("EFBBBF")) {
        sName = "UTF-8 text";
        sOptions = "BOM";
    }
    // Check for UTF-16 BOM
    else if (Binary.compare("FFFE")) {
        sName = "UTF-16LE text";
        sOptions = "BOM";
    }
    else if (Binary.compare("FEFF")) {
        sName = "UTF-16BE text";
        sOptions = "BOM";
    }
    
    // Detect line endings
    var size = Math.min(Binary.getSize(), 4096);
    var lfPos = Binary.findByte(0, size, 10);  // LF
    var crPos = Binary.findByte(0, size, 13);  // CR
    
    if (lfPos !== -1 && crPos !== -1) {
        sOptions = sOptions ? sOptions + ", CRLF" : "CRLF";
    } else if (lfPos !== -1) {
        sOptions = sOptions ? sOptions + ", LF" : "LF";
    } else if (crPos !== -1) {
        sOptions = sOptions ? sOptions + ", CR" : "CR";
    }
}

Compression Detection

ZLIB Data Detection

// ZLIB header detection
var firstByte = Binary.readByte(0);
var secondByte = Binary.readByte(1);

if ((firstByte & 0x0F) == 8 && (firstByte >> 4) <= 7) {
    if (((firstByte << 8) | secondByte) % 31 == 0) {
        sName = "ZLIB compressed data";
        bDetected = true;
        
        var compressionLevel = (secondByte >> 6) & 3;
        var windowSize = 1 << ((firstByte >> 4) + 8);
        
        sOptions = "level " + compressionLevel + ", " + windowSize + " byte window";
        
        if (secondByte & 0x20) {
            sOptions += ", dictionary";
        }
    }
}

Executable Format Detection

Shellcode Detection

// Detect common shellcode patterns
var shellcodePatterns = [
    "EB??5?5?", // JMP short, PUSH/POP pattern
    "E8????????", // CALL instruction
    "83C4??", // ADD ESP, immediate
    "FF??", // Various FF opcodes
];

var bShellcodeDetected = false;
var patternCount = 0;

for (var i = 0; i < shellcodePatterns.length; i++) {
    if (Binary.isSignaturePresent(0, Math.min(256, Binary.getSize()), shellcodePatterns[i])) {
        patternCount++;
    }
}

if (patternCount >= 2) {
    sName = "Possible shellcode";
    sOptions = "pattern count: " + patternCount;
    bDetected = true;
}

Method Shortcuts

For convenience, shorter method names are available:

Data Type Shortcuts

  • X.U8(a) = File.read_uint8(a)
  • X.I8(a) = File.read_int8(a)
  • X.U16(a, b) = File.read_uint16(a, b)
  • X.I16(a, b) = File.read_int16(a, b)
  • X.F16(a, b) = File.read_float16(a, b)
  • X.U24(a, b) = File.read_uint24(a, b)
  • X.I24(a, b) = File.read_int24(a, b)
  • X.U32(a, b) = File.read_uint32(a, b)
  • X.I32(a, b) = File.read_int32(a, b)
  • X.F32(a, b) = File.read_float32(a, b)
  • X.U64(a, b) = File.read_uint64(a, b)
  • X.I64(a, b) = File.read_int64(a, b)
  • X.F64(a, b) = File.read_float64(a, b)

String Shortcuts

  • X.SA(a, b) = File.read_ansiString(a, b)
  • X.SC(a, b, c) = File.read_codePageString(a, b, c)
  • X.UCSD(a) = File.read_ucsdString(a)
  • X.SU8(a, b) = File.read_utf8String(a, b)
  • X.SU16(a, b) = File.read_unicodeString(a, b)

Utility Shortcuts

  • X.Sz() = File.getSize()
  • X.fSig(a, b, c) = File.findSignature(a, b, c)
  • X.fStr(a, b, c) = File.findString(a, b, c)
  • X.c(a, b) = File.compare(a, b)
  • X.BA(a, b, c) = File.readBytes(a, b, c)