CRO0

CRO0

CRO with extension .cro is used for “DLLs”. CRS with extension .crs is in the same format of CRO but storing the symbol information of the static module (the main application). The end of the file is aligned to a 0x1000-byte boundary with 0xCC bytes.

The first hash-table entry hashes the 0x100-byte header following the hash-table. The following hash-table entries hash the sections specified in the header.

When the RO module loads the entire CRO into process memory(mapped in the 0x00100000-0x04000000 region), it modifies the mapped CRO data. The magic field is also changed to “FIXD” if fix level is not 0.

Upon loading, the RO module will look for export symbol “nnroAeabiAtexit_” to patch it to its import symbol “__aeabi_atexit”.

For dumping symbols and loading a CRO into IDA, see 🔗 1 and 🔗 2.

OffsetSizeDescription
0x00x80SHA-256 hash-table, verified by CRR
0x800x04Magic “CRO0”
0x840x04Name offset
0x880x04Next loaded CRO pointer, set by RO during loading (Usually zero when the CRO is being loaded)
0x8C0x04Previous loaded CRO pointer, set by RO during loading
0x900x04File size
0x940x04.bss size
0x980x04Unknown
0x9C0x04Unknown
0xA00x04“Segment offset” that is always the same as export symbol “nnroControlObject_”. 0xFFFFFFFF in CRS
0xA40x04“Segment offset” for “OnLoad” function, which will be called when the module is initialized. Set to 0xFFFFFFFF if not exists.
0xA80x04“Segment offset” for “OnExit” function, which will be called when the module is finalized. Set to 0xFFFFFFFF if not exists.
0xAC0x04“Segment offset” for “OnUnresolved” function, which will be called when an unresolved function is called. Set to 0xFFFFFFFF if not exists.
0xB00x04Code offset
0xB40x04Code size
0xB80x04.data offset
0xBC0x04.data size
0xC00x04Module Name offset
0xC40x04Module Name size
0xC80x04Segment Table offset
0xCC0x04Segment Table num (size = num*12)
0xD00x04Named Export Table offset
0xD40x04Named Export Table num (size = num * 8)
0xD80x04Indexed Export Table offset
0xDC0x04Indexed Export Table num (size = num * 4)
0xE00x04Export Strings offset
0xE40x04Export Strings size
0xE80x04Export Tree offset (fast lookups based on a trie-like structure)
0xEC0x04Export Tree num (size = num * 8)
0xF00x04Import Module Table offset
0xF40x04Import Module Table num (size = num * 20)
0xF80x04Import Patches offset
0xFC0x04Import Patches num (size = num * 12)
0x1000x04Named Import Table offset
0x1040x04Named Import Table num (size = num * 8)
0x1080x04Indexed Import Table offset
0x10C0x04Indexed Import Table num (size = num * 8)
0x1100x04Anonymous Import Table offset
0x1140x04Anonymous Import Table num (size = num * 8)
0x1180x04Import Strings offset
0x11C0x04Import Strings size
0x1200x04unk8 offset
0x1240x04unk8 num
0x1280x04Relocation Patches offset
0x12C0x04Relocation Patches num (size = num * 12)
0x1300x04unk9 offset
0x1340x04unk9 num

Segment offset (4 bytes)

BitsDescription
0-3Segment index for table
4-31Offset into segment

Segment Table entry (12 bytes)

OffsetSizeDescription
0x00x4Segment offset
0x40x4Segment size
0x80x4Segment id (0 = .text, 1 = .rodata, 2 = .data, 3 = .bss)

Named Export Table entry (8 bytes)

OffsetSizeDescription
0x00x4Name offset
0x40x4“Segment offset” for export

Indexed Export Table entry (4 bytes)

OffsetSizeDescription
0x00x4“Segment offset” for export

Named Import Table entry (8 bytes)

OffsetSizeDescription
0x00x4Name offset
0x40x4Offset of the head of a linear list that contains the patches for this import

Indexed Import Table entry (8 bytes)

OffsetSizeDescription
0x00x4index of the export symbol
0x40x4Offset of the head of a linear list that contains the patches for this import

Anonymous Import Table entry (8 bytes)

OffsetSizeDescription
0x00x4“Segment offset” of the export symbol
0x40x4Offset of the head of a linear list that contains the patches for this import

Import Module Table entry (20 bytes)

OffsetSizeDescription
0x00x4Module name offset
0x40x4Indexed import num
0x80x4Offset of the head of a sub list in Indexed Import Table
0xC0x4Anonymous import num
0x100x4Offset of the head of a sub list in Anonymous Import Table

Patch entry (12 bytes)

OffsetSizeDescription
0x00x4“Segment offset” for output.
0x40x1Patch type (0=nothing/ignore, 2=38=write u32 absolute (base+addend), 3=write u32 relative (base+addend-in_ptr), 10=THUMB branch, 28=ARM32 branch, 29=modify ARM32 branch offset, 42=write u32 relative (((signed int)base*2)/2+addend-in_ptr), otherwise err) (This is apparently a subset of relocation type for ARM ELF)
0x50x1For import patches, non-zero if last entry; for relocation patches, this is the referred segment index
0x60x1For import patches, 1 is written to first entry if all symbols loaded successfully; unknown (padding?) for relocation patches
0x70x1Unknown (padding?)
0x80x4addend

ARM32 branch instruction is constructed as follows:

 If addend > 0x2000000 or addend < 0xFE000000, then skip.
 If (addend&1) == 1 then write "b +4" (nop).
 Else write as normal.

Category:File formats