Skip to content

Instantly share code, notes, and snippets.

@joswr1ght
Last active June 8, 2021 11:50
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save joswr1ght/4480de9862284fc74f6e to your computer and use it in GitHub Desktop.
Save joswr1ght/4480de9862284fc74f6e to your computer and use it in GitHub Desktop.
Demonstration code to detect runtime method swizzling with Cydia Substrate/Cycript.
// Compile with:
// clang catchredir.m -o catchredir -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/ -miphoneos-version-min=7 -framework Foundation
#import <Foundation/Foundation.h>
#import <stdio.h>
#import <objc/runtime.h>
@interface UrlConnection : NSObject
@property (strong) NSString *url;
- (void)connect;
@end
@implementation UrlConnection
- (void)connect {
// Connect to a server, or other behavior the attacker wants to change
}
@end
int main() {
Class ucclass = objc_getClass("UrlConnection");
SEL sel = sel_getUid("connect");
IMP runtimeimp, ucconnectimp = class_getMethodImplementation(ucclass, sel);
while(1) {
[NSThread sleepForTimeInterval:10.0f];
ucclass = objc_getClass("UrlConnection");
sel = sel_getUid("connect");
runtimeimp = class_getMethodImplementation(ucclass, sel);
printf("pointer %p and %p\n", ucconnectimp, runtimeimp);
if (runtimeimp != ucconnectimp) printf("Modification Detected\n");
}
return 0;
}
@joswr1ght
Copy link
Author

Running this code on iOS produces output similar to the following:

# ./catchredir
pointer 0x3bd85 and 0x3bd85
pointer 0x3bd85 and 0x3bd85

While this is running, in another terminal attach with Cycript and redirect the connect method in the UrlConnection class:

# cycript -p catchredir
cy# UrlConnection = ObjectiveC.classes["UrlConnection"]
UrlConnection
cy# UrlConnection.messages['connect'] = function() { return; }
function () {return;}

Within 10 seconds, the binary will detect the modification:

pointer 0x3bd85 and 0x3bd85
pointer 0x3bd85 and 0x324000
Modification Detected

@galenzhao
Copy link

galenzhao commented Dec 8, 2016

Hi, how to detect 3rd party lib using method swizzle .

I used your code, but can not detect the following swizzle method.

`

#import "UIViewController+Hook.h"
#import "JRSwizzle.h"

@implementation UIViewController (Hook)

+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSError *error;
BOOL result = [[self class] jr_swizzleMethod:@selector(viewWillAppear:) withMethod:@selector(viewWillAppearHook:) error:&error];
if (!result || error) {
NSLog(@"Can't swizzle methods - %@", [error description]);
}else{
result = [[self class] jr_swizzleMethod:@selector(viewDidDisappear:) withMethod:@selector(viewDidDisappearHook:) error:&error];
if (!result || error) {
NSLog(@"Can't swizzle methods - %@", [error description]);
}
}
});
}

- (void)viewWillAppearHook:(BOOL)animated
{
[self viewWillAppearHook:animated]; // this will call viewWillAppear implementation, because we have exchanged them.
//TODO: add customer code here. This code will work for every ViewController
NSLog(@"viewWillAppearHook for - %@", NSStringFromClass(self.class));
//[TalkingData trackPageBegin:NSStringFromClass(self.class)];

//self.navigationController.navigationBar.translucent = NO;
}

- (void)viewDidDisappearHook:(BOOL)animated
{
[self viewDidDisappearHook:animated]; // this will call viewWillAppear implementation, because we have exchanged them.
//TODO: add customer code here. This code will work for every ViewController
NSLog(@"viewDidDisappearHook for - %@", NSStringFromClass(self.class));
//[TalkingData trackPageEnd:NSStringFromClass(self.class)];
}

@end

`

the detector code

`

- (void)detectMethod{
// @selector()
Class ucclass = objc_getClass("UIViewController");
SEL sel = sel_getUid("viewWillAppear:");
IMP runtimeimp, ucconnectimp = class_getMethodImplementation(ucclass, sel);

while(1) {
[NSThread sleepForTimeInterval:10.0f];
ucclass = objc_getClass("UIViewController");
sel = sel_getUid("viewWillAppear:");
runtimeimp = class_getMethodImplementation(ucclass, sel);
printf("pointer %p and %p\n", ucconnectimp, runtimeimp);
if (runtimeimp != ucconnectimp){ printf("Modification Detected\n");
NSLog(@"[Method Modified] unsafe env");
}
}
//return 0;
}

`

the output logs

`

2016-12-08 10:56:48.643785 x[454:244586] <-[UIViewController(Hook) viewWillAppearHook:]:35>viewWillAppearHook for - UINavigationController
2016-12-08 10:56:48.985530 x[454:244586] <-[UIViewController(Hook) viewWillAppearHook:]:35>viewWillAppearHook for - SliderViewController
2016-12-08 10:56:48.986630 x[454:244586] TalkingData: trackPageBegin()# trackPage begin pageName:SliderViewController
2016-12-08 10:56:48.987476 x[454:244586] <-[UIViewController(Hook) viewWillAppearHook:]:35>viewWillAppearHook for - PersonalCenterViewController
2016-12-08 10:56:48.987893 x[454:244586] TalkingData: trackPageBegin()# trackPage begin pageName:PersonalCenterViewController
2016-12-08 10:56:49.029391 x[454:244586] <-[UIViewController(Hook) viewWillAppearHook:]:35>viewWillAppearHook for - HomeViewController

pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524
pointer 0x100580524 and 0x100580524

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment