Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System Log came back from the dead #372

Closed
Ram4096 opened this issue Jan 21, 2020 · 6 comments
Closed

System Log came back from the dead #372

Ram4096 opened this issue Jan 21, 2020 · 6 comments
Projects

Comments

@Ram4096
Copy link

Ram4096 commented Jan 21, 2020

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!

@NSExceptional
Copy link
Collaborator

NSExceptional commented Jan 22, 2020

I like this solution! It will be annoying to update fishhook for each new OS each year, but I think I can manage. I will get to this after I finish 4.0.

Thanks again for the detailed issue!

Also, dyld 3 is already in use and if you check that issue it seems it did not affect fishhook

@Ram4096
Copy link
Author

Ram4096 commented Jan 22, 2020

Great! Anyway it's not really annoying, because you just need to replace the fishhook.c file when necessary, the code to hook the C function will be always the same.

@NSExceptional
Copy link
Collaborator

It's not that simple; I will probably need to namespace all of the symbols with flex_ to avoid collisions in apps that use fishook. I think I can write a script to make the process easier though.

@NSExceptional NSExceptional added this to To do in 4.0 Jan 30, 2020
@Ram4096
Copy link
Author

Ram4096 commented Feb 2, 2020

A suggestion: when fishhook support will be implemented, it would be amazing to see more details of NSLog.
For example, my idea is: FLEXSystemLogTableViewCell's accessoryType is UITableViewCellAccessoryDisclosureIndicator and, when FLEXSystemLogTableViewCell is tapped, it opens a new controller that gives additional info, for example where NSLog was called from (a framework? the main binary?), who is the caller (when possible) etc..
This and this might be useful to understand my idea. These should be implemented into static void replaced_nslog(NSString *format, ...) and information should be saved to be viewed later in that section.

@NSExceptional
Copy link
Collaborator

Not a bad idea! This would have to be something you enable manually though because that could take up a lot of memory.

@NSExceptional NSExceptional moved this from To do to In progress in 4.0 Feb 10, 2020
NSExceptional added a commit to NSExceptional/FLEX that referenced this issue Feb 13, 2020
iOS 10 and its associated SDK deprecated *ASL and replaced it with *os_log. This change is widely considered unfavorable and made it extremely tedious for FLEX to intercept log messages reliably.

@Ram4096 has brought to my attention that the os_log functionality is actually just a shim which is conditionally enabled based on what SDK version your binary links with. With a little reverse engineering, I was able to hook the function that tells `NSLog` (well, `CFLogv`) whether os_log should be used or not. This commit uses fishhook to hook `os_log_shim_enabled` to always return `NO` so that the old ASL library is used instead.

Prior to this commit we had code in place to conditionally intercept messages from os_log or ASL based on the iOS version. These checks are not semantically correct since ASL would still be used on iOS 10+ if the binary was built with the iOS 9 SDK. For now, this doesn't matter going forward since we are going to always use ASL, but it might be worth updating the check to instead check for the linked SDK version instead of the OS version.

- *ASL: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/asl.3.html
- *os_log: https://developer.apple.com/documentation/os/logging?language=objc
NSExceptional added a commit to NSExceptional/FLEX that referenced this issue Feb 13, 2020
iOS 10 and its associated SDK deprecated *ASL and replaced it with *os_log. This change is widely considered unfavorable and made it extremely tedious for FLEX to intercept log messages reliably.

@Ram4096 has brought to my attention that the os_log functionality is actually just a shim which is conditionally enabled based on what SDK version your binary links with. With a little reverse engineering, I was able to hook the function that tells `NSLog` (well, `CFLogv`) whether os_log should be used or not. This commit uses fishhook to hook `os_log_shim_enabled` to always return `NO` so that the old ASL library is used instead.

Prior to this commit we had code in place to conditionally intercept messages from os_log or ASL based on the iOS version. These checks are not semantically correct since ASL would still be used on iOS 10+ if the binary was built with the iOS 9 SDK. For now, this doesn't matter going forward since we are going to always use ASL, but it might be worth updating the check to instead check for the linked SDK version instead of the OS version.

- *ASL: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/asl.3.html
- *os_log: https://developer.apple.com/documentation/os/logging?language=objc
@NSExceptional
Copy link
Collaborator

I've added your fix in the 4.0 branch! Closing this. Thanks again for your help! You are credited in the commit message and in code for telling me it was an SDK feature. I took a different approach — I did some digging and hooked os_log_shim_enabled instead of NSLog itself.

@NSExceptional NSExceptional moved this from In progress to Done in 4.0 Feb 13, 2020
timonus pushed a commit to timonus/FLEX that referenced this issue May 1, 2023
iOS 10 and its associated SDK deprecated *ASL and replaced it with *os_log. This change is widely considered unfavorable and made it extremely tedious for FLEX to intercept log messages reliably.

@Ram4096 has brought to my attention that the os_log functionality is actually just a shim which is conditionally enabled based on what SDK version your binary links with. With a little reverse engineering, I was able to hook the function that tells `NSLog` (well, `CFLogv`) whether os_log should be used or not. This commit uses fishhook to hook `os_log_shim_enabled` to always return `NO` so that the old ASL library is used instead.

Prior to this commit we had code in place to conditionally intercept messages from os_log or ASL based on the iOS version. These checks are not semantically correct since ASL would still be used on iOS 10+ if the binary was built with the iOS 9 SDK. For now, this doesn't matter going forward since we are going to always use ASL, but it might be worth updating the check to instead check for the linked SDK version instead of the OS version.

- *ASL: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/asl.3.html
- *os_log: https://developer.apple.com/documentation/os/logging?language=objc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
4.0
  
Done
Development

No branches or pull requests

2 participants