Changes

Jump to navigation Jump to search
2,637 bytes added ,  02:26, 26 October 2016
added new header info
Line 16: Line 16:  
| 0x84
 
| 0x84
 
| 0x04
 
| 0x04
| Code size
+
| Name offset
 
|-
 
|-
 
| 0x88
 
| 0x88
| 0x08
+
| 0x04
| Unknown
+
| Next loaded CRO pointer, set by RO during loading (Usually zero when the CRO is being loaded)
 +
|-
 +
| 0x8C
 +
| 0x04
 +
| Previous loaded CRO pointer, set by RO during loading
 
|-
 
|-
 
| 0x90
 
| 0x90
Line 27: Line 31:  
|-
 
|-
 
| 0x94
 
| 0x94
| 0x18
+
| 0x04
 +
| .bss size
 +
|-
 +
| 0x98
 +
| 0x04
 
| Unknown
 
| Unknown
 +
|-
 +
| 0x9C
 +
| 0x04
 +
| Unknown
 +
|-
 +
| 0xA0
 +
| 0x04
 +
| "Segment offset" that is always the same as export symbol "nnroControlObject_". 0xFFFFFFFF in CRS
 +
|-
 +
| 0xA4
 +
| 0x04
 +
| "Segment offset" for "OnLoad" function, which will be called when the module is initialized. Set to 0xFFFFFFFF if not exists.
 +
|-
 +
| 0xA8
 +
| 0x04
 +
| "Segment offset" for "OnExit" function, which will be called when the module is finalized. Set to 0xFFFFFFFF if not exists.
 
|-
 
|-
 
| 0xAC
 
| 0xAC
 
| 0x04
 
| 0x04
| "Segment offset", symbols are loaded relative to this
+
| "Segment offset" for "OnUnresolved" function, which will be called when an unresolved function is called. Set to 0xFFFFFFFF if not exists.
 
|-
 
|-
 
| 0xB0
 
| 0xB0
Line 44: Line 68:  
| 0xB8
 
| 0xB8
 
| 0x04
 
| 0x04
| unk1 offset
+
| .data offset
 
|-
 
|-
 
| 0xBC
 
| 0xBC
 
| 0x04
 
| 0x04
| unk1 size
+
| .data size
 
|-
 
|-
 
| 0xC0
 
| 0xC0
Line 55: Line 79:  
|-
 
|-
 
| 0xC4
 
| 0xC4
| 0xBC
+
| 0x04
 
| Module Name size
 
| Module Name size
 
|-
 
|-
Line 68: Line 92:  
| 0xD0
 
| 0xD0
 
| 0x04
 
| 0x04
| Export Table offset
+
| Named Export Table offset
 
|-
 
|-
 
| 0xD4
 
| 0xD4
 
| 0x04
 
| 0x04
| Export Table num (size = num * 8)
+
| Named Export Table num (size = num * 8)
 
|-
 
|-
 
| 0xD8
 
| 0xD8
 
| 0x04
 
| 0x04
| unk3 offset
+
| Indexed Export Table offset
 
|-
 
|-
 
| 0xDC
 
| 0xDC
 
| 0x04
 
| 0x04
| unk3 num
+
| Indexed Export Table num (size = num * 4)
 
|-
 
|-
 
| 0xE0
 
| 0xE0
Line 92: Line 116:  
| 0xE8
 
| 0xE8
 
| 0x04
 
| 0x04
| Export Info offset
+
| Export Tree offset (fast lookups based on a trie-like structure)
 
|-
 
|-
 
| 0xEC
 
| 0xEC
 
| 0x04
 
| 0x04
| Export Info num (size = num * 8)
+
| Export Tree num (size = num * 8)
 
|-
 
|-
 
| 0xF0
 
| 0xF0
 
| 0x04
 
| 0x04
| unk4 offset
+
| Import Module Table offset
 
|-
 
|-
 
| 0xF4
 
| 0xF4
 
| 0x04
 
| 0x04
| unk4 num
+
| Import Module Table num (size = num * 20)
 
|-
 
|-
 
| 0xF8
 
| 0xF8
 
| 0x04
 
| 0x04
| unk5 offset
+
| Import Patches offset
 
|-
 
|-
 
| 0xFC
 
| 0xFC
 
| 0x04
 
| 0x04
| unk5 num (size = num * 12)
+
| Import Patches num (size = num * 12)
 
|-
 
|-
 
| 0x100
 
| 0x100
 
| 0x04
 
| 0x04
| Import Table 1 offset
+
| Named Import Table offset
 
|-
 
|-
 
| 0x104
 
| 0x104
 
| 0x04
 
| 0x04
| Import Table 1 num (size = num * 4)
+
| Named Import Table num (size = num * 8)
 
|-
 
|-
 
| 0x108
 
| 0x108
 
| 0x04
 
| 0x04
| Import Table 2 offset
+
| Indexed Import Table offset
 
|-
 
|-
 
| 0x10C
 
| 0x10C
 
| 0x04
 
| 0x04
| Import Table 2 num (size = num * 4)
+
| Indexed Import Table num (size = num * 8)
 
|-
 
|-
 
| 0x110
 
| 0x110
 
| 0x04
 
| 0x04
| Import Table 3 offset
+
| Anonymous Import Table offset
 
|-
 
|-
 
| 0x114
 
| 0x114
 
| 0x04
 
| 0x04
| Import Table 3 num (size = num * 4)
+
| Anonymous Import Table num (size = num * 8)
 
|-
 
|-
 
| 0x118
 
