Skip to content

Instantly share code, notes, and snippets.

@Lessica
Last active February 28, 2024 11:28
Show Gist options
  • Save Lessica/f762d3b2880d8f3744f657322db73f39 to your computer and use it in GitHub Desktop.
Save Lessica/f762d3b2880d8f3744f657322db73f39 to your computer and use it in GitHub Desktop.
A patch to securityd
#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;
}
@Lessica
Copy link
Author

Lessica commented Aug 13, 2023

This patch was tested on iOS 15.0 and iOS 15.4.1, with Dopamine + ElleKit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment