Skip to content

Commit

Permalink
Add offset finder for iPadOS override
Browse files Browse the repository at this point in the history
  • Loading branch information
khanhduytran0 committed Oct 12, 2024
1 parent a899ed6 commit fac213e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
55 changes: 55 additions & 0 deletions FindCacheDataOffset.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@import Foundation;
@import Darwin;
@import MachO;

__attribute__((constructor)) void FindCacheDataOffset() {
/*
* TL;DR: finding CacheData value offset is as follows:
* - Get a pointer to the corresponding obfuscated key in libMobileGestalt
* - Get a pointer to an unknown struct, whose first pointer is the pointer to the obfuscated key
* - Offset it by 0x9a (FIXME this lol), read it as uint16_t
* - Shift left the resulting offset by 3 bits
*/

const struct mach_header_64 *header = NULL;
const char *mgName = "/usr/lib/libMobileGestalt.dylib";
const char *mgKey = "mtrAoWJ3gsq+I90ZnQ0vQw";
dlopen(mgName, RTLD_GLOBAL);

for (int i = 0; i < _dyld_image_count(); i++) {
if (!strncmp(mgName, _dyld_get_image_name(i), strlen(mgName))) {
header = (const struct mach_header_64 *)_dyld_get_image_header(i);
break;
}
}
assert(header);

// Get a pointer to the corresponding obfuscated key in libMobileGestalt
size_t textCStringSize;
const char *textCStringSection = (const char *)getsectiondata(header, "__TEXT", "__cstring", &textCStringSize);
for (size_t size = 0; size < textCStringSize; size += strlen(textCStringSection + size) + 1) {
if (!strncmp(mgKey, textCStringSection + size, strlen(mgKey))) {
textCStringSection += size;
break;
}
}

// Get a pointer to an unknown struct, whose first pointer is the pointer to the obfuscated key
size_t constSize;
// arm64e
const uintptr_t *constSection = (const uintptr_t *)getsectiondata(header, "__AUTH_CONST", "__const", &constSize);
if (!constSection) {
// arm64, FIXME: is this correct?
constSection = (const uintptr_t *)getsectiondata(header, "__DATA_CONST", "__const", &constSize);
}
for (int i = 0; i < constSize / 8; i++) {
if (constSection[i] == (uintptr_t)textCStringSection) {
constSection += i;
break;
}
}

// FIXME: is offset of offset consistent?
off_t offset = (off_t)((uint16_t *)constSection)[0x9a/2] << 3;
[NSUserDefaults.standardUserDefaults setInteger:offset forKey:@"MGCacheDataDeviceClassNumberOffset"];
}
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ libEMProxy_FRAMEWORKS = Security
libEMProxy_INSTALL_PATH = /Applications/$(APPLICATION_NAME).app/Frameworks

# libimobiledevice + minimuxer
libimobiledevice_FILES = idevicebackup2.c
libimobiledevice_CFLAGS = -Iinclude
libimobiledevice_FILES = idevicebackup2.c FindCacheDataOffset.m
libimobiledevice_CFLAGS = -Iinclude -fobjc-arc
libimobiledevice_LDFLAGS = \
-force_load lib/libimobiledevice-1.0.a \
-force_load lib/libimobiledevice-glue-1.0.a \
Expand Down
2 changes: 1 addition & 1 deletion Sources/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ Thanks to:
func bindingForTrollPad() -> Binding<Bool> {
// We're going to overwrite DeviceClassNumber but we can't do it via CacheExtra, so we need to do it via CacheData instead
// However, CacheData is still a black box, as nobody has yet to document this data, so we're leaving a hardcoded offset for now
let valueOffset = 0x2e0
let valueOffset = UserDefaults.standard.integer(forKey: "MGCacheDataDeviceClassNumberOffset")
let cacheData = mobileGestalt["CacheData"] as! NSMutableData
//print("Read value from \(cacheData.mutableBytes.load(fromByteOffset: valueOffset, as: Int.self))")

Expand Down

0 comments on commit fac213e

Please sign in to comment.