Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-c IOS arm64 method swizzling fail to call original method

I use standard method swizzling on ARMv7 IOS devices and it works perfect to me.

But when I compile my code for arm64 - it fails to call original method from new method

Main purpose of my swizzling - to use parameter from internal method of my application in another method.

I have original method -(void)insertdata:(id)text and I want to change it on -(void)patchedCall:(id)text and call original method in new method.

Code:

static IMP sOriginalImp = NULL;

@interface TextOverrides: NSObject
+(void)load;
-(void)patchedinsert:(id)text;
@end

@implementation TextOverrides

+(void)load
{
    //Get Implementation of original method

    Class originalClass = NSClassFromString(@"DataViewController");
    Method originalMeth = class_getInstanceMethod(originalClass, @selector(insertdata:));

    //Save original method implementation
    sOriginalImp = method_getImplementation(originalMeth);

    // Get implementation of replacement method
    Method replacementMeth = class_getInstanceMethod(NSClassFromString(@"TextOverrides"), @selector(patchedCall:));

    //Replace methods
    method_exchangeImplementations(originalMeth, replacementMeth);
}

-(void)patchedCall:(id)text
{
    @synchronized(self){
        //Call of original method that we save
        sOriginalImp(self, @selector(insertdata:), text);

        //Make our code for argument "text"
        printf("Here is data%s\n", [text UTF8String]);
    }
}

@end

Code fails on calling original method on arm64 architecture:

//Call of original method that we save
sOriginalImp(self, @selector(insertdata:), text);

How can I improve my code to work both on armv7 and arm64?

like image 379
Yakov Avatar asked Nov 01 '22 13:11

Yakov


1 Answers

With the discussion on https://github.com/square/PonyDebugger/issues/84 I think the gist is https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html#//apple_ref/doc/uid/TP40013501-CH3-SW22 and the fact that IMP is defined as a variadic function and you call it with fixed arguments. In my case, casting the function pointer to the real signature fixed the crash. I believe in your case, something like

//Call of original method that we save
((void(*)(id, SEL, id))ssOriginalImp)(self, @selector(insertdata:), text);

could fix the crash.

like image 155
ashcatch Avatar answered Nov 15 '22 07:11

ashcatch