Git Product home page Git Product logo

eleme / stinger Goto Github PK

View Code? Open in Web Editor NEW
990.0 22.0 127.0 1.63 MB

Stinger is a high-efficiency library with great compatibility, for aop in Objective-C, using libffi instead of Objective-C message forwarding. It is 20+ times faster than the Aspects, from message-sending to Aspect-oriented code ends.

License: MIT License

Ruby 0.03% Objective-C 99.97%
aop objective-c objc aspects hook libffi efficiency-library

stinger's People

Contributors

assuner-lee avatar chenzhengxu avatar danboduan avatar lobster-king avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stinger's Issues

Crash with hooking NSURL

NSURL *url = [[NSURL alloc] initWithString:@"https://www.google.com"];
[url st_hookInstanceMethod:@selector(absoluteString) option:(STOptionBefore) usingIdentifier:@"123" withBlock:^(id<StingerParams> params) {
    NSLog(@"");
}];
[url absoluteString];

Screenshot 2020-11-12 at 11 03 37 PM

对 KVO 对象 Hook 必现 crash

crash 栈

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x00007fff513f778b libobjc.A.dylib`objc_msgSend + 11
    frame #1: 0x00007fff2572290d Foundation`_NSSetLongLongValueAndNotify + 81
    frame #2: 0x00000001013ca58d Stinger_Example`ffi_call_unix64 + 85
  * frame #3: 0x00000001013c7804 Stinger_Example`ffi_call_int(cif=<unavailable>, fn=<unavailable>, rvalue=<unavailable>, avalue=<unavailable>, closure=<unavailable>) at ffi64_x86_64.c:660:3 [opt]
    frame #4: 0x00000001013bb956 Stinger_Example`_st_ffi_function(cif=0x00006000002b82a8, ret=0x00007ffeee853920, args=0x00007ffeee8537b0, userdata=0x00006000002b82a0) at STHookInfoPool.m:338:7
    frame #5: 0x00000001013c7a7d Stinger_Example`ffi_closure_unix64_inner(cif=0x00006000002b82a8, fun=(Stinger_Example`_st_ffi_function at STHookInfoPool.m:292), user_data=0x00006000002b82a0, rvalue=0x00007ffeee853920, reg_args=<unavailable>, argp=<unavailable>) at ffi64_x86_64.c:810:3 [opt]
    frame #6: 0x00000001013ca732 Stinger_Example`ffi_closure_unix64 + 72
    frame #7: 0x00000001013acdf2 Stinger_Example`-[ASViewController test:](self=0x00007fdcd1104c70, _cmd="test:", sender=0x00007fdccef023d0) at ASViewController.m:80:10
    frame #8: 0x00007fff48093fff UIKitCore`-[UIApplication sendAction:to:from:forEvent:] + 83
    frame #9: 0x00007fff47a6c00e UIKitCore`-[UIControl sendAction:to:forEvent:] + 223
    frame #10: 0x00007fff47a6c358 UIKitCore`-[UIControl _sendActionsForEvents:withEvent:] + 398
    frame #11: 0x00007fff47a6b2b7 UIKitCore`-[UIControl touchesEnded:withEvent:] + 481
    frame #12: 0x00007fff480cebbf UIKitCore`-[UIWindow _sendTouchesForEvent:] + 2604
    frame #13: 0x00007fff480d04c6 UIKitCore`-[UIWindow sendEvent:] + 4596
    frame #14: 0x00007fff480ab53b UIKitCore`-[UIApplication sendEvent:] + 356
    frame #15: 0x00007fff4812c71a UIKitCore`__dispatchPreprocessedEventFromEventQueue + 6847
    frame #16: 0x00007fff4812f1e0 UIKitCore`__handleEventQueueInternal + 5980
    frame #17: 0x00007fff23bd4471 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #18: 0x00007fff23bd439c CoreFoundation`__CFRunLoopDoSource0 + 76
    frame #19: 0x00007fff23bd3b74 CoreFoundation`__CFRunLoopDoSources0 + 180
    frame #20: 0x00007fff23bce87f CoreFoundation`__CFRunLoopRun + 1263
    frame #21: 0x00007fff23bce066 CoreFoundation`CFRunLoopRunSpecific + 438
    frame #22: 0x00007fff384c0bb0 GraphicsServices`GSEventRunModal + 65
    frame #23: 0x00007fff48092d4d UIKitCore`UIApplicationMain + 1621
    frame #24: 0x00000001013acfa2 Stinger_Example`main(argc=1, argv=0x00007ffeee855cf0) at main.m:15:16
    frame #25: 0x00007fff5227ec25 libdyld.dylib`start + 1

测试代码:

//
//  ASViewController.m
//  Stinger
//
//  Created by Assuner on 12/05/2017.
//  Copyright (c) 2017 Assuner. All rights reserved.
//

#import "ASViewController.h"
#import <Stinger/Stinger.h>
#import <Aspects/Aspects.h>

@interface ASViewController ()

- (IBAction)test:(id)sender;
@property (nonatomic) NSInteger index;

@property (nonatomic) BOOL didAddKVO;
@property (nonatomic) BOOL didHook;

@end

@implementation ASViewController

- (void)methodA {
  
}

- (void)setFrame:(CGRect)rect {
  
}

- (void)viewDidLoad {
  [super viewDidLoad];
  [self.class st_hookInstanceMethod:@selector(methodA) option:STOptionBefore usingIdentifier:@"hook methodA before" withBlock:^(id<StingerParams> params) {

  }];
  [self.class st_hookInstanceMethod:@selector(methodA) option:STOptionAfter usingIdentifier:@"hook methodA after" withBlock:^(id<StingerParams> params) {

  }];
  
//  [self.class aspect_hookSelector:@selector(methodA) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> params) {
//
//  } error:nil];
//
//  [self.class aspect_hookSelector:@selector(methodA) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> params) {
//
//  } error:nil];
}

