BandarHL / BHTwitter

Awesome tweak for Twitter
1.81k stars 103 forks source link

Fix crash due to unexpected fonts methods. #134

Closed arandomdev closed 1 year ago

arandomdev commented 1 year ago

In twitter 9.47 there are some methods in TAEStandardFontGroup that have arguments,

fontOfSize:
mediumFontOfSize:
boldFontOfSize:
heavyFontOfSize:
monospacedDigitFontOfSize:weight:

The method that these are replaced with don't seem to handle them, so I added a small check to filter these methods out. This has also fixed the crash in #129 for me.

Also, I'm assuming the target methods are like,

- (id)subtext1MediumFont;
- (id)subtext1BoldFont;
- (id)bodyFont;

and don't include methods like,

- (void)_tae_resetFont_subtext3Font;
- (void)_tae_resetFont_subtext3MediumFont;
- (void)_tae_resetFont_subtext3BoldFont;
- (void)_tae_resetFont_subtext2Font;

If so, I believe a better method would be to filter by method type encodings. We would be looking for methods with the following type encoding, @@:. Please let me know if I should use that instead.

BandarHL commented 1 year ago

Thank for the PR. I’m thinking your code is enough but I’m gonna look more on it

BandarHL commented 1 year ago

We can use method_getReturnType for accurate results.

arandomdev commented 1 year ago

That could work, but it’ll include the methods that require arguments, since I believe fontOfSize: also returns id. I suggested type encoding as it would include both the return type and arguments. For @@: it would return an object and have 2 arguments, an object (self) and a selector.

BandarHL commented 1 year ago

The idea here is just accept methods that have a return type otherwise ignore it

BandarHL commented 1 year ago

and for the size of font in the args, we don't need it because when we take the return value (UIFont) we can take size from the UIFont class

arandomdev commented 1 year ago

Unfortunately it seems to crash again with the changes. I can try to look into passing additional arguments and open another PR.

BandarHL commented 1 year ago

And what is the crash log?

BandarHL commented 1 year ago

I'm afraid the problem is from the version of the IPA I was used. check this one: https://drive.google.com/file/d/1p-AWS-yPa4gvCLSn2sC5wKcJZagRUhgh/view?usp=share_link

BandarHL commented 1 year ago

it seems to work fine

arandomdev commented 1 year ago

Yep it still crashes, here is my crash log from earlier. Twitter-2023-03-05-141735.zip

It might be because my iOS version has an extra check? I'm on iOS15.1.

BandarHL commented 1 year ago

Are you sure the issue is from the Font? because I tried with a trollSore device (15.0) with disabled Font feature and the crash is still

BandarHL commented 1 year ago

and with a crash log there is no mention to BHTwitter process

arandomdev commented 1 year ago

I think so, commenting out the TAEStandardFontGroup hook, the crashing stops. And I believe that azule directly injects it into the main app, so it doesn't load any dylibs.

BandarHL commented 1 year ago

and why the crash just for trollstore

BandarHL commented 1 year ago

Maybe the problem for just 15-15.1? https://twitter.com/omega_omelet/status/1632540333505658880

arandomdev commented 1 year ago

Maybe? Right now I'm trying to just forward the arguments to see if that will work. image

It fixes the crashes and custom fonts still work.

BandarHL commented 1 year ago

okay since that fix the problem i'm going to try pass all args. Im sure there is a way in Runtime library

BandarHL commented 1 year ago

After researching, we have two options either ignore methods that have args or pass it throw the replacements. and the best option here is just to ignore it.

BandarHL commented 1 year ago

Try this code

%hook TAEStandardFontGroup
+ (TAEStandardFontGroup *)sharedFontGroup {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSMutableArray *fontsMethods = [NSMutableArray arrayWithArray:@[]];

        unsigned int methodCount = 0;
        Method *methods = class_copyMethodList([self class], &methodCount);
        for (unsigned int i = 0; i < methodCount; ++i) {
            Method method = methods[i];
            char returnType[255];
            char methodType[255];
            method_getReturnType(method, returnType, 255);
            method_getArgumentType(method, i, methodType, 255);
            const char *name = sel_getName(method_getName(method));
            NSString *selector = [NSString stringWithUTF8String:name];

            // Just add methods that have return type.
            if ([@(returnType) containsString:@"@"] && ![@(methodType) containsString:@"@"]) {
                [fontsMethods addObject:selector];
            }
        }
        free(methods);

        originalFontsIMP = [NSMutableDictionary new];
        batchSwizzlingOnClass([self class], [fontsMethods copy], (IMP)TAEStandardFontGroupReplacement);
    });
    return %orig;
}
%end
arandomdev commented 1 year ago

I found a way to pass additional arguments. As long as we don't try access any arguments that aren't there, it should be fine. image

Custom fonts still seem to work, I'll quickly upload this for you to test.

arandomdev commented 1 year ago

Hmm git doesn't like what I did. I'll just make another PR.