| 0x118
Line 156: Line 180:  
| 0x128
 
| 0x128
 
| 0x04
 
| 0x04
| Import Info offset
+
| Relocation Patches offset
 
|-
 
|-
 
| 0x12C
 
| 0x12C
 
| 0x04
 
| 0x04
| Import Info num (size = num * 12)
+
| Relocation Patches num (size = num * 12)
 
|-
 
|-
 
| 0x130
 
| 0x130
Line 169: Line 193:  
| 0x04
 
| 0x04
 
| unk9 num
 
| unk9 num
 +
|}
 +
 +
Segment offset (4 bytes)
 +
 +
{| class="wikitable" border="1"
 +
!  Bits
 +
!  Description
 +
|-
 +
| 0-3
 +
| Segment index for table
 +
|-
 +
| 4-31
 +
| Offset into segment
 
|}
 
|}
   Line 187: Line 224:  
| 0x8
 
| 0x8
 
| 0x4
 
| 0x4
| Segment id (0, 1, 2..)
+
| Segment id (0 = .text, 1 = .rodata, 2 = .data, 3 = .bss)
 +
|}
 +
 
 +
Named Export Table entry (8 bytes)
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| Name offset
 +
|-
 +
| 0x4
 +
| 0x4
 +
| "Segment offset" for export
 +
|}
 +
 
 +
Indexed Export Table entry (4 bytes)
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| "Segment offset" for export
 
|}
 
|}
   −
Import Table entry (8 bytes)
+
Named Import Table entry (8 bytes)
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  Offset
 
!  Offset
Line 202: Line 265:  
| 0x4
 
| 0x4
 
| 0x4
 
| 0x4
| Offset for symbol entry
+
| Offset of the head of a linear list that contains the patches for this import
 +
|}
 +
 
 +
Indexed Import Table entry (8 bytes)
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| index of the export symbol
 +
|-
 +
| 0x4
 +
| 0x4
 +
| Offset of the head of a linear list that contains the patches for this import
 +
|}
 +
 
 +
Anonymous Import Table entry (8 bytes)
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| "Segment offset" of the export symbol
 +
|-
 +
| 0x4
 +
| 0x4
 +
| Offset of the head of a linear list that contains the patches for this import
 +
|}
 +
 
 +
Import Module Table entry (20 bytes)
 +
{| class="wikitable" border="1"
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x4
 +
| Module name offset
 +
|-
 +
| 0x4
 +
| 0x4
 +
| Indexed import num
 +
|-
 +
| 0x8
 +
| 0x4
 +
| Offset of the head of a sub list in Indexed Import Table
 +
|-
 +
| 0xC
 +
| 0x4
 +
| Anonymous import num
 +
|-
 +
| 0x10
 +
| 0x4
 +
| Offset of the head of a sub list in Anonymous Import Table
 
|}
 
|}
   −
Symbol entry (12 bytes)
+
Patch entry (12 bytes)
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
!  Offset
 
!  Offset
Line 217: Line 337:  
| 0x4
 
| 0x4
 
| 0x1
 
| 0x1
| Type (0=nothing/ignore, 2=38=write u32 absolute (base+X), 3=write u32 relative (base+X-in_ptr), 10=THUMB branch, 28=ARM32 branch, 29=modify ARM32 branch offset, 42=write u32 relative (((signed int)base*2)/2+X-in_ptr), otherwise err)
+
| Patch 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)
 
|-
 
|-
 
| 0x5
 
| 0x5
 
| 0x1
 
| 0x1
| Non-zero if last entry.
+
| For import patches, non-zero if last entry; for relocation patches, this is the referred segment index
 
|-
 
|-
 
| 0x6
 
| 0x6
 
| 0x1
 
| 0x1
| 1 is written to last entry if all symbols loaded successfully.
+
| For import patches, 1 is written to first entry if all symbols loaded successfully; unknown (padding?) for relocation patches
 
|-
 
|-
 
| 0x7
 
| 0x7
 
| 0x1
 
| 0x1
| Unknown
+
| Unknown (padding?)
 
|-
 
|-
 
| 0x8
 
| 0x8
 
| 0x4
 
| 0x4
| X (00's in file, probably set by dynamic linker)
+
| addend
 
|}
 
|}
    
ARM32 branch instruction is constructed as follows:
 
ARM32 branch instruction is constructed as follows:
   If X > 0x2000000 or X < 0xFE000000, then skip.
+
   If addend > 0x2000000 or addend < 0xFE000000, then skip.
   If (X&1) == 1 then write "b 0" (infinite loop).
+
   If (addend&1) == 1 then write "b +4" (nop).
 
   Else write as normal.
 
   Else write as normal.
   −
Segment offset (4 bytes)
+
----
 
  −
{| class="wikitable" border="1"
  −
!  Bits
  −
!  Description
  −
|-
  −
| 0-3
  −
| Segment index for table
  −
|-
  −
| 4-31
  −
| Offset into segment
  −
|}
     −
CRO with extension .cro is used for "DLLs". CRS with extension .crs can be used for storing "DLL" symbols as well. The end of the file is aligned to a 0x1000-byte boundary with 0xCC bytes.
+
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.
CRO0 files are usually stored under "romfs:/cro/".
      
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.
 
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".
+
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".
   −
Upon loading, the RO module will look for symbol "__aeabi_atexit" or "nnroAeabiAtexit_".
+
For dumping symbols and loading a CRO into IDA, see [https://github.com/plutooo/ctr/] and [https://github.com/wwylele/IDA_plugin_CRO].
7

edits

Navigation menu