CRO0: Difference between revisions
Fix hyperlinks to link to section |
mNo edit summary |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 10: | Line 10: | ||
For dumping symbols and loading a CRO into IDA, see [https://github.com/plutooo/ctr/] and [https://github.com/wwylele/IDA_plugin_CRO]. | For dumping symbols and loading a CRO into IDA, see [https://github.com/plutooo/ctr/] and [https://github.com/wwylele/IDA_plugin_CRO]. | ||
= Structure = | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 218: | Line 220: | ||
|} | |} | ||
Segment Table entry (12 bytes) | ==Segment Table entry (12 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 237: | Line 239: | ||
|} | |} | ||
Named Export Table entry (8 bytes) | ==Named Export Table entry (8 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 252: | Line 254: | ||
|} | |} | ||
Indexed Export Table entry (4 bytes) | ==Indexed Export Table entry (4 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 263: | Line 265: | ||
|} | |} | ||
Named Import Table entry (8 bytes) | ==Named Import Table entry (8 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 278: | Line 280: | ||
|} | |} | ||
Indexed Import Table entry (8 bytes) | ==Indexed Import Table entry (8 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 293: | Line 295: | ||
|} | |} | ||
Anonymous Import Table entry (8 bytes) | ==Anonymous Import Table entry (8 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 308: | Line 310: | ||
|} | |} | ||
Import Module Table entry (20 bytes) | ==Import Module Table entry (20 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 335: | Line 337: | ||
|} | |} | ||
Patch entry (12 bytes) | ==Patch entry (12 bytes)== | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
! Offset | ! Offset | ||
Line 347: | Line 349: | ||
| 0x4 | | 0x4 | ||
| 0x1 | | 0x1 | ||
| Patch type (0= | | Patch type (R_ARM_NONE = 0, R_ARM_ABS32 = 2, R_ARM_REL32 = 3, R_ARM_THM_PC22 = 10, R_ARM_CALL = 28, R_ARM_JUMP24 = 29, R_ARM_TARGET1 = 38, R_ARM_PREL31 = 42) | ||
|- | |- | ||
| 0x5 | | 0x5 | ||
Line 366: | Line 368: | ||
|} | |} | ||
Relocation code from RO: | |||
static Result writePatch(u32* out, u32 patchType, u32 addend, u32 base, u32 inputPtr) { | |||
const s32 branchOffset = inputPtr - base; | |||
u32 offset = base + addend - inputPtr; | |||
if (patchType == R_ARM_NONE) | |||
return 0; | |||
if (patchType == R_ARM_ABS32 || patchType == R_ARM_TARGET1) { | |||
*out = base + addend; | |||
return 0; | |||
} | |||
if (patchType == R_ARM_REL32) { | |||
*out = offset; | |||
return 0; | |||
} | |||
if (patchType == R_ARM_THM_PC22) { | |||
// +-4MB. | |||
if (branchOffset >= 0x400000 || branchOffset <= -0x400000) | |||
return 0xD9012C23; | |||
if (base & 1) { | |||
*out = (((offset >> 12) | 0xF000) << 16) | ((offset << 4) >> 5) | 0xF800; | |||
} else { | |||
if (offset & 2) | |||
offset += 2; | |||
*out = ((offset >> 12) | 0xF000) << 16 | ((offset << 4) >> 5) | 0xE800; | |||
} | |||
return 0; | |||
} | |||
if (patchType == R_ARM_CALL) { | |||
// +-32MB. | |||
if (branchOffset >= 0x2000000 || branchOffset <= -0x2000000) | |||
return 0xD9012C23; | |||
if (base & 1) { | |||
*out = ((offset << 23) & 0x1000000) | ((offset << 6) >> 8) | 0xFA000000; | |||
} else { | |||
*out = 0xEB000000 | ((offset << 6) >> 8); | |||
} | |||
return 0; | |||
} | |||
if (patchType == R_ARM_JUMP24) { | |||
// +-32MB. | |||
if (branchOffset >= 0x2000000 || branchOffset <= -0x2000000 || (base & 1)) | |||
return 0xD9012C23; | |||
*out = (*out & 0xFF000000) | ((offset << 6) >> 8); | |||
return 0; | |||
} | |||
if (patchType == R_ARM_PREL31) { | |||
*out = addend + ((base << 1) >> 1) - inputPtr; | |||
return 0; | |||
} | |||
return 0xD9012C22; | |||
} | |||
== nnroControlObject == | |||
---- | Signature: | ||
Result nnroControlObject(void* arg, u32 type); | |||
{| class="wikitable" border="1" | |||
! Type | |||
! Description | |||
|- | |||
| 0 | |||
| Write address of "nnroEitNode_" to memory pointed by arg (*(u32*)arg = &nnroEitNode_) | |||
|- | |||
| 1 | |||
| Set global in CRO to arg, where arg is the CRO end (g_CRO_end = (u32)arg) | |||
|- | |||
| 2 | |||
| Write CRO end to memory pointed by arg (*(u32*)arg = g_CRO_end) | |||
|- | |||
| 3 | |||
| Write begin, end of function list (C initializers?) to memory pointed by arg (*(u32*)arg = (u32)listBegin, ((u32*)arg)[1] = (u32)listEnd) | |||
|- | |||
| 4 | |||
| Write begin, end of function list (C++ initializers?) to memory pointed by arg (*(u32*)arg = (u32)listBegin, ((u32*)arg)[1] = (u32)listEnd) | |||
|} | |||
"EitNode" are nodes of a linked list containing informations about the main executable + loaded modules: | |||
{| class="wikitable" border="1" | |||
! Index Word | |||
! Type | |||
! Description | |||
|- | |||
| 0 | |||
| EitNode* | |||
| Pointer to the previous element of the list | |||
|- | |||
| 1 | |||
| EitNode* | |||
| Pointer to the next element of the list | |||
|- | |||
| 2 | |||
| u32 | |||
| Module code start, for the main executable this is .text base, for CROs this is the value at CRO+0xB0 | |||
|- | |||
| 3 | |||
| u32 | |||
| Module code end (start + size), for the main executable the size is the size of all mapped sections, for CROs it's the value at CRO+0xB4 | |||
|- | |||
| 4 | |||
| u32* | |||
| Unknown, seems to be an array of u32, probably holds debugging informations | |||
|- | |||
| 5 | |||
| u32* | |||
| This points at the end of the previous array | |||
|- | |||
| 6 | |||
| ElfNode* (?) | |||
| Unknown, this is only set for the main executable node, and it points to itself | |||
|} |