iOS小技能:程式碼觸發button的點選事件、快速找到按鈕action方法

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第29天,點選檢視活動詳情

前言

  1. 快速找到按鈕action方法 ```objectivec cy# [#0x17a9cad0 actionsForTarget:#0x174eb8b0 forControlEvent:64] @["onVerifyContactOk"]

```

  1. 程式碼觸發button的點選事件:[btn sendActionsForControlEvents:UIControlEventTouchUpInside];

I 找按鈕的action方法(在逆向分析中的應用例子)

1.1 步驟1: 利用cy 找到對應的按鈕地址

  • 展開views結構: [UIWindow keyWindow].recursiveDescription().toString()

bash | | | | | | | | | | | <WCPayOfflinePayBottomButton: 0x170bab80; baseClass =

```bash \u4e8c\u7ef4\u7801\u6536\u6b3e 進行搜尋找到對應按鈕

echo -e ```

1.2 步驟2:尋找 點選按鈕對應的執行方法

UIButton 是繼承 UIControl 的,而 UIControl 的話可以通過allTargets 與 allControlEvents檢視所有的物件與事件,再使用actionsForTarget:forControlEvent:從而找到觸發的方法

objectivec - (nullable NSArray<NSString *> *)actionsForTarget:(nullable id)target forControlEvent:(UIControlEvents)controlEvent; // single event. returns NSArray of NSString selector names. returns nil if none * allTargets

objectivec cy# [#0x17a9cad0 allTargets] [NSSet setWithArray:@[#"<WeixinContactInfoAssist: 0x174eb8b0>"]]]

  • allControlEvents

objectivec cy# [#0x17a9cad0 allControlEvents] 64

  • actionsForTarget: forControlEvent

cy# [#0x17a9cad0 actionsForTarget:#0x174eb8b0 forControlEvent:64] @["onVerifyContactOk"]

  • 最終確定:WeixinContactInfoAssist WeixinContactInfoAssist:

```objectivec - (void)onVerifyContactOk;

```

1.3 進行驗證方法

  • objc_msgSend objectivec objc_msgSend(vc, @selector(initView));
  • [] objectivec cy# [[[#0x170bab80 allTargets] allObjects][0] receiveMoneyBtnPress:nil]
  • valueForKey objectivec cy# [[#0x183d6e00 valueForKey:@"m_delegate"] WCPayFacingReceiveChangeToFixedAmount]

1.4 tweak code

相關code的獲取,請關注公號:iOS逆向。

  • cy# [#0x16b60600 _ivarDescription].toString()

objectivec CBaseContactInfoAssist *m_oContactInfoAssist; CContact *m_contact; \tm_uiVerify (unsigned long): <01000000> \tm_contact (CContact*): <CPushContact: 0x177450d0> \tm_oContactInfoAssist (CBaseContactInfoAssist*): <WeixinContactInfoAssist: 0x174eb8b0> * 書寫 tweak ```objectivec %hook ContactInfoViewController - (void)viewWillAppear:(BOOL)arg1 { %orig;

        Ivar mDelegateVar = class_getInstanceVariable(objc_getClass("ContactInfoViewController"), "m_oContactInfoAssist");
        WeixinContactInfoAssist * mDelegate = object_getIvar(self, mDelegateVar);
        [mDelegate onAction];
    Ivar mDelegateVar1 = class_getInstanceVariable(objc_getClass("ContactInfoViewController"), "m_contact");

} ```

1.5 小結

  • 獲取allTargets ```objectivec cy# [[#0x170bab80 allTargets] allObjects][0]

""

* 獲取 actionsobjectivec cy# [#0x170bab80 actionsForTarget:[[#0x170bab80 allTargets] allObjects][0] forControlEvent:[#0x170bab80 allControlEvents]] @["receiveMoneyBtnPress:"] ```

  • cy# [#0x189ce7e0 setHidden:0]驗證是否找對了view

II 程式碼觸發button點選事件

2.1 UIControl

```objectivec

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView

// send the action. the first method is called for the event and is a point at which you can observe or override behavior. it is called repeately by the second. - (void)sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event; - (void)sendActionsForControlEvents:(UIControlEvents)controlEvents; // send all actions associated with events ```

2.2 UIButton

objectivec NS_CLASS_AVAILABLE_IOS(2_0) @interface UIButton : UIControl <NSCoding>

2.3 iOS 程式碼觸發button點選事件

objectivec cy# [#0x18c0ad10 sendActionsForControlEvents:UIControlEventTouchUpInside] objectivec [btn sendActionsForControlEvents:UIControlEventTouchUpInside];

III 預備知識: UIButton到NSObject之間的繼承關係

UIButton繼承自UIControl,UIControl繼承自UIView,UIView繼承自UIResponder,UIResponder繼承自最基本的類NSObject。

UIButton是一個控制元件,它具備“按下”等具體的動作操控,而不僅僅是一個簡單的靜態元件(如UILabel),從這個角度來看UIButton肯定是繼承自UIControl的; UIControl繼承自UIView,它將UIView的複雜的觸控事件封裝成了像“Touch Down”“Editing DidBegin”“Touch Drag Enter”等具體的UIControlEvent事件,其他繼承自UIControl的控制元件還有UISwitch、UITextField、UISlider、UISegmentedControl、UIPageControl等。

最後UIView、UIControl等都是可互動的元素,它們必然都繼承自UIResponder,UIResponder繼承自根類NSObject

see also

更多內容請關注 #公號:iOS逆向,只為你呈現有價值的資訊,專注於移動端技術研究領域;