All pointers are offsets from the beginning of the main header. The file consists of a header (always uncompressed), followed by content (might be compressed). You need to decompress the data first (if compressed) and place it back directly behind the header to access the data pointed to.
Main Header
60h (96) Bytes header:
0000 BYTES 14h (20) bytes unknown, always zero.
0014 BYTES 28h (40) bytes seemingly random bits. Signature?
003C WORD unknown purpose
003E BYTES 8 bytes name of the module
0046 BYTE unknown. Space for terminating NUL byte?
0047 BYTE 1 if content is zlib compressed
0048 DWORD total byte count (after decompression)
004C DWORD pointer to entry point
0050 DWORD pointer to export table
0054 WORD unknown
0056 WORD number of exports
0058 DWORD pointer to relocation table
005C DWORD size of relocation table
Each export entry is 8 bytes in size
Each relocation entry is 8 bytes in size.
0000 BYTE relocation type
0001 3BYTE pointer to relocation position
0004 DWORD type specific info
Relocation type 02 and 91: local offset
The type specific info is interpreted as a pointer, the module base added and patched at the relocation position
Relocation type 09: absolute value
The type specific info (the whole DWORD) is simply copied to the relocation position
Relocation type 34: ignored
Relocations of this type are simply skipped during relocation process
Relocation type 80: OpenMG API function
The type-specific info is an offset into the API function pointer table, the offset is written to the relocation position
Relocation type 81-88/CB-D1: call to MS support library functions
Patches the offset of a call instruction (relocation position is the address of the offset) to point to the compiler support library function specific to the type.
81: alloca_probe
82: checkesp
84: aulldiv
85: ftol
86: allmul
87: assert
88: alldiv
CB: allrm
CC: allshl
CD: allshr
CF: aullrem
D1: aullshr