- (void)addKVO {
    if (_didAddKVO) {
        return;
    }
    [self addObserver:self forKeyPath:@"index" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    _didAddKVO = YES;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    NSLog(@"KVO: %@", change);
}

- (void)hook_set_index {
    if (_didHook) {
        return;
    }
    [self st_hookInstanceMethod:@selector(setIndex:) option:STOptionBefore usingIdentifier:@"setIndex" withBlock:^(id<StingerParams> params, NSInteger index) {
        NSLog(@"HOOK: %@", @(index));
    }];
    _didHook = YES;
}

- (IBAction)test:(id)sender {
//  for (NSInteger i = 0; i < 1000000; i++) {
//    [self methodA];
//  }
  NSLog(@"clicked!!");
    [self addKVO];
    [self hook_set_index];
    self.index += 1;
}
@end

why hook systemFontOfSize cause app crash?

when I put the following code in category or homeViewController, the app will crash:
[UIFont st_hookClassMethod:@selector(systemFontOfSize:) option:(STOptionInstead) usingIdentifier:(@"myHook_fontWithSize") withBlock:^UIFont * (id params, CGFloat oldPara){
UIFont *oldRet;
[params invokeAndGetOriginalRetValue:&oldRet];
CGFloat newSize = oldRet.pointSize * 2;
return [UIFont fontWithName:oldRet.familyName size:newSize];
}];

the crash info is:
2023-06-28 18:00:33.468715+0800 ChangeFontSizeTest[1784:376274] [Assert] UINavigationBar decoded as unlocked for UINavigationController, or navigationBar delegate set up incorrectly. Inconsistent configuration may cause problems. navigationController=<UINavigationController: 0x15c01c200>, navigationBar=<UINavigationBar: 0x15bd09d50; frame = (0 59; 0 50); opaque = NO; autoresize = W; layer = <CALayer: 0x2833c74c0>> delegate=0x15c01c200

pls help!

ffiTypeWithType does not match 'CGSize'

你好,看了是饿了么团队出品,我就用中文了。
项目中有较多地方使用Aspects,正在换 Stinger,遇到点问题,我有一个分类监听 UIScrollView contentSize 变化,使用 Stinger 无法正确工作,上代码:
crash at 'can't match a ffi_type of {CGSize=dd}'

`
#import "UIScrollView+ContentSizeChangedHandler.h"
#import <objc/runtime.h>
#import <Stinger/Stinger.h>

static NSString *const kID = @"UIScrollView.setContentSize.after";

@interface UIScrollView ()
@Property (nonatomic, assign) CGSize wj_contentSizeChangedHandler_oldContentSize; ///< 旧 contentSize
@EnD

@implementation UIScrollView (ContentSizeChangedHandler)

  • (void)wj_setContentSizeChangedHandler:(ContentSizeChangedHandler)handler {
    void (^insideHandler)() = ^() {
    !handler ?: handler(self.contentSize);
    };

    self.wj_contentSizeChangedHandler_oldContentSize = self.contentSize;
    [self st_hookInstanceMethod:@selector(setContentSize:)
    option:STOptionAfter
    usingIdentifier:kID
    withBlock:^(id params, CGSize contentSize) {
    if (!CGSizeEqualToSize(self.contentSize, self.wj_contentSizeChangedHandler_oldContentSize)) {
    // 设置新值
    self.wj_contentSizeChangedHandler_oldContentSize = self.contentSize;
    insideHandler();
    }
    }];
    }
    `
    希望帮助解决,谢谢

Link failed with release build configuration.

Download Stinger from master bad3f7a.

Build the Demo project successfully.

Change the build configuration from debug to release and build again.

Screenshot 2020-11-25 at 9 53 01 AM

It's failed with:

Screenshot 2020-11-25 at 9 53 18 AM

This also happens on my project which is using Stinger with cocoapods.

Class、 Instance hook 同一个方法,Class 的 hook 会重复执行

如下面代码,
执行 [[TestClass new] foo], clz foo after 会打印两次

@implementation TestClass

+ (void)load
{
    [self st_hookInstanceMethod:@selector(foo)
                         option:STOptionAfter
                usingIdentifier:@"clz"
                      withBlock:^(id info) {
        NSLog(@"clz foo after");
    }];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self st_hookInstanceMethod:@selector(foo)
                             option:STOptionAfter
                    usingIdentifier:@"instance"
                          withBlock:^(id info) {
            NSLog(@"instance foo after");
        }];
    }
    return self;
}

- (void)foo
{
    NSLog(@"foo...");
}

@end 

hook method with block argument, crash !

define and implement

typedef void(^TestBlock)(float arg1, int arg2, id arg3);

- (void)print4:(NSString *)s block:(TestBlock)block;

- (void)print4:(NSString *)s block:(TestBlock)block { NSLog(@"---original print3: %@", s); block(1.2, 1, self); }

hook

[self st_hookInstanceMethod:@selector(print4:block:) option:STOptionAfter usingIdentifier:@"hook_print4_after4" withBlock:^(id<StingerParams> params, NSString *s) { NSLog(@"---after4 print4:block: %@", s); }];

crash

*** Assertion failure in BOOL isMatched(STMethodSignature *__strong, STMethodSignature *__strong, STOption, __unsafe_unretained Class, SEL, NSString *__strong)(), /Users/fsen/Downloads/Stinger-master/Stinger/Classes/Stinger.m:119
2018-02-26 12:17:18.498817+0800 Stinger_Example[38082:5521717] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'count of arguments isn't equal. Class: (ASViewController), SEL: (print4:block:), Identifier: (hook_print4_after4)'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.