Skip to content

Commit 19d905f

Browse files
authored
Merge pull request #1 from Lessica/main
fix: reap lldb proc
2 parents 6ed3b8a + 8d03773 commit 19d905f

4 files changed

Lines changed: 59 additions & 21 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ obj/
77
Payload/
88
*.tipa
99
*.ipa
10-
10+
.cache/
11+
compile_commands.json

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
TARGET := iphone:clang:latest:15.0
2-
INSTALL_TARGET_PROCESSES = SpringBoard appstored installd
2+
INSTALL_TARGET_PROCESSES = SpringBoard appstored installd TrollDecrypt
33
ARCHS = arm64 arm64e
44
THEOS_PACKAGE_SCHEME = rootless
55
THEOS_DEVICE_IP = 192.168.1.32

TDUtils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ void decryptApp(NSDictionary *app);
4141
void decryptAppWithPID(pid_t pid);
4242
void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version, pid_t lldb_pid);
4343
pid_t attachLLDBToProcessByName(const char *executableName, pid_t target_pid);
44-
void continueLLDBProcess(pid_t lldb_pid);
4544
void detachLLDB(pid_t lldb_pid);
4645
NSArray *decryptedFileList(void);
4746
NSString *docPath(void);

TDUtils.m

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,36 @@
22
#import "TDDumpDecrypted.h"
33
#import "LSApplicationProxy+AltList.h"
44

5+
static NSString *getLogPath(void) {
6+
return [NSTemporaryDirectory() stringByAppendingPathComponent:@"lldb_output.log"];
7+
}
8+
9+
static BOOL waitForContentOfFileSync(NSString *filePath, NSString *content, NSTimeInterval timeout) {
10+
int fd = open([filePath UTF8String], O_EVTONLY);
11+
if (fd == -1) {
12+
NSLog(@"[trolldecrypt] Failed to open file for monitoring: %@", filePath);
13+
return NO;
14+
}
15+
16+
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
17+
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
18+
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_WRITE, queue);
19+
dispatch_source_set_event_handler(source, ^{
20+
NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
21+
if ([fileContent containsString:content]) {
22+
NSLog(@"[trolldecrypt] File content matched: %@", filePath);
23+
dispatch_semaphore_signal(semaphore);
24+
}
25+
});
26+
dispatch_resume(source);
27+
28+
int rc = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)));
29+
dispatch_source_cancel(source);
30+
close(fd);
31+
32+
return (rc == 0);
33+
}
34+
535
UIWindow *alertWindow = NULL;
636
UIWindow *kw = NULL;
737
UIViewController *root = NULL;
@@ -120,13 +150,27 @@ void decryptApp(NSDictionary *app) {
120150
return;
121151
}
122152

153+
// Kill existing process if any
154+
NSArray *processes;
155+
NSLog(@"[trolldecrypt] kill existing process if any...");
156+
processes = sysctl_ps();
157+
for (NSDictionary *process in processes) {
158+
NSString *proc_name = process[@"proc_name"];
159+
if ([proc_name isEqualToString:binaryName]) {
160+
pid_t pid = [process[@"pid"] intValue];
161+
NSLog(@"[trolldecrypt] Found app PID: %d (existing)", pid);
162+
kill(pid, SIGKILL);
163+
break;
164+
}
165+
}
166+
123167
NSLog(@"[trolldecrypt] launch app and lldb force pause...");
124-
[[UIApplication sharedApplication] launchApplicationWithIdentifier:bundleID suspended:NO];
125-
sleep(2); // Wait for lldb to catch the app
168+
[[UIApplication sharedApplication] launchApplicationWithIdentifier:bundleID suspended:YES]; // Launch app in suspended state
169+
waitForContentOfFileSync(getLogPath(), @"Architecture set to", 30.0); // Wait for lldb to attach
126170

127171
// Get PID after lldb caught it
128172
pid_t pid = -1;
129-
NSArray *processes = sysctl_ps();
173+
processes = sysctl_ps();
130174
for (NSDictionary *process in processes) {
131175
NSString *proc_name = process[@"proc_name"];
132176
if ([proc_name isEqualToString:binaryName]) {
@@ -167,13 +211,12 @@ pid_t attachLLDBToProcessByName(const char *executableName, pid_t target_pid) {
167211

168212
NSString *scriptPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"lldb_attach.txt"];
169213
NSString *scriptContent = [NSString stringWithFormat:
170-
@"process attach --name %s --waitfor\n", executableName];
214+
@"process attach --name '%s' --waitfor\n", executableName]; // TODO: shell-escape executableName
171215
[scriptContent writeToFile:scriptPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
172-
173-
NSString *logPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"lldb_output.log"];
216+
NSString *logPath = getLogPath();
174217

175218
pid_t lldb_pid = 0;
176-
const char *lldb_path = "/var/jb/usr/bin/lldb"; //please edit to use auto scheme for rootful/roothide, i'm lazy and forgot to do it
219+
const char *lldb_path = "/var/jb/usr/bin/lldb"; // TODO: please edit to use auto scheme for rootful/roothide, i'm lazy and forgot to do it
177220
const char *args[] = {
178221
"lldb",
179222
"-s", [scriptPath UTF8String], // Source script file
@@ -193,7 +236,8 @@ pid_t attachLLDBToProcessByName(const char *executableName, pid_t target_pid) {
193236
NSLog(@"[trolldecrypt] lldb spawned done, lldb PID: %d", lldb_pid);
194237
NSLog(@"[trolldecrypt] lldb output: %@", logPath);
195238

196-
sleep(2);
239+
waitForContentOfFileSync(logPath, @"process attach --name", 5.0);
240+
sleep(1); // Give lldb a moment to settle
197241

198242
// Verify lldb is still running
199243
if (kill(lldb_pid, 0) == 0) {
@@ -210,13 +254,6 @@ pid_t attachLLDBToProcessByName(const char *executableName, pid_t target_pid) {
210254
return lldb_pid;
211255
}
212256

213-
//i was trying to make sure the app is paused before killed, but not success... can anyone help!?
214-
void continueLLDBProcess(pid_t lldb_pid) {
215-
if (lldb_pid <= 0) return;
216-
217-
NSLog(@"[trolldecrypt] 'continue' to lldb (PID: %d)", lldb_pid);
218-
}
219-
220257
// Detach lldb from process
221258
void detachLLDB(pid_t lldb_pid) {
222259
if (lldb_pid > 0) {
@@ -232,6 +269,10 @@ void detachLLDB(pid_t lldb_pid) {
232269
}
233270

234271
NSLog(@"[trolldecrypt] lldb detached successfully");
272+
273+
// Reap the lldb process
274+
int unused;
275+
waitpid(lldb_pid, &unused, WNOHANG);
235276
}
236277
}
237278

@@ -282,9 +323,6 @@ void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version, pid_t l
282323
[dd createIPAFile:pid];
283324
NSLog(@"[trolldecrypt] Decryption complete!");
284325

285-
continueLLDBProcess(lldb_pid);
286-
sleep(1);
287-
288326
NSLog(@"[trolldecrypt] Detaching lldb...");
289327
detachLLDB(lldb_pid);
290328

0 commit comments

Comments
 (0)