Last active
February 28, 2024 11:28
-
-
Save Lessica/f762d3b2880d8f3744f657322db73f39 to your computer and use it in GitHub Desktop.
A patch to securityd
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
#import <Foundation/Foundation.h> | |
#import <os/log.h> | |
#define FAKE_BASE 0x100000000 | |
#define FAKE_PAGE 4096 | |
template <unsigned B> inline int64_t SignExtend64(uint64_t x) { | |
static_assert(B > 0, "Bit width can't be 0."); | |
static_assert(B <= 64, "Bit width out of range."); | |
return int64_t(x << (64 - B)) >> (64 - B); | |
} | |
struct Adrp { | |
uint32_t destRegister; | |
int64_t addend; | |
}; | |
struct Add { | |
uint8_t destRegister; | |
uint8_t srcRegister; | |
uint32_t addend; | |
}; | |
static bool parseAdrp(uint32_t insn, Adrp *adrp) { | |
if ((insn & 0x9f000000) != 0x90000000) | |
return false; | |
adrp->destRegister = insn & 0x1f; | |
uint64_t immHi = (insn >> 5) & 0x7ffff; | |
uint64_t immLo = (insn >> 29) & 0x3; | |
uint64_t imm = SignExtend64<21>(immLo | (immHi << 2)); | |
adrp->addend = imm * FAKE_PAGE; | |
return true; | |
} | |
static bool parseAdd(uint32_t insn, Add *add) { | |
if ((insn & 0xffc00000) != 0x91000000) | |
return false; | |
add->destRegister = insn & 0x1f; | |
add->srcRegister = (insn >> 5) & 0x1f; | |
add->addend = (insn >> 10) & 0xfff; | |
return true; | |
} | |
int main(int argc, const char * argv[]) { // this should be a constructor in your tweak... | |
@autoreleasepool { | |
const void *thisImage = [[NSData dataWithContentsOfFile:@"securityd"] bytes]; | |
uint8_t *base = (uint8_t *)thisImage; // use MSGetImage or dlopen instead in your tweak... | |
uint8_t *funcBase = (uint8_t *)thisImage + 0x67b4; // use MSFindSymbol or dlsym instead in your tweak... | |
os_log_debug(OS_LOG_DEFAULT, "got _fill_security_client: %p", (void *)(funcBase - base + FAKE_BASE)); | |
uint32_t *adrpPtr = (uint32_t *)funcBase; | |
uint32_t *adrpEnd = (uint32_t *)funcBase + 0x200; | |
uint32_t *got = NULL; | |
while (adrpPtr < adrpEnd) { | |
uint64_t uPtr = ((uint8_t *)adrpPtr - base + FAKE_BASE); | |
os_log_debug(OS_LOG_DEFAULT, "%p: %02X %02X %02X %02X ", | |
(uint32_t *)uPtr, *((uint8_t *)adrpPtr), | |
*((uint8_t *)adrpPtr + 1), *((uint8_t *)adrpPtr + 2), | |
*((uint8_t *)adrpPtr + 3)); | |
struct Adrp adrp; | |
struct Add add; | |
if (parseAdrp(*adrpPtr, &adrp) && parseAdd(*(adrpPtr + 1), &add)) { | |
if (adrp.destRegister == add.srcRegister) { | |
uint64_t uPage = ((uint64_t)uPtr & ~0xfff); | |
os_log_debug(OS_LOG_DEFAULT, "adrp x%d, #0x%llx", adrp.destRegister, uPage + adrp.addend); | |
os_log_debug(OS_LOG_DEFAULT, "add x%d, x%d, #0x%x", add.destRegister, add.srcRegister, add.addend); | |
uint8_t *ptr = (uint8_t *)(uPage + adrp.addend + add.addend); | |
uint64_t *realPtr = (uint64_t *)(ptr - FAKE_BASE + (uint64_t)base); | |
uint64_t offset = (*(realPtr + 2) & ~0x10000000000000); | |
uint64_t len = *(realPtr + 3); | |
if (len == 1) { | |
os_log_debug(OS_LOG_DEFAULT, "real offset = 0x%llx, length = %llu", offset, len); | |
got = adrpPtr; | |
break; | |
} | |
} | |
} | |
adrpPtr++; | |
} | |
if (got) { | |
got += 4; | |
// check if the instruction got is a CBZ | |
// *011010? 00000000 00000000 00000000 | |
// bit 23-5: imm19 | |
if ((*got & 0xff000000) == 0xb4000000 || (*got & 0xff000000) == 0x34000000) { | |
os_log_debug(OS_LOG_DEFAULT, "got cbz"); | |
// change it to cbnz (bit 24 0->1) | |
// uint32_t modified = *got | 0x01000000; | |
// MSHookMemory((void *)got, &modified, sizeof(uint32_t)); | |
uint32_t imm19 = (*got & 0x00ffffe0) >> 5; | |
uint32_t bInst = 0x14000000 | imm19; | |
os_log_debug(OS_LOG_DEFAULT, "bInst = 0x%08x\n", bInst); | |
// uncomment this line in your tweak... | |
// MSHookMemory((void *)got, &bInst, sizeof(uint32_t)); | |
} | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This patch was tested on iOS 15.0 and iOS 15.4.1, with Dopamine + ElleKit.