GXM File Format

Technical specification for guideX Module executables

Format Overview

GXM (guideX Module) is a custom executable format designed for guideXOS. It's a simple binary format with a fixed-size header followed by either native machine code or GUI script data.

?? Design Goals:

• Simple to parse and load
• Support both native binaries and scripts
• Minimal overhead (16-byte header)
• Easy to inspect and debug


Every GXM file starts with a 16-byte header:

Offset | Size | Type   | Description
-------|------|--------|-----------------------------------
0x00   | 4    | char[4]| Magic: 'G', 'X', 'M', '\0'
0x04   | 4    | u32    | Version (little-endian)
0x08   | 4    | u32    | Entry RVA (little-endian)
0x0C   | 4    | u32    | Image size (little-endian)
0x10   | N    | byte[] | Image data (binary or script)

Field Descriptions

Field Description Typical Values
Magic File signature for format identification 'GXM\0' (0x47 0x58 0x4D 0x00)
Version Format version number 1 (current)
Entry RVA Relative Virtual Address of entry point 0 for scripts, offset for binaries
Image Size Size of image data following header Variable (bytes)

Binary GXM Format

For native compiled executables (NativeAOT output):

????????????????????????????????????????
? GXM Header (16 bytes)                ?
?  Magic: "GXM\0"                      ?
?  Version: 1                          ?
?  Entry RVA: 0x1000 (example)         ?
?  Image Size: 51200 (example)         ?
????????????????????????????????????????
? Native Binary Image                  ?
?  - x86/x64 machine code              ?
?  - Data sections                     ?
?  - Read-only data                    ?
?  (Size matches Image Size)           ?
????????????????????????????????????????

Binary Example

Hex Dump (first 32 bytes):
Offset  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0x0000  47 58 4D 00 01 00 00 00  00 10 00 00 00 C8 00 00  GXM.............
0x0010  55 48 89 E5 48 83 EC 20  48 8D 0D F4 1F 00 00 E8  UH..H.. H.......

Breakdown:
• 47 58 4D 00 = "GXM\0" (magic)
• 01 00 00 00 = Version 1
• 00 10 00 00 = Entry RVA 0x1000
• 00 C8 00 00 = Image size 51200 bytes
• 55 48 89 E5 ... = x86-64 machine code

GUI Script GXM Format

For GUI script applications, a special marker follows the header:

????????????????????????????????????????
? GXM Header (16 bytes)                ?
?  Magic: "GXM\0"                      ?
?  Version: 1                          ?
?  Entry RVA: 0                        ?
?  Image Size: script_size + 4         ?
????????????????????????????????????????
? GUI Script Marker (4 bytes)          ?
?  "GUI\0"                             ?
????????????????????????????????????????
? Script Data (UTF-8 text)             ?
?  WINDOW|Title|W|H                    ?
?  LABEL|Text|X|Y                      ?
?  BUTTON|ID|Text|X|Y|W|H              ?
?  ONCLICK|ID|Action|Arg               ?
?  ...                                 ?
????????????????????????????????????????

Script Example

Hex Dump (complete small script):
Offset  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0x0000  47 58 4D 00 01 00 00 00  00 00 00 00 7C 00 00 00  GXM.........|...
0x0010  47 55 49 00 57 49 4E 44  4F 57 7C 48 65 6C 6C 6F  GUI.WINDOW|Hello
0x0020  7C 33 30 30 7C 32 30 30  0A 4C 41 42 45 4C 7C 48  |300|200.LABEL|H
0x0030  65 6C 6C 6F 20 57 6F 72  6C 64 21 7C 32 30 7C 35  ello World!|20|5
0x0040  30 0A 42 55 54 54 4F 4E  7C 31 7C 4F 4B 7C 32 30  0.BUTTON|1|OK|20
0x0050  7C 31 30 30 7C 31 30 30  7C 33 30 0A 4F 4E 43 4C  |100|100|30.ONCL
0x0060  49 43 4B 7C 31 7C 43 4C  4F 53 45 7C 0A           ICK|1|CLOSE|.

