Skip to content

Commit 2214243

Browse files
committed
Enhance filesystem access initialization and logging in FileUtils and FileManagerView for improved debugging and error handling
1 parent 4f5033d commit 2214243

3 files changed

Lines changed: 141 additions & 13 deletions

File tree

lara/pe/fileutils.m

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,18 @@ + (BOOL)enableSandboxAccess:(NSString *)path {
214214

215215
+ (BOOL)initializeFilesystemAccess {
216216
printf("FILE-UTILS: initializeFilesystemAccess called\n");
217-
printf("FILE-UTILS: Initializing filesystem access for /private/var...\n");
217+
printf("FILE-UTILS: Attempting to enable full filesystem access via root token...\n");
218218

219-
// Enable access to /private/var specifically with sandbox token
220-
// This grants access to the target directory through sandbox extensions
221-
printf("FILE-UTILS: Calling enableSandboxAccessCached(@\"/private/var\")\n");
219+
// Try to get root token first for maximum access
220+
printf("FILE-UTILS: Calling enableSandboxAccessCached(@\"/\") for root access\n");
221+
if ([self enableSandboxAccessCached:@"/"]) {
222+
printf("FILE-UTILS: Successfully enabled root access via sandbox token\n");
223+
return YES;
224+
}
225+
226+
printf("FILE-UTILS: Root token failed, falling back to /private/var\n");
222227
if (![self enableSandboxAccessCached:@"/private/var"]) {
223-
printf("FILE-UTILS ERROR: Failed to enable /private/var access\n");
228+
printf("FILE-UTILS ERROR: Failed to enable both root and /private/var access\n");
224229
return NO;
225230
}
226231

lara/pe/sandbox.m

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
#include <string.h>
1414
#include <dlfcn.h>
1515

16+
// Kernel read/write imports from Darksword exploit
17+
extern uint64_t ds_kread64(uint64_t address);
18+
extern uint32_t ds_kread32(uint64_t address);
19+
extern void ds_kwrite64(uint64_t address, uint64_t value);
20+
extern void ds_kwrite32(uint64_t address, uint32_t value);
21+
extern void ds_kread(uint64_t address, void *buffer, uint64_t size);
22+
extern void ds_kwrite(uint64_t address, void *buffer, uint64_t size);
23+
1624
// Sandbox extension token handling
1725
typedef const struct __sandbox_extension_token * sandbox_extension_t;
1826

@@ -27,12 +35,56 @@ typedef int (*sandbox_extension_issue_file_t)(const char *extension_class, int s
2735
static sandbox_extension_consume_t real_sandbox_extension_consume = NULL;
2836
static sandbox_extension_release_t real_sandbox_extension_release = NULL;
2937

38+
/**
39+
* Attempt to patch sandbox extension policy in kernel memory
40+
* Based on iOS 18.3 sandbox escape that rewrites extension class names
41+
* This searches kernel memory for sandbox extension class strings and patches them
42+
*/
43+
static void patch_sandbox_in_kernel(void) {
44+
printf("SANDBOX: Attempting kernel memory sandbox patching...\n");
45+
fflush(stdout);
46+
47+
// These are common sandbox extension class strings we might find in kernel
48+
const char *target_strings[] = {
49+
"com.apple.sandbox.container",
50+
"com.apple.app-sandbox",
51+
"http://com.apple",
52+
"app-sandbox",
53+
};
54+
55+
const char *replacement = "com.apple.app-sandbox.read-write";
56+
size_t replacement_len = strlen(replacement);
57+
58+
printf("SANDBOX: Warning - kernel memory patching is complex and device-specific\n");
59+
printf("SANDBOX: This requires matching iOS version-specific offsets\n");
60+
printf("SANDBOX: Attempting to patch sandbox policy...\n");
61+
fflush(stdout);
62+
63+
// Note: The actual patching would require finding the exact kernel structures
64+
// and offsets for this specific iOS version and device. This is a placeholder
65+
// for the approach described in the sandbox escape tweets.
66+
//
67+
// In a real implementation, you would:
68+
// 1. Find kernel slide from Darksword
69+
// 2. Locate sandbox policy structures at known offsets
70+
// 3. Identify the extension class string location
71+
// 4. Patch it using ds_kwrite
72+
73+
// For now, we just log that we attempted this approach
74+
printf("SANDBOX: Kernel patching approach - would require device-specific offsets\n");
75+
printf("SANDBOX: Falling back to API-level approaches\n");
76+
fflush(stdout);
77+
}
78+
3079
static void init_sandbox_apis(void) {
3180
static dispatch_once_t onceToken;
3281
dispatch_once(&onceToken, ^{
3382
printf("SANDBOX: Initializing sandbox APIs via dlsym...\n");
3483
fflush(stdout);
3584

85+
// Attempt kernel memory patching first (iOS 18 sandbox escape technique)
86+
patch_sandbox_in_kernel();
87+
3688
// Try to find the sandbox functions in the loaded framework
3789
// These are private APIs, so they might be in different places depending on iOS version
3890
void *handle = dlopen(NULL, RTLD_GLOBAL);
@@ -94,6 +146,9 @@ static void init_sandbox_apis(void) {
94146
* Based on the tweet approach for unrestricted file access
95147
*/
96148
char* getTokenForPath(const char *path) {
149+
printf("SANDBOX DEBUG: getTokenForPath START\n");
150+
fflush(stdout);
151+
97152
if (!path) {
98153
printf("SANDBOX: getTokenForPath called with NULL path\n");
99154
fflush(stdout);
@@ -104,13 +159,17 @@ static void init_sandbox_apis(void) {
104159
fflush(stdout);
105160

106161
init_sandbox_apis();
162+
printf("SANDBOX DEBUG: After init_sandbox_apis\n");
163+
fflush(stdout);
107164

108165
if (!real_sandbox_extension_issue_file) {
109-
printf("SANDBOX ERROR: sandbox_extension_issue_file not found at runtime\n");
166+
printf("SANDBOX ERROR: sandbox_extension_issue_file not found at runtime (NULL pointer)\n");
110167
fflush(stdout);
111168
return NULL;
112169
}
113170

171+
printf("SANDBOX: sandbox_extension_issue_file found at: %p\n", real_sandbox_extension_issue_file);
172+
fflush(stdout);
114173
printf("SANDBOX: Calling sandbox_extension_issue_file for: %s\n", path);
115174
fflush(stdout);
116175

@@ -121,13 +180,35 @@ static void init_sandbox_apis(void) {
121180
kSBXExtensionClass_ReadWrite,
122181
kSBXExtensionClass_Read,
123182
kSBXExtensionClass_Write,
124-
kSBXExtensionClass_Empty
183+
kSBXExtensionClass_Empty,
184+
NULL // Try NULL as last resort
125185
};
126186

127187
int result = -1;
128-
for (int i = 0; i < 4; i++) {
188+
printf("SANDBOX DEBUG: Starting extension class loop\n");
189+
fflush(stdout);
190+
191+
for (int i = 0; extension_classes[i] != NULL || i == 4; i++) {
129192
const char *ext_class = extension_classes[i];
130-
printf("SANDBOX: Trying extension class: '%s'\n", ext_class);
193+
194+
// Safely log even if pointer is unusual
195+
if (ext_class) {
196+
printf("SANDBOX DEBUG: Loop iteration %d, ext_class='%s'\n", i, ext_class);
197+
} else {
198+
printf("SANDBOX DEBUG: Loop iteration %d, ext_class=NULL\n", i);
199+
}
200+
fflush(stdout);
201+
202+
// Extra safety: check function pointer again
203+
if (!real_sandbox_extension_issue_file) {
204+
printf("SANDBOX ERROR: Function pointer became NULL in loop!\n");
205+
fflush(stdout);
206+
break;
207+
}
208+
209+
// Call the API - be very explicit about parameters
210+
printf("SANDBOX DEBUG: About to call sandbox_extension_issue_file(ext_class=%p, flags=0, path=%p, token_out=%p)\n",
211+
ext_class, (void*)path, &token);
131212
fflush(stdout);
132213

133214
result = real_sandbox_extension_issue_file(
@@ -137,18 +218,21 @@ static void init_sandbox_apis(void) {
137218
&token
138219
);
139220

140-
printf("SANDBOX: Result for '%s': error=%d, token=%p\n", ext_class, result, token);
221+
printf("SANDBOX: Extension class '%s': result=%d, token=%p\n",
222+
ext_class ? ext_class : "NULL", result, token);
141223
fflush(stdout);
142224

143225
if (result == 0 && token != NULL) {
144-
printf("SANDBOX: SUCCESS with extension class: '%s'\n", ext_class);
226+
printf("SANDBOX: SUCCESS with extension class: '%s'\n", ext_class ? ext_class : "NULL");
145227
fflush(stdout);
146228
break;
147229
}
148230
token = NULL;
231+
232+
if (extension_classes[i] == NULL) break; // Exit after NULL attempt
149233
}
150234

151-
printf("SANDBOX: sandbox_extension_issue_file returned: %d, token: %p\n", result, token);
235+
printf("SANDBOX DEBUG: Loop complete, result=%d, token=%p\n", result, token);
152236
fflush(stdout);
153237

154238
if (result != 0 || !token) {

lara/views/FileManagerView.swift

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,46 @@ class FileUtilsBridge: NSObject {
294294

295295
globallogger.log("[Bridge] listDirectory attempting to enumerate: \(path)")
296296

297-
// With sandbox tokens enabled at init, FileManager should now have access
297+
// First try kernel VFS which has unrestricted access
298+
globallogger.log("[Bridge] Attempting VFS approach for: \(path)")
299+
if let vfsItems = FileUtils.listDirectoryVFS(path) {
300+
globallogger.log("[Bridge] VFS succeeded with \(vfsItems.count) entries")
301+
for name in vfsItems {
302+
let fullPath = (path as NSString).appendingPathComponent(name)
303+
304+
guard let attrs = try? FileManager.default.attributesOfItem(atPath: fullPath) else {
305+
globallogger.log("[Bridge] Could not get attrs for: \(name)")
306+
// Still add it even without attrs
307+
let item = FileItem(
308+
name: name,
309+
path: fullPath,
310+
isDirectory: false,
311+
size: 0,
312+
modifiedDate: Date()
313+
)
314+
items.append(item)
315+
continue
316+
}
317+
318+
let isDir = attrs[.type] as? String == FileAttributeType.typeDirectory.rawValue
319+
let size = (attrs[.size] as? NSNumber)?.uint64Value ?? 0
320+
let modDate = (attrs[.modificationDate] as? Date) ?? Date()
321+
322+
let item = FileItem(
323+
name: name,
324+
path: fullPath,
325+
isDirectory: isDir,
326+
size: size,
327+
modifiedDate: modDate
328+
)
329+
items.append(item)
330+
}
331+
globallogger.log("[Bridge] Created \(items.count) FileItem objects from VFS")
332+
return items
333+
}
334+
335+
// Fall back to FileManager if VFS fails
336+
globallogger.log("[Bridge] VFS failed, falling back to FileManager for: \(path)")
298337
guard let enumerator = try? FileManager.default.contentsOfDirectory(
299338
atPath: path
300339
) else {

0 commit comments

Comments
 (0)