Created
May 29, 2021 20:24
-
-
Save NyanSatan/0c49c8548179d9558e231b577cdd326a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
arm_clean_dcache_line() weirdness | |
27 Dec 2020 12:12 MSK | |
At some point of my iPhone 5 SecureROM research, I've *decided* to REDACTED. After the process I was quite tired, so I was just looking at different functions in the ROM for no particular reason. One of the functions was platform_get_boot_trampoline(): | |
void *platform_get_boot_trampoline() | |
{ | |
#define TRAMPOLINE_SIZE 0x40 | |
void *buffer; | |
unsigned int i; | |
buffer = malloc(TRAMPOLINE_SIZE); | |
memmove(buffer, &trampoline, TRAMPOLINE_SIZE); | |
for (i = buffer; i < buffer + TRAMPOLINE_SIZE; i += CPU_CACHELINE_SIZE) | |
arm_clean_dcache_line(i); | |
return buffer; | |
} | |
This function allocates a buffer in heap, copies a boot trampoline there, cleans data cache for this buffer and then returns the buffer's pointer to a caller | |
The boot trampoline disables SecureROM effectively removing it from memory forever: | |
void trampoline(entry_t entry) | |
{ | |
((*(volatile u_int32_t *)SECURITY_REG) |= ROM_READ_DISABLE; | |
entry(0, 0, 0, 0); | |
} | |
That's why it obviously needs to run from SRAM | |
But the suspicious part is how it cleans caches: | |
arm_clean_dcache_line: | |
MCR p15, 0, R0, c7, c10, 1 | |
ISB SY | |
BX LR | |
I have to be honest with you - I have got close to none ideas about how caches work on ARM (especially custom ARM, like Apple Swift) and what the MCR/MRS/MSR/whatever cryptic sequences mean, so I simply searched for that very sequence in the stolen iBoot source code (it was normalized to their style, of course): | |
ARM_FUNCTION _arm_clean_dcache_line | |
mcr p15, 0, r0, c7, c10, 1 // clean L1/L2 line by MVA | |
dmb | |
bx lr | |
(arch/arm/cache_v7.S:57) | |
Looks the same, except they use DMB instead of ISB. Seems suspicious, indeed, even to me (I don't know how the caches work, remember?) | |
Few months later I realized I have many more 32-bit SecureROMs I can compare with! (I'm dumb, yeah) | |
The first one I took was the S5L8747 one (iBoot-1413.8): | |
arm_clean_dcache_line: | |
MCR p15, 0, R0, c7, c10, 1 | |
DMB SY | |
BX LR | |
And wow! It has DMB instead of ISB! | |
Well, maybe it's because of little bit different architectures (Cortex-A5 vs. Apple Swift)? Who knows... but maybe better let's compare this function in ROMs that belong to platforms that has the same architecture? Luckily for us, we have 2 different platforms with yet same architecture and whose bootroms were built in different years - one most likely even earlier than A6' one, and another later than Haywire' one - these are S5L8942 (unknown version) and S5L8947 (iBoot-1458.2). Here are results: | |
arm_clean_dcache_line: | |
MCR p15, 0, R0, c7, c10, 1 | |
ISB SY | |
BX LR | |
arm_clean_dcache_line: | |
MCR p15, 0, R0, c7, c10, 1 | |
DMB SY | |
BX LR | |
Ha! Different! More and more I'm becoming confident about that it was a bug in older ROMs rather than a feature! But can this be used to get code execution? That's to be discovered yet! The function is used while MMU setup, in platform_cache_operation() and of course while preparing the boot trampoline (remember @iH8sn0w's words about code-execution between bootrom and LLB?) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment