Line 112: |
Line 112: |
| | 0xF0 | | | 0xF0 |
| | 0x04 | | | 0x04 |
− | | Import Modules offset | + | | Import Module Table offset |
| |- | | |- |
| | 0xF4 | | | 0xF4 |
| | 0x04 | | | 0x04 |
− | | Import Modules num (size = num * 20) | + | | Import Module Table num (size = num * 20) |
| |- | | |- |
| | 0xF8 | | | 0xF8 |
Line 226: |
Line 226: |
| |- | | |- |
| | 0x4 | | | 0x4 |
| + | | 0x4 |
| + | | "Segment offset" for export |
| + | |} |
| + | |
| + | Indexed Export Table entry (4 bytes) |
| + | {| class="wikitable" border="1" |
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| + | |- |
| + | | 0x0 |
| | 0x4 | | | 0x4 |
| | "Segment offset" for export | | | "Segment offset" for export |
Line 243: |
Line 254: |
| | 0x4 | | | 0x4 |
| | Offset of the head of a linear list that contains the patches for this import | | | 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 |
| |} | | |} |
| | | |
Line 257: |
Line 325: |
| | 0x4 | | | 0x4 |
| | 0x1 | | | 0x1 |
− | | Patch 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 first 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 +4" (nop). | + | If (addend&1) == 1 then write "b +4" (nop). |
| Else write as normal. | | Else write as normal. |
| | | |
| ---- | | ---- |
| | | |
− | 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. |
Line 290: |
Line 357: |
| 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. | | 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 symbol "__aeabi_atexit" or "nnroAeabiAtexit_". | + | 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 [https://github.com/plutooo/ctr/]. | + | For dumping symbols and loading a CRO into IDA, see [https://github.com/plutooo/ctr/] and [https://github.com/wwylele/IDA_plugin_CRO]. |