Breakdown:
• 47 58 4D 00 = "GXM\0" (magic)
• 01 00 00 00 = Version 1
• 00 00 00 00 = Entry RVA 0 (scripts)
• 7C 00 00 00 = Image size 124 bytes
• 47 55 49 00 = "GUI\0" (script marker)
• 57 49 4E ... = Script text (UTF-8)

Practical Examples

Minimal GUI Script

# Script content (28 bytes):
WINDOW|Test|200|100
BUTTON|1|OK|50|50|80|25
ONCLICK|1|CLOSE|

# Total GXM size:
16 (header) + 4 (GUI marker) + 28 (script) = 48 bytes

C# Code to Create GXM

public static byte[] CreateGXM(byte[] binaryData, 
                                uint entryRva, 
                                uint version, 
                                byte[]? scriptData)
{
    uint imageSize = (uint)binaryData.Length;
    int totalSize = 16 + binaryData.Length;
    
    if (scriptData != null)
        totalSize = 16 + 4 + scriptData.Length + binaryData.Length;
    
    byte[] gxm = new byte[totalSize];
    int offset = 0;
    
    // Magic
    gxm[offset++] = (byte)'G';
    gxm[offset++] = (byte)'X';
    gxm[offset++] = (byte)'M';
    gxm[offset++] = 0;
    
    // Version
    WriteU32(gxm, offset, version);
    offset += 4;
    
    // Entry RVA
    WriteU32(gxm, offset, entryRva);
    offset += 4;
    
    // Image size
    uint declaredSize = scriptData != null 
        ? (uint)(4 + scriptData.Length + binaryData.Length)
        : imageSize;
    WriteU32(gxm, offset, declaredSize);
    offset += 4;
    
    // GUI marker if script
    if (scriptData != null)
    {
        gxm[offset++] = (byte)'G';
        gxm[offset++] = (byte)'U';
        gxm[offset++] = (byte)'I';
        gxm[offset++] = 0;
        
        Array.Copy(scriptData, 0, gxm, offset, scriptData.Length);
        offset += scriptData.Length;
    }
    
    // Binary data
    Array.Copy(binaryData, 0, gxm, offset, binaryData.Length);
    
    return gxm;
}

Inspecting GXM Files

Using guideXOS Console

# Inspect GXM header
gxminfo Programs/hello.gxm

Output:
Signature: GXM
Version:1 EntryRVA:0x00000000 DeclaredSize:124

Using Hex Editor

Open the .gxm file in any hex editor (HxD, ImHex, etc.) and verify:

  • First 4 bytes are 47 58 4D 00 ("GXM\0")
  • Bytes 4-7 contain version as little-endian u32
  • Bytes 8-11 contain entry RVA
  • Bytes 12-15 contain image size
  • If GUI script, bytes 16-19 are 47 55 49 00 ("GUI\0")

Using PowerShell

# Read and display GXM header
$bytes = [System.IO.File]::ReadAllBytes("hello.gxm")

# Magic
$magic = [char]$bytes[0] + [char]$bytes[1] + [char]$bytes[2]
Write-Host "Magic: $magic"

# Version
$version = [BitConverter]::ToUInt32($bytes, 4)
Write-Host "Version: $version"

# Entry RVA
$entry = [BitConverter]::ToUInt32($bytes, 8)
Write-Host "Entry RVA: 0x$($entry.ToString('X8'))"

# Image Size
$size = [BitConverter]::ToUInt32($bytes, 12)
Write-Host "Image Size: $size bytes"

# Check for GUI marker
if ($bytes.Length > 16)
{
    $gui = [char]$bytes[16] + [char]$bytes[17] + [char]$bytes[18]
    if ($gui -eq "GUI")
    {
        Write-Host "Type: GUI Script"
    }
    else
    {
        Write-Host "Type: Binary Executable"
    }
}
?? Pro Tip:

Use the GXM Packager log output to verify the format before testing in guideXOS. It shows all header values and file sizes.


Related Topics