-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
A long time ago some developers complained about an issue for the System Log feature implemented in FLEX. #140
This feature was able to capture all NSLogs. In the referenced issue, we can discover that it was caused by ASL on iOS 10 and newer, replaced by OS Log, so FLEX couldn't capture logs.
Today I have more details about this issue, and a possible solution:
- Using FLEX with the old ASL behavior, FLEX is able to capture NSLogs if the app / tweak where the NSLog is called from is compiled using the iOS 9 SDK. This is because ASL is on the iOS 9 SDK, so FLEX is able to use it also on newer iOS versions.
- Using Fishhook, a powerful code that's able to hook C functions, is possible to capture all NSLogs from any iOS version that fishhook supports (probably it targets the same version of FLEX).
You can test what I said using the following code. For example, I'm using an app compiled using the iOS 13 SDK, but my tweak (so I'm in a jailbroken environment) is compiled using the iOS 9.3 SDK. I restored the old behavior of FLEX (so FLEX will consider ASL again), and I'm able to see the NSLog coded in my tweak.
This is how I've restored the old ASL behavior (but it works only if the tweak/app where NSLog is called is compiled using the iOS 9 SDK, so it's not something related to the system):
%hook FLEXOSLogController
+ (instancetype)withUpdateHandler:(void(^)(NSArray<FLEXSystemLogMessage *> *newMessages))newMessagesHandler {
return [%c(FLEXASLLogController) performSelector:@selector(withUpdateHandler:) withObject:newMessagesHandler];
}
%end
%hook FLEXOSLogController
- (id)init {
self = %orig;
if (self) {
[self setValue:@(NSProcessInfo.processInfo.processIdentifier) forKey:@"_filterPid"];
[self setValue:@NO forKey:@"_levelInfo"];
[self setValue:@NO forKey:@"_subsystemInfo"];
}
return self;
}
%end
Note: this code should be used if you use a tweak compiled using the iOS 9 SDK and you would like to see NSLogs directly in FLEX.
Using the ASL behavior, FLEX is able to capture NSLog on iOS 12, if the tweak is compiled using a SDK where ASL worked.
But, seen that we are looking for a general solution that works on any SDK and on a no-jailbroken environment too, we can opt for fishhook (yes, it works on no-jailbroken iOS versions):
#import "fishhook.h"
#import <Foundation/Foundation.h>
static void (*orig_nslog)(NSString *format, ...);
static void replaced_nslog(NSString *format, ...) {
va_list vl;
va_start(vl, format);
NSString* str = [[NSString alloc] initWithFormat:format arguments:vl];
va_end(vl);
orig_nslog(str);
// Here do your operations to save str and [NSDate date] (for example you can create a new string that has [NSDate date] as prefix and "str" as suffix, saving it in a NSMutableArray that you will use as source where the new System Log section reads NSLogs.
}
rebind_symbols((struct rebinding[1]){"NSLog",(void*)replaced_nslog,(void**)&orig_nslog},1);
The rebind_symbols
function should be called once. I'm not sure if it works system-wide (for example in the SpringBoard on jailbroken devices), but it works in apps.
Fishhook is amazing, it's maintained from Facebook and updated to support new iOS versions (when it's necessary). The only bad thing is that it might not work when Apple decides to enable Dyld 3.0, but we cannot know until they do that.
At the moment this is the best solution to capture NSLogs using FLEX. Give it a test!