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+
535UIWindow *alertWindow = NULL ;
636UIWindow *kw = NULL ;
737UIViewController *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
221258void 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