逆向工程二:微信抢红包

微信版本: WeChat 6.5.20 (计算ASLR偏移,是之前版本;不同版本的偏移地址不一样)

砸壳获取头文件

找到bundle路径:
登录到iPhone,查看微信的进程信息

1
2
ssh root@192.168.2.24
ps -e | grep WeChat

从进程信息里获取微信bundle的路径

1
3079 ?? 0:41.37 /var/containers/Bundle/Application/26F5C9BE-61AB-468F-B2E8-9AC2DBD49F40/WeChat.app/WeChat

获取沙盒路径:
通过cyscript获取微信的沙盒路径,如果没有cy#那么点击进入微信:

1
cycript -p WeChat

注入微信进程之后,NSHomeDirectory()输出沙盒路径

1
2
3
cy# NSHomeDirectory()
@"/var/mobile/Containers/Data/Application/0A361401-3880-4C73-862A-8E06F4B7328D"
cy#

下载dumpdecrypted砸壳工具,编译成dylib包

克隆源码,并且编译生成一个dumpdecrypted.dylib

1
2
git clone https://github.com/stefanesser/dumpdecrypted.git 
make

注入微信获取解密的包

scp将dumpdecrypted.dylib拷贝到iPhone

1
scp dumpdecrypted.dylib root@192.168.2.24:/tmp

iPhone里进入微信沙盒的Documents目录,拷贝dumpdecrypted.dylib到Documents目录

1
2
cd /var/mobile/Containers/Data/Application/0A361401-3880-4C73-862A-8E06F4B7328D/Documents
cp /tmp/dumpdecrypted.dylib .

通过上面得到的bundle中WeChat包文件,注入微信。注意如果输出Killed: 9那么切换到mobile用户

1
2
su mobile
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/26F5C9BE-61AB-468F-B2E8-9AC2DBD49F40/WeChat.app/WeChat

输出信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mach-o decryption dumper

DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.

[+] detected 64bit ARM binary in memory.
[+] offset to cryptid found: @0x10006cca8(from 0x10006c000) = ca8
[+] Found encrypted data at address 00004000 of length 52396032 bytes - type 1.
[+] Opening /private/var/containers/Bundle/Application/26F5C9BE-61AB-468F-B2E8-9AC2DBD49F40/WeChat.app/WeChat for reading.
[+] Reading header
[+] Detecting header type
[+] Executable is a plain MACH-O image
[+] Opening WeChat.decrypted for writing.
[+] Copying the not encrypted start of the file
[+] Dumping the decrypted data into the file
[+] Copying the not encrypted remainder of the file
[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset ca8
[+] Closing original file
[+] Closing dump file

上面信息结束之后,在Documents目录下有个WeChat.decrypted文件

获取头文件信息
在mac上拷贝iPhone的解密的微信包文件

1
2
3
4
scp root@192.168.2.24:/var/mobile/Containers/Data/Application/0A361401-3880-4C73-862A-8E06F4B7328D/Documents/WeChat.decrypted . 

root@192.168.2.24's password:
WeChat.decrypted 100% 63MB 2.1MB/s 00:30

class-dump 获取所有的微信头文件到WXHeaders目录

1
class-dump -s -S -H WeChat.decrypted -o WXHeaders/

获取微信bundle id : com.tencent.xin
查看签名信息:codesign -dvvv WeChat.decrypted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Executable=/Users/leaf/yy/project/redpocket/WeChat.decrypted
Identifier=com.tencent.xin
Format=Mach-O thin (arm64)
CodeDirectory v=20200 size=511951 flags=0x0(none) hashes=15991+5 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha1=5640d0abb3945378afd4a6b90dfc5aab4010e268
CandidateCDHash sha256=f664c1dd6fc1d17f04fd4f268fa2872f04316a7b
Hash choices=sha1,sha256
CDHash=f664c1dd6fc1d17f04fd4f268fa2872f04316a7b
Signature size=4297
Authority=Apple iPhone OS Application Signing
Authority=Apple iPhone Certification Authority
Authority=Apple Root CA
Info.plist=not bound
TeamIdentifier=88L2Q4487U
Sealed Resources=none
Internal requirements count=1 size=96

创建Tweak工程

调用theod: /opt/theos/bin/nic.pl
选择tweak,然后输入相关信息:

1
2
3
4
5
6
7
8
9
10
11
12
//项目名称    
Project Name (required): redpocket
//项目的包名,即bundle id
Package Name [com.yourcompany.demo]: cc.onezen.redpocket
//开发者名称
Author/Maintainer Name [wz]: wz
//需要注入的进程的 bundle id
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.tencent.xin
//deb包安装完成后需要重启的进程名字
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: WeChat
Instantiating iphone/tweak in demo/...
Done.

自动安装配置Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#debug=0是release包
DEBUG = 0
#iphone的ip地址
THEOS_DEVICE_IP = 192.168.2.24
#当前包支持的cpu架构
ARCHS = armv7 arm64
#支持的ios版本
TARGET = iphone:latest:8.0
include $(THEOS)/makefiles/common.mk

TWEAK_NAME = redpocket
redpocket_FILES = Tweak.xm
#需要导入的库
redpocket_FRAMEWORKS = UIKit
include $(THEOS_MAKE_PATH)/Tweak.mk

after-install::
install.exec "killall -9 WeChat"
clean::
rm -rf ./packages/*
rm -rf ./.theos/*

定位视图

安装Reveal:安装mac客户端,iPhone通过Cydia安装Reveal Loader
通过cycript

注入:cycript -p WeChat

通过recursiveDescription输出View层级信息

1
2
3
4
5
6
7
[[UIApp keyWindow] recursiveDescription].toString()

点语法:
UIApp.keyWindow.recursiveDescription().toString()

简化信息:
[[UIApp keyWindow] _autolayoutTrace].toString()

找到一个ViewController上面的UIView:<UIView: 0x12f09d930; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x12f2567e0>>,查看响应者

1
2
cy#  [#0x12f09d930 nextResponder]
#"<BaseMsgContentViewController: 0x12e2f1600>"

定位 BaseMsgContentViewController 消息响应方法

BaseMsgContentViewController头文件所有的方法被触发打印信息

1
/opt/theos/bin/logify.pl ./WXHeaders/BaseMsgContentViewController.h > Tweak.xm

编译安装
注释掉//- (void).cxx_destruct { %log; %orig; }方法,并且在编译中,注释掉所有报错的方法,报错的最主要的原因是找不到头文件。

安装成功后查看log信息

发送消息,定位和消息相关的方法

1
2
3
4
5
6
7
8
-[<BaseMsgContentViewController: 0x137904600> addMessageNode:{m_uiMesLocalID=15, m_ui64MesSvrID=4691907035794540423, m_nsFromUsr=wxi*m21~19, m_nsToUsr=wxi*712~19, m_uiStatus=4, type=1, msgSource="<msgsource><sequence_id>690750074</sequence_id></msgsource>"}  layout:1 addMoreMsg:0]


-[<BaseMsgContentViewController: 0x137904600> addTimeNode:{m_uiMesLocalID=15, m_ui64MesSvrID=4691907035794540423, m_nsFromUsr=wxi*m21~19, m_nsToUsr=wxi*712~19, m_uiStatus=4, type=1, msgSource="<msgsource><sequence_id>690750074</sequence_id></msgsource>"} layout:1 addMoreMsg:0]

-[<BaseMsgContentViewController: 0x137904600> isShowHeadImage:{m_uiMesLocalID=15, m_ui64MesSvrID=4691907035794540423, m_nsFromUsr=wxi*m21~19, m_nsToUsr=wxi*712~19, m_uiStatus=4, type=1, msgSource="<msgsource><sequence_id>690750074</sequence_id></msgsource>"} ]

-[<BaseMsgContentViewController: 0x137904600> getMessageChatContactByMessageWrap:{m_uiMesLocalID=15, m_ui64MesSvrID=4691907035794540423, m_nsFromUsr=wxi*m21~19, m_nsToUsr=wxi*712~19, m_uiStatus=4, type=1, msgSource="<msgsource><sequence_id>690750074</sequence_id></msgsource>"}

根据log信息,可以很容易得出addMessageNode是我们要找的

通过lldb动态调试

iPhone连接xcode,iOS上会自动在/Developer/usr/bin/目录下面生成调试工具debugserver
debugserver瘦身和重新签名,并放入iPhone /usr/bin /目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#mac上拷贝debugserver
scp root@192.168.2.24:/Developer/usr/bin/debugserver .

#查看支持的架构
lipo -info debugserver
Architectures in the fat file: debugserver are: armv7 armv7s arm64

#瘦身
lipo -thin arm64 debugserver -output debugserver.arm64


#使用ldid添加task_for_pid权限
vi ent.xml
#添加下面信息
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.springboard.debugapplications</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
</dict>
</plist>

#开始修改
ldid -S ent.xml debugserver.arm64
#查看修改后的信息
ldid -e debugserver.arm64

#使用codesign添加task_for_pid权限
vim ent.plist
codesign -s - --entitlements ent.plist -f debugserver.arm64

#配合debugserver命令
cp debugserver.arm64 /usr/local/Cellar
ln -s /usr/local/Cellar/debugserver.arm64 /usr/local/bin/debugserver
scp debugserver.arm64 root@192.168.2.24:/usr/bin/

#在iphone改debugserver名字
mv /usr/bin/debugserver.arm64 /usr/bin/debugserver

启动调试(目的: 找出接受消息的类,不受页面的限制,单例)
在iPhone启动服务

1
debugserver *:6666 -a "WeChat"

mac lldb连接debugserver

1
2
lldb
(lldb) process connect connect://192.168.2.24:6666 //注意ip和端口要和配的相同

调试相关命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#查看所有断点
br list

#添加 -a后的地址是:偏移后符号基地址
br s -a '0x00000000000a4000+0x0000000101c8bf4c'

#删除:根据br list标号
br delete 1

#设置
b function
br s –a address
br s –a 'ASLROffset+address'

#继续运行
c

#等待断点触发
bt

计算地址

地址相关计算逻辑

1
2
3
偏移后模块基地址 = 偏移前模块基地址 + 模块的ASLR偏移
偏移后指令基地址 = 偏移前指令基地址 + 指令所在模块的ASLR偏移
偏移后符号基地址 = 偏移前符号基地址 + 符号所在模块的ASLR偏移

查看ASLR偏移

1
2
(lldb) image list -o -f | grep WeChat
[ 0] 0x00000000000a4000 /var/containers/Bundle/Application/26F5C9BE-61AB-468F-B2E8-9AC2DBD49F40/WeChat.app/WeChat(0x00000001000a4000)

通过Hopper查看addMessageNode的函数基地址

1
2
3
4
-[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]:
0000000101c8bf4c db 0xff ; '.' ; Objective C Implementation defined at 0x103863320 (instance)
0000000101c8bf4d db 0xc3 ; '.'
0000000101c8bf4e db 0x05 ; '.'

偏移后符号基地址 = 0x00000000000a4000 + 0x0000000101c8bf4c

调试微信发送消息
lldb 添加第一个断点:br s -a '0x00000000000a4000+0x0000000101c8bf4c'
注意:在进入好友聊天界面的时候,会多次调用断点,所以进入是删除断点,然后再添加。

发送消息之后,断点停留。然后bt查看堆栈信息,最后c继续

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x0000000101d2ff4c WeChat`ClearDataItem::compareTime(std::__1::shared_ptr<ClearDataItem> const&, std::__1::shared_ptr<ClearDataItem> const&) + 4127552
frame #1: 0x0000000101f999ec WeChat`ClearDataItem::compareTime(std::__1::shared_ptr<ClearDataItem> const&, std::__1::shared_ptr<ClearDataItem> const&) + 6657504
frame #2: 0x0000000101f83310 WeChat`ClearDataItem::compareTime(std::__1::shared_ptr<ClearDataItem> const&, std::__1::shared_ptr<ClearDataItem> const&) + 6565636
frame #3: 0x0000000104464ce8 MMCommon`_callExtension + 480
frame #4: 0x00000001027e35fc WeChat`ClearDataItem::compareTime(std::__1::shared_ptr<ClearDataItem> const&, std::__1::shared_ptr<ClearDataItem> const&) + 15348208
frame #5: 0x0000000182f1002c Foundation`__NSThreadPerformPerform + 340
frame #6: 0x00000001824f109c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #7: 0x00000001824f0b30 CoreFoundation`__CFRunLoopDoSources0 + 540
frame #8: 0x00000001824ee830 CoreFoundation`__CFRunLoopRun + 724
frame #9: 0x0000000182418c50 CoreFoundation`CFRunLoopRunSpecific + 384
frame #10: 0x0000000183d00088 GraphicsServices`GSEventRunModal + 180
frame #11: 0x0000000187702088 UIKit`UIApplicationMain + 204
frame #12: 0x0000000100180488 WeChat`_mh_execute_header + 902280
frame #13: 0x0000000181fb68b8 libdyld.dylib`start + 4
(lldb) c
Process 2013 resuming
(lldb)

查看堆栈信息可以的得出:与WeChat相关的有四条信息
计算四条信息的地址:

1
2
3
4
5
6
7
偏移后符号基地址 = 符号所在模块的ASLR偏移 + 偏移前符号基地址
frame #0: 0x0000000101d2ff4c => 0x00000000000a4000 + 0x0000000101c8bf4c
frame #1: 0x0000000101f999ec => 0x00000000000a4000 + ?
偏移前符号基地址 = 偏移后符号基地址 - 符号所在模块的ASLR偏移
frame #1: 0x0000000101f999ec => 0x00000000000a4000 + (0x101EF59EC)
frame #2: 0x0000000101f83310 => 0x00000000000a4000 + (0x101EDF310)
frame #4: 0x00000001027e35fc => 0x00000000000a4000 + (0x10273F5FC)

通过Hopper和计算出的(偏移前符号基地址)查看相关的方法,Hopper中使用快捷键G,跳转到某一地址。查看地址不是对应地址,而是地址相关的地址。

1
2
3
4
5
6
7
8
0x101EF59EC:(内部方法)
0000000101ef5964 adrpx24, #0x102f0f000; XREF=-[BaseMsgContentLogicController DidAddMsg:]+328

0x101EDF310:
0000000101edf310 adrp x8, #0x103b7c000; XREF=-[BaseMsgContentLogicController OnAddMsg:MsgWrap:]+336

0x10273F5FC: (相关)
-[CMessageMgr MainThreadNotifyToExt:]:

lldb继续添加断点调试,这次在好友列表页打断点。

1
2
3
4
5
6
7
8
9
10
11
0x0000000101d2ff4c:
好友聊天页面有效,淘汰!

0x0000000101f999ec:
好友聊天页面有效,淘汰!

0x0000000101f83310:
好友聊天页面有效,淘汰!

0x00000001027e35fc:
任意页面有效, 找到了!

通过上面分析的出,是[CMessageMgr MainThreadNotifyToExt:]方法。然后我们hook CMessageMgr类中的所有方法,来找出接受消息的方法。

1
2
3
4
➜  WXHeaders ls -ll *CMessageMgr*
-rw-r--r-- 1 wz staff 17573 9 28 10:08 CMessageMgr.h

/opt/theos/bin/logify.pl CMessageMgr.h > ../Tweak.xm

查看日志找出的相关方法:

1
2
3
4
5
[<CMessageMgr: 0x127ab9570> CheckMessageStatus:]
[<CMessageMgr: 0x127ab9570> AsyncOnPreAddMsg:]
[<CMessageMgr: 0x127ab9570> AsyncOnAddMsg:]
[<CMessageMgr: 0x127ab9570> AsyncOnPushMsg:]
[<CMessageMgr: 0x127ab9570> AsyncOnAddMsgListForSession:]

选择方法:[ AsyncOnAddMsg:],并且输出参数类型,移除不用的方法,留下部分有用的方法。

1
2
3
4
5
6
- (void)AsyncOnAddMsg:(id)arg1 MsgWrap:(id)arg2 {
//%log;
%orig;
NSLog(@"arg1: %@, %@", [arg1 class], arg1);
NSLog(@"arg2: %@, %@", [arg2 class], arg2);
}

输出内容

1
2
Sep 29 15:02:44 iPhone WeChat[2394] <Warning>: arg1: __NSCFString,  wxid_y9bs6i3qil6m21
Sep 29 15:02:44 iPhone WeChat[2394] <Warning>: arg2: CMessageWrap, {m_uiMesLocalID=28, m_ui64MesSvrID=3324982937891416074, m_nsFromUsr=wxi*m21~19, m_nsToUsr=wxi*712~19, m_uiStatus=3, type=1, msgSource="<msgsource><sequence_id>690750088</sequence_id></msgsource>"}

分析消息 CMessageWrap头文件,根据测试得出结论:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@interface CMessageWrap
@property(nonatomic) _Bool m_bCdnForward; // @synthesize m_bCdnForward;
@property(nonatomic) _Bool m_bForward; // @synthesize m_bForward;
@property(nonatomic) _Bool m_bIsBrandSendMass; // @synthesize m_bIsBrandSendMass;
@property(nonatomic) _Bool m_bIsFromBrandSession; // @synthesize m_bIsFromBrandSession;
@property(nonatomic) _Bool m_bIsSplit; // @synthesize m_bIsSplit;
@property(nonatomic) _Bool m_bNew; // @synthesize m_bNew;
@property(nonatomic) unsigned int m_bReceiveMessageSwitchStatus; // @synthesize m_bReceiveMessageSwitchStatus;
@property(retain, nonatomic) NSString *m_bizMsgMenuID; // @synthesize m_bizMsgMenuID;
@property(retain, nonatomic) NSMutableDictionary *m_dicForwardParas; // @synthesize m_dicForwardParas=_m_dicForwardParas;
@property(retain, nonatomic) NSData *m_dtThumbnail; // @synthesize m_dtThumbnail;
@property(nonatomic) unsigned int m_forwardType; // @synthesize m_forwardType=_m_forwardType;
@property(nonatomic) _Bool m_isEnterpriseMsg; // @synthesize m_isEnterpriseMsg;
@property(nonatomic) _Bool m_isTempSessionMsg; // @synthesize m_isTempSessionMsg;
@property(nonatomic) long long m_n64MesSvrID; // @synthesize m_n64MesSvrID;
@property(retain, nonatomic) NSString *m_nsAtUserList; // @synthesize m_nsAtUserList;
@property(retain, nonatomic) NSString *m_nsBizChatId; // @synthesize m_nsBizChatId;
@property(retain, nonatomic) NSString *m_nsBizClientMsgID; // @synthesize m_nsBizClientMsgID;
@property(retain, nonatomic) NSString *m_nsContent; // @synthesize m_nsContent;
@property(retain, nonatomic) NSString *m_nsDisplayName; // @synthesize m_nsDisplayName;
@property(retain, nonatomic) NSString *m_nsFromUsr; // @synthesize m_nsFromUsr;
@property(retain, nonatomic) NSString *m_nsKFWorkerOpenID; // @synthesize m_nsKFWorkerOpenID;
@property(retain, nonatomic) NSString *m_nsMsgSource; // @synthesize m_nsMsgSource;
@property(retain, nonatomic) NSString *m_nsPattern; // @synthesize m_nsPattern;
@property(retain, nonatomic) NSString *m_nsPushBody; // @synthesize m_nsPushBody;
@property(retain, nonatomic) NSString *m_nsPushContent; // @synthesize m_nsPushContent;
@property(retain, nonatomic) NSString *m_nsPushPrefix; // @synthesize m_nsPushPrefix;
@property(retain, nonatomic) NSString *m_nsPushTitle; // @synthesize m_nsPushTitle;
@property(retain, nonatomic) NSString *m_nsRealChatUsr; // @synthesize m_nsRealChatUsr;
@property(retain, nonatomic) NSString *m_nsToUsr; // @synthesize m_nsToUsr;
@property(nonatomic) unsigned int m_sequenceId; // @synthesize m_sequenceId;
@property(nonatomic) unsigned int m_uiBizChatVer; // @synthesize m_uiBizChatVer;
@property(nonatomic) unsigned int m_uiCreateTime; // @synthesize m_uiCreateTime;
@property(nonatomic) unsigned int m_uiDownloadStatus; // @synthesize m_uiDownloadStatus;
@property(nonatomic) unsigned int m_uiEmojiStatFlag; // @synthesize m_uiEmojiStatFlag;
@property(nonatomic) unsigned int m_uiImgStatus; // @synthesize m_uiImgStatus;
@property(nonatomic) unsigned int m_uiMesLocalID; // @synthesize m_uiMesLocalID;
@property(nonatomic) int m_uiMessageType; // @synthesize m_uiMessageType;
@property(nonatomic) unsigned int m_uiMsgFlag; // @synthesize m_uiMsgFlag;
@property(nonatomic) unsigned int m_uiPercent; // @synthesize m_uiPercent;
@property(nonatomic) unsigned int m_uiSendTime; // @synthesize m_uiSendTime;
@property(nonatomic) unsigned int m_uiStatus; // @synthesize m_uiStatus;
@end


%hook CMessageMgr

- (void)AsyncOnAddMsg:(NSString *)wxid MsgWrap:(CMessageWrap *)msg {

NSString *content = [msg m_nsContent];
NSString *fromUsr = [msg m_nsFromUsr];
NSString *toUsr = [msg m_nsToUsr];
int messageType = [msg m_uiMessageType];

NSLog(@"content: %@", content);
NSLog(@"fromUsr: %@", fromUsr);
NSLog(@"toUsr: %@", toUsr);
NSLog(@"messageType: %d", messageType);

if (messageType == 1)
{
NSLog(@"文本消息");
}else if (messageType == 3)
{
NSLog(@"图片消息");
}else if (messageType == 48)
{
NSLog(@"位置消息");
}else if (messageType == 49)
{
NSLog(@"红包消息、转账消息");
}else{
NSLog(@"未知");
}

%orig;

}

红包相关的方法

点开红包,显示抢红包页面,然后通过cycript查看页面层级:

1
2
iPhone:~ root# cycript -p WeChat
cy# [[UIApp keyWindow] _autolayoutTrace].toString()

红包相关的页面层级:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|   WCRedEnvelopesReceiveHomeView:0x1301296d0
| | UIButton:0x1301298c0
| | UIImageView:0x12fd566c0
| | | UIView:0x130237de0
| | | UIView:0x130240a70
| | | UIImageView:0x13021d600
| | | UIView:0x13021bad0
| | | | UIView:0x13023d320
| | | | UIView:0x13021d1c0
| | | | UIImageView:0x1302418d0
| | | | UIImageView:0x13021ed80
| | | | UIButton:0x13022fe50
| | | UIView:0x1302251f0
| | | | MMHeadImageView:0x1302328c0
| | | | | MMUILongPressImageView:0x1302249a0
| | | | | UIImageView:0x1302309c0
| | | MMUILabel:0x1302412f0'\u591c\u8fb0'
| | | MMUILabel:0x13021f740'\u7ed9\u4f60\u53d1\u4e86\u4e00\u4e2a\u7ea2\u5305'
| | | MMUILabel:0x1302436e0'\u8be5\u7ea2\u5305\u5df2\u8d85\u8fc724\u5c0f\u65f6\u3002\u5982\u5df2\u9886\u53d6\uff0c\u53ef\u5728\u201c\u6211\u7684\u7ea2\u5305\u201d\u4e2d...'
| | | UIButton:0x13012d3f0
| | | UIButton:0x13012d690
| | | | UIImageView:0x13012ddb0
| | | UIImageView:0x13012adf0
| | | UIImageView:0x13012b0b0

调试WCRedEnvelopesReceiveHomeView页面

1
/opt/theos/bin/logify.pl WXHeaders/WCRedEnvelopesReceiveHomeView.h > Tweak.xm

日志:

1
2
3
4
5
6
7
8
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:8 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> initWithFrame:-- andData:<WCRedEnvelopesControlData: 0x13742e5b0> delegate:<WCRedEnvelopesReceiveControlLogic: 0x13719a0c0>]
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:13 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> refreshViewWithData:<WCRedEnvelopesControlData: 0x13742e5b0>]
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:16 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> shouldShowDetailButtonWithIsSender:0 Type:0 ReceiveStutus:0 envelopeStutus:2 data:<WCRedEnvelopesControlData: 0x13742e5b0>]
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:16 DEBUG: = 0
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:15 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> shouldShowBottomDescriptionWithType:0 envelopeStutus:2]
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:15 DEBUG: = 0
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:8 DEBUG: = <WCRedEnvelopesReceiveHomeView: 0x13720c6d0; frame = (0 0; 320 568); clipsToBounds = YES; layer = <CALayer: 0x1370e6d30>>
Oct 20 10:50:22 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:17 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> showAnimation]

点开红包后调用:

1
2
3
4
Oct 20 10:50:25 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:5 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> OnOpenRedEnvelopes]
Oct 20 10:50:25 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:19 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> startReceiveAnimation]
Oct 20 10:50:26 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:18 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> showSuccessOpenAnimation]
Oct 20 10:50:26 iPhone WeChat[3235] <Notice>: [redpocket] Tweak.xm:14 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> removeView]

仔细分析可以得出几个和数据相关的方法,其它基本是UI相关

1
2
3
4
5
6
7
8
//WCRedEnvelopesControlData & WCRedEnvelopesReceiveControlLogic 初始化一个红包视图
-[<WCRedEnvelopesReceiveHomeView: 0x1370974c0> initWithFrame:-- andData:<WCRedEnvelopesControlData: 0x136cddbf0> delegate:<WCRedEnvelopesReceiveControlLogic: 0x136f4c9b0>]

//根据WCRedEnvelopesControlData刷新界面
-[<WCRedEnvelopesReceiveHomeView: 0x1370974c0> refreshViewWithData:<WCRedEnvelopesControlData: 0x136cddbf0>]

//打开红包操作
-[<WCRedEnvelopesReceiveHomeView: 0x13720c6d0> OnOpenRedEnvelopes]

打开红包的操作才是我们需要的,那么我们走起,通过Hopper反编译OnOpenRedEnvelopes

头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@interface WCRedEnvelopesReceiveHomeView{
id m_delegate;
NSDictionary *m_dicBaseInfo;
}
@end

%hook WCRedEnvelopesReceiveHomeView

- (void)OnOpenRedEnvelopes {
%log;
//%orig;
NSDictionary *dict = MSHookIvar<NSDictionary *>(self, "m_dicBaseInfo");
NSArray *arr = [dict allKeys];
for(NSInteger i=0; i<arr.count; i++){
NSString *key = arr[i];
id value = [dict valueForKey:key];
NSLog(@"key : %@ value : %@", key, value);
}
id delegate = MSHookIvar<id>(self, "m_delegate");
NSLog(@"m_delegate class is %@ ", [delegate class]);
}


%end

日志输出:

1
2
3
4
5
6
7
8
9
10
Oct 20 15:21:19 iPhone WeChat[3282] <Notice>: [redpocket] Tweak.xm:25 DEBUG: -[<WCRedEnvelopesReceiveHomeView: 0x15e8b0510> OnOpenRedEnvelopes]
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>:Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : watermark value :
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : sendUserName value : wxid_y9bs6i3qil6m21
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : timingIdentifier value : C2E51DAD13A971F9E5C3EC016C9CA2E7
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : hbStatus value : 2
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : receiveStatus value : 0
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : sendId value : 1000039501201710207015233607354
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : isSender value : 0
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>:Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: key : hbType value : 0
Oct 20 15:21:19 iPhone WeChat[3282] <Warning>: m_delegate class is WCRedEnvelopesReceiveControlLogic

WeChat 6.5.20 分割线,上面是之前版本,偏移地址不一样,逻辑啥的都一样。App Store自动升级真是郁闷啊!

Hopper反汇编打开红包方法(和IDA做对比):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    -[WCRedEnvelopesReceiveHomeView OnOpenRedEnvelopes]:
0000000100e586e8 sub sp, sp, #0x70 ; Objective C Implementation defined at 0x1036f8b50 (instance)
0000000100e586ec stp x24, x23, [sp, #0x30] ;x23+(sp+0x30) = x24
0000000100e586f0 stp x22, x21, [sp, #0x40] ;x21+(sp+0x40) = x22
0000000100e586f4 stp x20, x19, [sp, #0x50] ;x19+(sp+0x50) = x20
0000000100e586f8 stp x29, x30, [sp, #0x60] ;x30+(sp+0x60) = x29
0000000100e586fc add x29, sp, #0x60 ;x29 = sp + 0x60
0000000100e58700 mov x19, x0 ;x19 = x0
0000000100e58704 adrp x8, #0x103c2a000 ;地址生成self
0000000100e58708 ldrsw x24, [x8, #0xfbc] ; x24 = (x8+0xfbc) objc_ivar_offset_WCRedEnvelopesReceiveHomeView_m_dicBaseInfo self.m_dicBaseInfo
0000000100e5870c ldr x0, [x19, x24] ;x0 = (x19+x24)
0000000100e58710 adrp x8, #0x103b7d000
0000000100e58714 ldr x20, [x8, #0xee0] ; "objectForKey:",@selector(objectForKey:) ;方法地址
0000000100e58718 adrp x2, #0x1033a6000
0000000100e5871c add x2, x2, #0xfb8 ; @"isSender"
0000000100e58720 mov x1, x20
0000000100e58724 bl imp___stubs__objc_msgSend ;调用 [self.m_dicBaseInfo objectForKey:@"isSender"]

0000000100e58728 mov x29, x29
0000000100e5872c bl imp___stubs__objc_retainAutoreleasedReturnValue 返回值在x0

0000000100e58730 mov x21, x0
0000000100e58734 adrp x8, #0x103b7f000 ; @selector(WAAppCacheSandboxDirWithAppID:)
0000000100e58738 ldr x22, [x8, #0x858] ; "intValue",@selector(intValue)
0000000100e5873c mov x1, x22
0000000100e58740 bl imp___stubs__objc_msgSend ; 实现appid变为intValue

0000000100e58744 mov x23, x0
0000000100e58748 mov x0, x21 ;返回值isSender
0000000100e5874c bl imp___stubs__objc_release

0000000100e58750 ldr x0, [x19, x24] ;x0 = (x19+x24)
0000000100e58754 adrp x2, #0x1033a6000
0000000100e58758 add x2, x2, #0xb18 ;@"hbType"
0000000100e5875c mov x1, x20
0000000100e58760 bl imp___stubs__objc_msgSend ;[self.m_dicBaseInfo valueForKey:@"hbType"]
0000000100e58764 mov x29, x29
0000000100e58768 bl imp___stubs__objc_retainAutoreleasedReturnValue ;返回值

0000000100e5876c mov x20, x0
0000000100e58770 mov x1, x22
0000000100e58774 bl imp___stubs__objc_msgSend
0000000100e58778 mov x21, x0
0000000100e5877c mov x0, x20
0000000100e58780 bl imp___stubs__objc_release

0000000100e58784 adrp x8, #0x103c07000
0000000100e58788 ldr x0, [x8, #0x7b8] ; x0 = (x8+0x7b8) objc_cls_ref_NSString,_OBJC_CLASS_$_NSString
0000000100e5878c add w8, w21, #0x1
0000000100e58790 cmp w23, #0x0
0000000100e58794 orr w9, wzr, #0x1
0000000100e58798 cinc w9, w9, le
0000000100e5879c adrp x10, #0x103b7d000
0000000100e587a0 ldr x1, [x10, #0xf68] ; "stringWithFormat:",@selector(stringWithFormat:)
0000000100e587a4 adrp x10, #0x10330d000
0000000100e587a8 add x10, x10, #0x18 ; @""
0000000100e587ac orr w11, wzr, #0x2
0000000100e587b0 stp x11, x10, [sp, #0x20]
0000000100e587b4 stp x9, xzr, [sp, #0x10]
0000000100e587b8 movz w9, #0x5
0000000100e587bc stp x9, x8, [sp]
0000000100e587c0 adrp x2, #0x1033a7000
0000000100e587c4 add x2, x2, #0x2b8 ; @"%u,%u,%u,%u,%u,%@"
0000000100e587c8 bl imp___stubs__objc_msgSend ; [NSString stringWithFormat:@"%u,%u,%u,%u,%u,%@"];
0000000100e587cc mov x29, x29
0000000100e587d0 bl imp___stubs__objc_retainAutoreleasedReturnValue


0000000100e587d4 mov x20, x0
0000000100e587d8 movz w0, #0x2db5
0000000100e587dc mov x1, x20
0000000100e587e0 movz w2, #0x0
0000000100e587e4 movz w3, #0x0 ; argument "self"
0000000100e587e8 bl 0x102923a8c
0000000100e587ec adrp x8, #0x103c2a000
0000000100e587f0 ldrsw x8, [x8, #0xfd8] ; objc_ivar_offset_WCRedEnvelopesReceiveHomeView_m_delegate
0000000100e587f4 add x0, x19, x8
0000000100e587f8 bl imp___stubs__objc_loadWeakRetained
0000000100e587fc mov x19, x0
0000000100e58800 adrp x8, #0x103bb1000 ; @selector(setModifyDefaultAmt:)
0000000100e58804 ldr x1, [x8, #0xf40] ; "WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes",@selector(WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes)
0000000100e58808 bl imp___stubs__objc_msgSend
0000000100e5880c mov x0, x19
0000000100e58810 bl imp___stubs__objc_release
0000000100e58814 mov x0, x20
0000000100e58818 ldp x29, x30, [sp, #0x60]
0000000100e5881c ldp x20, x19, [sp, #0x50]
0000000100e58820 ldp x22, x21, [sp, #0x40]
0000000100e58824 ldp x24, x23, [sp, #0x30]
0000000100e58828 add sp, sp, #0x70
0000000100e5882c b imp___stubs__objc_release
; endp

IDA反汇编打开红包的方法(IDA 调用方法时比Hopper注释更加详细,所以下面使用IDA):

  1. IDA 在调用方法时,将方法的地址,转换为函数名;看反汇编代码更加清晰
  2. 调用objc_msgSend方法时: X0存放第一个参数receiver,X1存放第二个参数selector,后面的参数依此类推
  3. x0~x7常用做参数,x0常用做返回值
  4. adrp地址生成指令,常用做取方法的地址
  5. x8常用做间接寻址
  6. mac终端命令 只在当前目录根据内容(MMServiceCenter)查找相关文件:mdfind -onlyin . MMServiceCenter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
text:0000000100E586E8 ; void __cdecl -[WCRedEnvelopesReceiveHomeView OnOpenRedEnvelopes](WCRedEnvelopesReceiveHomeView *self, SEL)
__text:0000000100E586E8 __WCRedEnvelopesReceiveHomeView_OnOpenRedEnvelopes_
__text:0000000100E586E8 SUB SP, SP, #0x70
__text:0000000100E586EC STP X24, X23, [SP,#0x30]
__text:0000000100E586F0 STP X22, X21, [SP,#0x40]
__text:0000000100E586F4 STP X20, X19, [SP,#0x50]
__text:0000000100E586F8 STP X29, X30, [SP,#0x60]
__text:0000000100E586FC ADD X29, SP, #0x60
__text:0000000100E58700 MOV X19, X0
__text:0000000100E58704 ADRP X8, #_OBJC_IVAR_$_WCRedEnvelopesReceiveHomeView.m_dicBaseInfo@PAGE
__text:0000000100E58708 LDRSW X24, [X8,#_OBJC_IVAR_$_WCRedEnvelopesReceiveHomeView.m_dicBaseInfo@PAGEOFF] ; NSDictionary *m_dicBaseInfo;
__text:0000000100E5870C LDR X0, [X19,X24]
__text:0000000100E58710 ADRP X8, #selRef_objectForKey_@PAGE
__text:0000000100E58714 LDR X20, [X8,#selRef_objectForKey_@PAGEOFF]
__text:0000000100E58718 ADRP X2, #cfstr_Issender_1@PAGE
__text:0000000100E5871C ADD X2, X2, #cfstr_Issender_1@PAGEOFF ; "isSender"
__text:0000000100E58720 MOV X1, X20
__text:0000000100E58724 BL _objc_msgSend
__text:0000000100E58728 MOV X29, X29
__text:0000000100E5872C BL _objc_retainAutoreleasedReturnValue
;上面是返回值: [self.m_dicBaseInfo objectForKey:@"isSender"]

__text:0000000100E58730 MOV X21, X0
__text:0000000100E58734 ADRP X8, #selRef_intValue@PAGE
__text:0000000100E58738 LDR X22, [X8,#selRef_intValue@PAGEOFF]
__text:0000000100E5873C MOV X1, X22
__text:0000000100E58740 BL _objc_msgSend

__text:0000000100E58744 MOV X23, X0
__text:0000000100E58748 MOV X0, X21
__text:0000000100E5874C BL _objc_release
__text:0000000100E58750 LDR X0, [X19,X24]
__text:0000000100E58754 ADRP X2, #cfstr_Hbtype_1@PAGE
__text:0000000100E58758 ADD X2, X2, #cfstr_Hbtype_1@PAGEOFF ; "hbType"
__text:0000000100E5875C MOV X1, X20
__text:0000000100E58760 BL _objc_msgSend
__text:0000000100E58764 MOV X29, X29
__text:0000000100E58768 BL _objc_retainAutoreleasedReturnValue
;上面是返回值: [self.m_dicBaseInfo objectForKey:@"hbType"]

__text:0000000100E5876C MOV X20, X0
__text:0000000100E58770 MOV X1, X22
__text:0000000100E58774 BL _objc_msgSend
__text:0000000100E58778 MOV X21, X0
__text:0000000100E5877C MOV X0, X20
__text:0000000100E58780 BL _objc_release
__text:0000000100E58784 ADRP X8, #classRef_NSString@PAGE
__text:0000000100E58788 LDR X0, [X8,#classRef_NSString@PAGEOFF]
__text:0000000100E5878C ADD W8, W21, #1
__text:0000000100E58790 CMP W23, #0
__text:0000000100E58794 MOV W9, #1
__text:0000000100E58798 CINC W9, W9, LE
__text:0000000100E5879C ADRP X10, #selRef_stringWithFormat_@PAGE
__text:0000000100E587A0 LDR X1, [X10,#selRef_stringWithFormat_@PAGEOFF]
__text:0000000100E587A4 ADRP X10, #stru_10330D018@PAGE
__text:0000000100E587A8 ADD X10, X10, #stru_10330D018@PAGEOFF
__text:0000000100E587AC MOV W11, #2
__text:0000000100E587B0 STP X11, X10, [SP,#0x20]
__text:0000000100E587B4 STP X9, XZR, [SP,#0x10]
__text:0000000100E587B8 MOV W9, #5
__text:0000000100E587BC STP X9, X8, [SP]
__text:0000000100E587C0 ADRP X2, #cfstr_UUUUU_1@PAGE ;
__text:0000000100E587C4 ADD X2, X2, #cfstr_UUUUU_1@PAGEOFF ; "%u,%u,%u,%u,%u,%@"
__text:0000000100E587C8 BL _objc_msgSend
__text:0000000100E587CC MOV X29, X29
__text:0000000100E587D0 BL _objc_retainAutoreleasedReturnValue
;上面是返回值: [NSString stringWithFormat:@"%u,%u,%u,%u,%u,%@"]

__text:0000000100E587D4 MOV X20, X0
__text:0000000100E587D8 MOV W0, #0x2DB5
__text:0000000100E587DC MOV X1, X20
__text:0000000100E587E0 MOV W2, #0
__text:0000000100E587E4 MOV W3, #0
__text:0000000100E587E8 BL sub_102923A8C
__text:0000000100E587EC ADRP X8, #_OBJC_IVAR_$_WCRedEnvelopesReceiveHomeView.m_delegate@PAGE
__text:0000000100E587F0 LDRSW X8, [X8,#_OBJC_IVAR_$_WCRedEnvelopesReceiveHomeView.m_delegate@PAGEOFF] ; WCRedEnvelopesReceiveHomeViewDelegate *m_delegate;
__text:0000000100E587F4 ADD X0, X19, X8
__text:0000000100E587F8 BL _objc_loadWeakRetained
__text:0000000100E587FC MOV X19, X0
__text:0000000100E58800 ADRP X8, #selRef_WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes@PAGE
__text:0000000100E58804 LDR X1, [X8,#selRef_WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes@PAGEOFF]
__text:0000000100E58808 BL _objc_msgSend
; 上面调用: [self.m_delegate WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]
;通过日志可以看出self.m_delegate类的类型为:WCRedEnvelopesReceiveControlLogic

__text:0000000100E5880C MOV X0, X19
__text:0000000100E58810 BL _objc_release
__text:0000000100E58814 MOV X0, X20
__text:0000000100E58818 LDP X29, X30, [SP,#0x60]
__text:0000000100E5881C LDP X20, X19, [SP,#0x50]
__text:0000000100E58820 LDP X22, X21, [SP,#0x40]
__text:0000000100E58824 LDP X24, X23, [SP,#0x30]
__text:0000000100E58828 ADD SP, SP, #0x70
__text:0000000100E5882C B _objc_release
__text:0000000100E5882C ; End of function -[WCRedEnvelopesReceiveHomeView OnOpenRedEnvelopes]

得出的大概伪代码:

1
2
3
4
5
6
7
8
//是否是消息发送者
int isSender = [[self.m_dicBaseInfo objectForKey:@"isSender"] intValue];
//红包类型
NSNumber *hbType = [self.m_dicBaseInfo objectForKey:@"hbType"];
//后面参数未知
NSString *unknownStr = [NSString stringWithFormat:@"%u,%u,%u,%u,%u,%@"];
//调用打开红包 WCRedEnvelopesReceiveControlLogic
[self.m_delegate WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]

接着我们通过上面调用方法的信息,反汇编 WCRedEnvelopesReceiveControlLogic的WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
text:00000001011FF35C ; void __cdecl -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes](WCRedEnvelopesReceiveControlLogic *self, SEL)
__text:00000001011FF35C __WCRedEnvelopesReceiveControlLogic_WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes_
... ;省略部分代码
__text:00000001011FF35C SUB SP, SP, #0x130
__text:00000001011FF360 STP D9, D8, [SP,#0x120+var_60]
__text:00000001011FF364 STP X28, X27, [SP,#0x120+var_50]
__text:00000001011FF368 STP X26, X25, [SP,#0x120+var_40]
__text:00000001011FF36C STP X24, X23, [SP,#0x120+var_30]
__text:00000001011FF370 STP X22, X21, [SP,#0x120+var_20]
__text:00000001011FF374 STP X20, X19, [SP,#0x120+var_10]
__text:00000001011FF378 STP X29, X30, [SP,#0x120+var_s0]
__text:00000001011FF37C ADD X29, SP, #0x120
__text:00000001011FF380 MOV X27, X0
__text:00000001011FF384 ADRP X8, #_OBJC_IVAR_$_WCRedEnvelopesControlLogic.m_data@PAGE ; WCRedEnvelopesControlData *m_data;
__text:00000001011FF388 NOP
__text:00000001011FF38C LDRSW X21, [X8,#_OBJC_IVAR_$_WCRedEnvelopesControlLogic.m_data@PAGEOFF] ; WCRedEnvelopesControlData *m_data;
__text:00000001011FF390 LDR X0, [X27,X21]
__text:00000001011FF394 ADRP X8, #selRef_m_oSelectedMessageWrap@PAGE
__text:00000001011FF398 LDR X19, [X8,#selRef_m_oSelectedMessageWrap@PAGEOFF]
__text:00000001011FF39C MOV X1, X19
__text:00000001011FF3A0 BL _objc_msgSend
__text:00000001011FF3A4 MOV X29, X29
__text:00000001011FF3A8 BL _objc_retainAutoreleasedReturnValue
;上面返回值 CMessageWrap *messageWrap = [self.m_data m_oSelectedMessageWrap];


__text:00000001011FF3AC MOV X22, X0 ;x0返回值,是messageWrap的地址
__text:00000001011FF3B0 ADRP X8, #selRef_m_oWCPayInfoItem@PAGE
__text:00000001011FF3B4 LDR X1, [X8,#selRef_m_oWCPayInfoItem@PAGEOFF]
__text:00000001011FF3B8 STR X1, [SP,#0x120+var_100] ;x1是m_oWCPayInfoItem方法地址
__text:00000001011FF3BC BL _objc_msgSend
__text:00000001011FF3C0 MOV X29, X29
__text:00000001011FF3C4 BL _objc_retainAutoreleasedReturnValue
;上面返回值 WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];

__text:00000001011FF3C8 MOV X23, X0
__text:00000001011FF3CC ADRP X8, #selRef_m_c2cNativeUrl@PAGE
__text:00000001011FF3D0 LDR X24, [X8,#selRef_m_c2cNativeUrl@PAGEOFF]
__text:00000001011FF3D4 MOV X1, X24
__text:00000001011FF3D8 BL _objc_msgSend
__text:00000001011FF3DC MOV X29, X29
__text:00000001011FF3E0 BL _objc_retainAutoreleasedReturnValue
;上面返回值 NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];

__text:00000001011FF3E4 MOV X25, X0
__text:00000001011FF3E8 ADRP X8, #selRef_length@PAGE
__text:00000001011FF3EC LDR X1, [X8,#selRef_length@PAGEOFF]
__text:00000001011FF3F0 ADRP X0, #cfstr_WxpayC2cbizmes_0@PAGE ; "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?"
__text:00000001011FF3F4 ADD X0, X0, #cfstr_WxpayC2cbizmes_0@PAGEOFF ; "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?"
__text:00000001011FF3F8 STR X1, [SP,#0x120+var_F8] ;[SP,#0x120+var_F8] = 字符串length方法
__text:00000001011FF3FC BL _objc_msgSend
__text:00000001011FF400 MOV X2, X0
__text:00000001011FF404 ADRP X8, #selRef_substringFromIndex_@PAGE
__text:00000001011FF408 LDR X1, [X8,#selRef_substringFromIndex_@PAGEOFF]
__text:00000001011FF40C MOV X0, X25
__text:00000001011FF410 BL _objc_msgSend
__text:00000001011FF414 MOV X29, X29
__text:00000001011FF418 BL _objc_retainAutoreleasedReturnValue
;上面有两个方法:1. [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length] 2. [m_c2cNativeUrl substringFromIndex]
;NSInterger index = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
;上面的返回值 : NSString *nativeUrlData = [m_c2cNativeUrl substringFromIndex:index];

__text:00000001011FF41C MOV X20, X0 ;x20是nativeUrlData
__text:00000001011FF420 MOV X0, X25 ;此时的x25是m_c2cNativeUrl的地址
__text:00000001011FF424 BL _objc_release
__text:00000001011FF428 MOV X0, X23
__text:00000001011FF42C BL _objc_release
__text:00000001011FF430 MOV X0, X22 ; x22 是messageWrap的地址
__text:00000001011FF434 BL _objc_release
__text:00000001011FF438 ADRP X8, #classRef_WCBizUtil@PAGE
__text:00000001011FF43C LDR X0, [X8,#classRef_WCBizUtil@PAGEOFF] ;x0是WCBizUtil
__text:00000001011FF440 ADRP X8, #selRef_dictionaryWithDecodedComponets_separator_@PAGE
__text:00000001011FF444 LDR X1, [X8,#selRef_dictionaryWithDecodedComponets_separator_@PAGEOFF] ;x1是dictionaryWithDecodedComponets_separator
__text:00000001011FF448 ADRP X3, #stru_10330F0F8@PAGE ; "&" x3是字符串 "&"
__text:00000001011FF44C ADD X3, X3, #stru_10330F0F8@PAGEOFF ; "&"
__text:00000001011FF450 STR X20, [SP,#0x120+var_E0]
__text:00000001011FF454 MOV X2, X20 ;x2 是nativeUrlData
__text:00000001011FF458 BL _objc_msgSend
__text:00000001011FF45C MOV X29, X29
__text:00000001011FF460 BL _objc_retainAutoreleasedReturnValue
;上面返回值:
;NSDictionary *nativeUrlDict = [WCBizUtil dictionaryWithDecodedComponets:nativeUrlData separator:@"&"]

__text:00000001011FF464 MOV X20, X0 ;x20 是 nativeUrlDict
__text:00000001011FF468 ADRP X8, #classRef_NSMutableDictionary@PAGE
__text:00000001011FF46C LDR X0, [X8,#classRef_NSMutableDictionary@PAGEOFF] ;x0是NSMutableDictionary
__text:00000001011FF470 ADRP X8, #selRef_dictionary@PAGE
__text:00000001011FF474 LDR X1, [X8,#selRef_dictionary@PAGEOFF] ;x1是dictionary
__text:00000001011FF478 BL _objc_msgSend
__text:00000001011FF47C MOV X29, X29
__text:00000001011FF480 BL _objc_retainAutoreleasedReturnValue
;上面返回值: NSMutableDictionary *dictM = [NSMutableDictionary dictionary];

__text:00000001011FF484 MOV X22, X0 ;x22是dictM
__text:00000001011FF488 ADRP X8, #selRef_safeSetObject_forKey_@PAGE
__text:00000001011FF48C LDR X25, [X8,#selRef_safeSetObject_forKey_@PAGEOFF]
__text:00000001011FF490 ADRP X2, #cfstr_1@PAGE ; "1"
__text:00000001011FF494 ADD X2, X2, #cfstr_1@PAGEOFF ; "1"
__text:00000001011FF498 ADRP X3, #cfstr_Msgtype_1@PAGE ; "msgType"
__text:00000001011FF49C ADD X3, X3, #cfstr_Msgtype_1@PAGEOFF ; "msgType"
__text:00000001011FF4A0 MOV X1, X25
__text:00000001011FF4A4 BL _objc_msgSend
;上面代码: [dictM setObject:@1 forKey:@"msgType"];

__text:00000001011FF4A8 ADRP X8, #selRef_objectForKey_@PAGE
__text:00000001011FF4AC LDR X23, [X8,#selRef_objectForKey_@PAGEOFF]
__text:00000001011FF4B0 ADRP X2, #cfstr_Sendid_2@PAGE ; "sendid"
__text:00000001011FF4B4 ADD X2, X2, #cfstr_Sendid_2@PAGEOFF ; "sendid"
__text:00000001011FF4B8 MOV X0, X20 ;x20是nativeUrlData
__text:00000001011FF4BC MOV X1, X23
__text:00000001011FF4C0 BL _objc_msgSend
__text:00000001011FF4C4 MOV X29, X29
__text:00000001011FF4C8 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id sendId = [nativeUrlData objectForKey:@"sendid"];

__text:00000001011FF4CC MOV X26, X0 ;X26是 sendId
__text:00000001011FF4D0 ADRP X3, #cfstr_Sendid_1@PAGE ; "sendId"
__text:00000001011FF4D4 ADD X3, X3, #cfstr_Sendid_1@PAGEOFF ; "sendId"
__text:00000001011FF4D8 MOV X0, X22 ;x22是dictM
__text:00000001011FF4DC MOV X1, X25 ;x25是方法setObject: forKey:
__text:00000001011FF4E0 MOV X2, X26 ;X26是sendId
__text:00000001011FF4E4 BL _objc_msgSend
;上面代码:[dictM setObject:sendId forKey: @"sendId"]

__text:00000001011FF4E8 MOV X0, X26
__text:00000001011FF4EC MOV X26, X21
__text:00000001011FF4F0 BL _objc_release
__text:00000001011FF4F4 ADRP X2, #cfstr_Channelid_0@PAGE ; "channelid"
__text:00000001011FF4F8 ADD X2, X2, #cfstr_Channelid_0@PAGEOFF ; "channelid"
__text:00000001011FF4FC STR X20, [SP,#0x120+var_E8]
__text:00000001011FF500 MOV X0, X20 ;x20是nativeUrlData
__text:00000001011FF504 MOV X1, X23 ;X23是 objectForKey
__text:00000001011FF508 BL _objc_msgSend
__text:00000001011FF50C MOV X29, X29
__text:00000001011FF510 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id channelId = [nativeUrlData objectForKey:@"channelid"]

__text:00000001011FF514 MOV X23, X0
__text:00000001011FF518 ADRP X3, #cfstr_Channelid@PAGE ; "channelId"
__text:00000001011FF51C ADD X3, X3, #cfstr_Channelid@PAGEOFF ; "channelId"
__text:00000001011FF520 MOV X0, X22
__text:00000001011FF524 MOV X1, X25
__text:00000001011FF528 MOV X2, X23
__text:00000001011FF52C BL _objc_msgSend
;上面代码:[dictM setObject:channelId forKey:@"channelId"]

__text:00000001011FF530 MOV X0, X23
__text:00000001011FF534 BL _objc_release
__text:00000001011FF538 ADRP X8, #classRef_MMServiceCenter@PAGE
__text:00000001011FF53C LDR X0, [X8,#classRef_MMServiceCenter@PAGEOFF] ;x0是MMServiceCenter
__text:00000001011FF540 ADRP X8, #selRef_defaultCenter@PAGE
__text:00000001011FF544 LDR X28, [X8,#selRef_defaultCenter@PAGEOFF]
__text:00000001011FF548 MOV X1, X28 ;x8是defaultCenter
__text:00000001011FF54C BL _objc_msgSend
__text:00000001011FF550 MOV X29, X29
__text:00000001011FF554 BL _objc_retainAutoreleasedReturnValue
;上面返回值:MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];
;MMServiceCenter 比较神奇,从classdump里找不到相关的头文件信息

__text:00000001011FF558 MOV X23, X0
__text:00000001011FF55C ADRP X8, #classRef_CContactMgr@PAGE
__text:00000001011FF560 LDR X0, [X8,#classRef_CContactMgr@PAGEOFF]
__text:00000001011FF564 ADRP X8, #selRef_class@PAGE
__text:00000001011FF568 LDR X1, [X8,#selRef_class@PAGEOFF]
__text:00000001011FF56C STR X1, [SP,#0x120+var_D0]
__text:00000001011FF570 BL _objc_msgSend
;上面代码:Class contactMgrCls = [CContactMgr class];

__text:00000001011FF574 MOV X2, X0
__text:00000001011FF578 ADRP X8, #selRef_getService_@PAGE
__text:00000001011FF57C LDR X1, [X8,#selRef_getService_@PAGEOFF]
__text:00000001011FF580 MOV X0, X23 ;X23是serviceCenter
__text:00000001011FF584 STR X1, [SP,#0x120+var_D8]
__text:00000001011FF588 BL _objc_msgSend
__text:00000001011FF58C MOV X29, X29
__text:00000001011FF590 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id contactMgrSer = [serviceCenter getService: contactMrgCls]

__text:00000001011FF594 MOV X21, X0
__text:00000001011FF598 ADRP X8, #selRef_getSelfContact@PAGE
__text:00000001011FF59C LDR X1, [X8,#selRef_getSelfContact@PAGEOFF]
__text:00000001011FF5A0 BL _objc_msgSend
__text:00000001011FF5A4 MOV X29, X29
__text:00000001011FF5A8 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id contactMgrSelfContact = [contactMgrSer getSelfContact];

__text:00000001011FF5AC MOV X20, X0
__text:00000001011FF5B0 MOV X0, X21
__text:00000001011FF5B4 BL _objc_release
__text:00000001011FF5B8 MOV X0, X23
__text:00000001011FF5BC BL _objc_release
__text:00000001011FF5C0 ADRP X8, #selRef_getContactDisplayName@PAGE
__text:00000001011FF5C4 LDR X1, [X8,#selRef_getContactDisplayName@PAGEOFF]
__text:00000001011FF5C8 MOV X0, X20
__text:00000001011FF5CC BL _objc_msgSend
__text:00000001011FF5D0 MOV X29, X29
__text:00000001011FF5D4 BL _objc_retainAutoreleasedReturnValue
;上面返回值: NSString *displayName = [contactMgrSelfContact getContactDisplayName];

__text:00000001011FF5D8 MOV X21, X0
__text:00000001011FF5DC ADRP X3, #cfstr_Nickname_4@PAGE ; "nickName"
__text:00000001011FF5E0 ADD X3, X3, #cfstr_Nickname_4@PAGEOFF ; "nickName"
__text:00000001011FF5E4 MOV X0, X22 ;x22是dictM
__text:00000001011FF5E8 MOV X1, X25 ;x25是方法setObject: forKey:
__text:00000001011FF5EC MOV X2, X21
__text:00000001011FF5F0 BL _objc_msgSend
;上面代码: [dictM setObject:displayName forKey: @"nickName"];

__text:00000001011FF5F4 MOV X0, X21
__text:00000001011FF5F8 BL _objc_release
__text:00000001011FF5FC ADRP X8, #selRef_m_nsHeadImgUrl@PAGE
__text:00000001011FF600 LDR X1, [X8,#selRef_m_nsHeadImgUrl@PAGEOFF]
__text:00000001011FF604 STR X20, [SP,#0x120+var_F0]
__text:00000001011FF608 MOV X0, X20
__text:00000001011FF60C BL _objc_msgSend
__text:00000001011FF610 MOV X29, X29
__text:00000001011FF614 BL _objc_retainAutoreleasedReturnValue
;上面返回值:NSString *headImgUrl = [contactMgrSelfContact m_nsHeadImgUrl];

__text:00000001011FF618 MOV X21, X0
__text:00000001011FF61C ADRP X3, #cfstr_Headimg_2@PAGE ; "headImg"
__text:00000001011FF620 ADD X3, X3, #cfstr_Headimg_2@PAGEOFF ; "headImg"
__text:00000001011FF624 MOV X0, X22
__text:00000001011FF628 MOV X1, X25
__text:00000001011FF62C MOV X2, X21
__text:00000001011FF630 BL _objc_msgSend
;上面代码:[dictM setObject: headImgUrl forKey:@"headImg"]

__text:00000001011FF634 MOV X0, X21
__text:00000001011FF638 BL _objc_release
__text:00000001011FF63C LDR X0, [X27,X26] ;x26=X21 即[X27, x26] = [x27,x21] self.m_data
__text:00000001011FF640 MOV X1, X19 ;X19是m_oSelectedMessageWrap方法
__text:00000001011FF644 BL _objc_msgSend
__text:00000001011FF648 MOV X29, X29
__text:00000001011FF64C BL _objc_retainAutoreleasedReturnValue
;上面返回值:CMessageWrap *messageWrap = [self.m_data m_oSelectedMessageWrap];

__text:00000001011FF650 MOV X21, X0
__text:00000001011FF654 BL _objc_release

__text:00000001011FF658 CBZ X21, loc_1011FF6CC ;如果messageWrap为空跳转loc_1011FF6CC
__text:00000001011FF65C LDR X0, [X27,X26]
__text:00000001011FF660 MOV X1, X19
__text:00000001011FF664 BL _objc_msgSend
__text:00000001011FF668 MOV X29, X29
__text:00000001011FF66C BL _objc_retainAutoreleasedReturnValue
;上面返回值:CMessageWrap *messageWrap = [self.m_data m_oSelectedMessageWrap];

__text:00000001011FF670 MOV X19, X0 ;x19是messageWrap
__text:00000001011FF674 LDR X1, [SP,#0x120+var_100] ; [SP,#0x120+var_100] 是m_oWCPayInfoItem方法地址
__text:00000001011FF678 BL _objc_msgSend
__text:00000001011FF67C MOV X29, X29
__text:00000001011FF680 BL _objc_retainAutoreleasedReturnValue
;上面返回值 WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];

__text:00000001011FF684 MOV X21, X0
__text:00000001011FF688 MOV X1, X24
__text:00000001011FF68C BL _objc_msgSend
__text:00000001011FF690 MOV X29, X29
__text:00000001011FF694 BL _objc_retainAutoreleasedReturnValue
;上面返回值 NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];

__text:00000001011FF698 MOV X23, X0
__text:00000001011FF69C ADRP X3, #cfstr_Nativeurl_4@PAGE ; "nativeUrl"
__text:00000001011FF6A0 ADD X3, X3, #cfstr_Nativeurl_4@PAGEOFF ; "nativeUrl"
__text:00000001011FF6A4 MOV X0, X22 ;x22是dictM
__text:00000001011FF6A8 MOV X1, X25 ;x25是方法setObject: forKey:
__text:00000001011FF6AC MOV X2, X23 ;
__text:00000001011FF6B0 BL _objc_msgSend
;上面代码:[dictM setObject:m_c2cNativeUrl forKey: @"nativeUrl"];

__text:00000001011FF6B4 MOV X0, X23
__text:00000001011FF6B8 BL _objc_release
__text:00000001011FF6BC MOV X0, X21
__text:00000001011FF6C0 BL _objc_release
__text:00000001011FF6C4 MOV X0, X19
__text:00000001011FF6C8 BL _objc_release

__text:00000001011FF6CC
__text:00000001011FF6CC loc_1011FF6CC ; CODE XREF: -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+2FC↑j
__text:00000001011FF6CC ADRP X8, #classRef_MMServiceCenter@PAGE
__text:00000001011FF6D0 LDR X0, [X8,#classRef_MMServiceCenter@PAGEOFF] ;MMServiceCenter
__text:00000001011FF6D4 STR X28, [SP,#0x120+var_100]
__text:00000001011FF6D8 MOV X1, X28 ;x28是defaultCenter
__text:00000001011FF6DC BL _objc_msgSend
__text:00000001011FF6E0 MOV X29, X29
__text:00000001011FF6E4 BL _objc_retainAutoreleasedReturnValue
;上面返回值 MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];

__text:00000001011FF6E8 MOV X21, X0
__text:00000001011FF6EC ADRP X8, #classRef_MMMsgLogicManager@PAGE
__text:00000001011FF6F0 LDR X0, [X8,#classRef_MMMsgLogicManager@PAGEOFF] ; MMMsgLogicManager
__text:00000001011FF6F4 LDR X1, [SP,#0x120+var_D0] ;class方法
__text:00000001011FF6F8 BL _objc_msgSend
;上面代码: Class logicMgrCls = [MMMsgLogicManager class];

__text:00000001011FF6FC MOV X2, X0
__text:00000001011FF700 MOV X0, X21
__text:00000001011FF704 LDR X1, [SP,#0x120+var_D8] ;getService方法
__text:00000001011FF708 BL _objc_msgSend
__text:00000001011FF70C MOV X29, X29
__text:00000001011FF710 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id logicMgrSer = [serviceCenter getService:logicMgrCls];

__text:00000001011FF714 MOV X23, X0
__text:00000001011FF718 ADRP X8, #selRef_GetCurrentLogicController@PAGE
__text:00000001011FF71C LDR X1, [X8,#selRef_GetCurrentLogicController@PAGEOFF]
__text:00000001011FF720 BL _objc_msgSend
__text:00000001011FF724 MOV X29, X29
__text:00000001011FF728 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id currentVC = [logicMgrSer GetCurrentLogicController];

__text:00000001011FF72C MOV X28, X0
__text:00000001011FF730 MOV X0, X23
__text:00000001011FF734 BL _objc_release
__text:00000001011FF738 MOV X0, X21
__text:00000001011FF73C BL _objc_release
__text:00000001011FF740 CBZ X28, loc_1011FF810 ;如果currentVC为nil,跳转到loc_1011FF810
__text:00000001011FF744 ADRP X8, #selRef_m_contact@PAGE
__text:00000001011FF748 LDR X21, [X8,#selRef_m_contact@PAGEOFF]
__text:00000001011FF74C MOV X0, X28
__text:00000001011FF750 MOV X1, X21
__text:00000001011FF754 BL _objc_msgSend
__text:00000001011FF758 MOV X29, X29
__text:00000001011FF75C BL _objc_retainAutoreleasedReturnValue
;上面返回值:id contact = [currentVC m_contact];

__text:00000001011FF760 MOV X23, X0
__text:00000001011FF764 CBZ X23, loc_1011FF810 ;如果contact为nil,跳转loc_1011FF810
__text:00000001011FF768 MOV X0, X28
__text:00000001011FF76C MOV X1, X21
__text:00000001011FF770 BL _objc_msgSend
__text:00000001011FF774 MOV X29, X29
__text:00000001011FF778 BL _objc_retainAutoreleasedReturnValue
;上面返回值:id contact = [currentVC m_contact];

__text:00000001011FF77C MOV X19, X26
__text:00000001011FF780 MOV X26, X0
__text:00000001011FF784 ADRP X8, #selRef_m_nsUsrName@PAGE
__text:00000001011FF788 LDR X24, [X8,#selRef_m_nsUsrName@PAGEOFF]
__text:00000001011FF78C MOV X1, X24
__text:00000001011FF790 BL _objc_msgSend
__text:00000001011FF794 MOV X29, X29
__text:00000001011FF798 BL _objc_retainAutoreleasedReturnValue
;上面返回值:NSString *userName = [contact m_nsUsrName];

__text:00000001011FF79C MOV X20, X0
__text:00000001011FF7A0 BL _objc_release
__text:00000001011FF7A4 MOV X0, X26
__text:00000001011FF7A8 MOV X26, X19
__text:00000001011FF7AC BL _objc_release
__text:00000001011FF7B0 MOV X0, X23
__text:00000001011FF7B4 BL _objc_release
__text:00000001011FF7B8 CBZ X20, loc_1011FF810 ;如果userName为空跳转到loc_1011FF810
__text:00000001011FF7BC MOV X0, X28
__text:00000001011FF7C0 MOV X1, X21
__text:00000001011FF7C4 BL _objc_msgSend
__text:00000001011FF7C8 MOV X29, X29
__text:00000001011FF7CC BL _objc_retainAutoreleasedReturnValue
;上面返回值:id contact = [currentVC m_contact];

__text:00000001011FF7D0 MOV X20, X0
__text:00000001011FF7D4 MOV X1, X24
__text:00000001011FF7D8 BL _objc_msgSend
__text:00000001011FF7DC MOV X29, X29
__text:00000001011FF7E0 BL _objc_retainAutoreleasedReturnValue
;上面返回值:NSString *userName = [contact m_nsUsrName];

__text:00000001011FF7E4 MOV X21, X0
__text:00000001011FF7E8 ADRP X3, #cfstr_Sessionusernam@PAGE ; "sessionUserName"
__text:00000001011FF7EC ADD X3, X3, #cfstr_Sessionusernam@PAGEOFF ; "sessionUserName"
__text:00000001011FF7F0 MOV X0, X22 ;x22是dictM
__text:00000001011FF7F4 MOV X1, X25 ;x25是方法setObject
__text:00000001011FF7F8 MOV X2, X21 ;x21是username
__text:00000001011FF7FC BL _objc_msgSend
;上面代码: [dictM setObject:userName forKey:@"sessionUserName"]
__text:00000001011FF800 MOV X0, X21
__text:00000001011FF804 BL _objc_release
__text:00000001011FF808 MOV X0, X20
__text:00000001011FF80C BL _objc_release
;判断语句结束

__text:00000001011FF810
__text:00000001011FF810 loc_1011FF810 ; CODE XREF: -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+3E4↑j
__text:00000001011FF810 ; -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+408↑j ...
__text:00000001011FF810 STP X28, X26, [SP,#0x120+var_110]
__text:00000001011FF814 LDR X0, [X27,X26] ;x0是 self.m_data
__text:00000001011FF818 ADRP X8, #selRef_m_structDicRedEnvelopesBaseInfo@PAGE ;m_structDicRedEnvelopesBaseInfo
__text:00000001011FF81C LDR X24, [X8,#selRef_m_structDicRedEnvelopesBaseInfo@PAGEOFF]
__text:00000001011FF820 MOV X1, X24
__text:00000001011FF824 BL _objc_msgSend
__text:00000001011FF828 MOV X29, X29
__text:00000001011FF82C BL _objc_retainAutoreleasedReturnValue
;返回值:NSDictionary* baseInfoDict = [self.m_data m_structDicRedEnvelopesBaseInfo];

__text:00000001011FF830 MOV X20, X0
__text:00000001011FF834 ADRP X8, #selRef_stringForKey_@PAGE
__text:00000001011FF838 LDR X1, [X8,#selRef_stringForKey_@PAGEOFF]
__text:00000001011FF83C ADRP X2, #cfstr_Timingidentifi@PAGE ; "timingIdentifier"
__text:00000001011FF840 ADD X2, X2, #cfstr_Timingidentifi@PAGEOFF ; "timingIdentifier"
__text:00000001011FF844 BL _objc_msgSend
__text:00000001011FF848 MOV X29, X29
__text:00000001011FF84C BL _objc_retainAutoreleasedReturnValue
; NSString *timingIdentifier = [baseInfoDict stringForKey:@"timingIdentifier"];

__text:00000001011FF850 MOV X19, X0
__text:00000001011FF854 MOV X0, X20
__text:00000001011FF858 BL _objc_release
__text:00000001011FF85C MOV X0, X19
__text:00000001011FF860 LDR X1, [SP,#0x120+var_F8] ;字符串length方法
__text:00000001011FF864 BL _objc_msgSend
; [timingIdentifier length]

__text:00000001011FF868 CBZ X0, loc_1011FF884 ;如果[timingIdentifier length] = 0 跳转 loc_1011FF884
__text:00000001011FF86C ADRP X3, #cfstr_Timingidentifi@PAGE ; "timingIdentifier"
__text:00000001011FF870 ADD X3, X3, #cfstr_Timingidentifi@PAGEOFF ; "timingIdentifier"
__text:00000001011FF874 MOV X0, X22
__text:00000001011FF878 MOV X1, X25
__text:00000001011FF87C MOV X2, X19
__text:00000001011FF880 BL _objc_msgSend
; [dictM setObject:timingIdentifier forKey:@"timingIdentifier"];

__text:00000001011FF884
__text:00000001011FF884 loc_1011FF884 ; CODE XREF: -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+50C↑j
__text:00000001011FF884 SUB X0, X29, #-var_68 ;x0 = (x29-var_68)
__text:00000001011FF888 MOV X1, X27
__text:00000001011FF88C BL _objc_initWeak
__text:00000001011FF890 ADRP X28, #classRef_MMServiceCenter@PAGE
__text:00000001011FF894 LDR X0, [X28,#classRef_MMServiceCenter@PAGEOFF]
__text:00000001011FF898 LDR X26, [SP,#0x120+var_100]
__text:00000001011FF89C MOV X1, X26
__text:00000001011FF8A0 BL _objc_msgSend
__text:00000001011FF8A4 MOV X29, X29
__text:00000001011FF8A8 BL _objc_retainAutoreleasedReturnValue
;上面返回值 MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];

__text:00000001011FF8AC MOV X20, X0
__text:00000001011FF8B0 STR X19, [SP,#0x120+var_F8]
__text:00000001011FF8B4 MOV X19, X27
__text:00000001011FF8B8 ADRP X27, #classRef_WCPayLogicMgr@PAGE
__text:00000001011FF8BC LDR X0, [X27,#classRef_WCPayLogicMgr@PAGEOFF]
__text:00000001011FF8C0 LDR X21, [SP,#0x120+var_D0]
__text:00000001011FF8C4 MOV X1, X21 ;x21是class
__text:00000001011FF8C8 BL _objc_msgSend
;Class payLogicMgrCls = [WCPayLogicMgr class];

__text:00000001011FF8CC MOV X2, X0
__text:00000001011FF8D0 MOV X0, X20 ;serviceCenter
__text:00000001011FF8D4 MOV X25, X22
__text:00000001011FF8D8 LDR X22, [SP,#0x120+var_D8] ;getService方法
__text:00000001011FF8DC MOV X1, X22
__text:00000001011FF8E0 BL _objc_msgSend
__text:00000001011FF8E4 MOV X29, X29
__text:00000001011FF8E8 BL _objc_retainAutoreleasedReturnValue
;id payLogicMgrSer = [serviceCenter getService: payLogicMgrCls];

__text:00000001011FF8EC MOV X23, X0
__text:00000001011FF8F0 ADRP X8, #selRef_setRealnameReportScene_@PAGE
__text:00000001011FF8F4 LDR X1, [X8,#selRef_setRealnameReportScene_@PAGEOFF]
__text:00000001011FF8F8 MOV W2, #0x3EB
__text:00000001011FF8FC BL _objc_msgSend
;[payLogicMgrSer setRealnameReportScene:@"0x3EB"]

__text:00000001011FF900 MOV X0, X23
__text:00000001011FF904 BL _objc_release
__text:00000001011FF908 MOV X0, X20
__text:00000001011FF90C BL _objc_release
__text:00000001011FF910 ADD X8, SP, #0x120+var_C8
__text:00000001011FF914 ADD X8, X8, #0x28
__text:00000001011FF918 STR X8, [SP,#0x120+var_118]
__text:00000001011FF91C LDR X0, [X28,#classRef_MMServiceCenter@PAGEOFF]
__text:00000001011FF920 MOV X1, X26
__text:00000001011FF924 BL _objc_msgSend
__text:00000001011FF928 MOV X29, X29
__text:00000001011FF92C BL _objc_retainAutoreleasedReturnValue
;上面返回值 MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];

__text:00000001011FF930 MOV X26, X0
__text:00000001011FF934 LDR X0, [X27,#classRef_WCPayLogicMgr@PAGEOFF]
__text:00000001011FF938 MOV X1, X21
__text:00000001011FF93C BL _objc_msgSend
__text:00000001011FF940 MOV X2, X0
__text:00000001011FF944 MOV X0, X26
__text:00000001011FF948 MOV X1, X22
__text:00000001011FF94C BL _objc_msgSend
__text:00000001011FF950 MOV X29, X29
__text:00000001011FF954 BL _objc_retainAutoreleasedReturnValue
;Class payLogicMgrCls = [WCPayLogicMgr class];

__text:00000001011FF958 MOV X27, X0
__text:00000001011FF95C LDR X8, [SP,#0x120+var_108]
__text:00000001011FF960 LDR X0, [X19,X8]
__text:00000001011FF964 MOV X1, X24
__text:00000001011FF968 BL _objc_msgSend
__text:00000001011FF96C MOV X29, X29
__text:00000001011FF970 BL _objc_retainAutoreleasedReturnValue
;返回值:NSDictionary* baseInfoDict = [self.m_data m_structDicRedEnvelopesBaseInfo];

__text:00000001011FF974 MOV X24, X0
__text:00000001011FF978 ADRP X8, #selRef_objectForKeyedSubscript_@PAGE
__text:00000001011FF97C LDR X1, [X8,#selRef_objectForKeyedSubscript_@PAGEOFF]
__text:00000001011FF980 ADRP X2, #cfstr_AgreeDuty@PAGE ; "agree_duty"
__text:00000001011FF984 ADD X2, X2, #cfstr_AgreeDuty@PAGEOFF ; "agree_duty"
__text:00000001011FF988 BL _objc_msgSend
__text:00000001011FF98C MOV X29, X29
__text:00000001011FF990 BL _objc_retainAutoreleasedReturnValue
; id agreeDuty = [baseInfoDict objectForKeyedSubscript:@"agree_duty"]

__text:00000001011FF994 MOV X20, X0
__text:00000001011FF998 ADRP X28, #__NSConcreteStackBlock_ptr@PAGE
__text:00000001011FF99C LDR X28, [X28,#__NSConcreteStackBlock_ptr@PAGEOFF] ; x28是NSConcreteStackBlock_ptr
__text:00000001011FF9A0 STR X28, [SP,#0x120+var_98] ;(sp+0x120+var_98) = x28
__text:00000001011FF9A4 ADRP X8, #qword_103101B78@PAGE
__text:00000001011FF9A8 LDR D8, [X8,#qword_103101B78@PAGEOFF]
__text:00000001011FF9AC ADR X8, sub_1011FFAD8
__text:00000001011FF9B0 NOP
;sub_1011FFAD8 子程序,分析里面的代码

__text:00000001011FF9B4 STR D8, [SP,#0x120+var_90]
__text:00000001011FF9B8 STR X8, [SP,#0x120+var_88]
__text:00000001011FF9BC ADRP X8, #unk_1032B3238@PAGE
__text:00000001011FF9C0 ADD X8, X8, #unk_1032B3238@PAGEOFF
__text:00000001011FF9C4 STP X8, X25, [SP,#0x120+var_80]
__text:00000001011FF9C8 MOV X0, X25 ;x25是dictM
__text:00000001011FF9CC BL _objc_retain
__text:00000001011FF9D0 MOV X22, X0
__text:00000001011FF9D4 MOV X0, X19
__text:00000001011FF9D8 BL _objc_retain
;第一个block参数 #0x120+var_98

__text:00000001011FF9DC MOV X23, X0
__text:00000001011FF9E0 STR X23, [SP,#0x120+var_70]
__text:00000001011FF9E4 STR X28, [SP,#0x120+var_C8]
__text:00000001011FF9E8 STR D8, [SP,#0x120+var_C0]
__text:00000001011FF9EC ADR X8, sub_1011FFBF0
__text:00000001011FF9F0 NOP
;sub_1011FFBF0 子程序,分析里面的代码

__text:00000001011FF9F4 STR X8, [SP,#0x120+var_B8]
__text:00000001011FF9F8 ADRP X8, #unk_1032B3268@PAGE
__text:00000001011FF9FC ADD X8, X8, #unk_1032B3268@PAGEOFF
__text:00000001011FFA00 STR X8, [SP,#0x120+var_B0]
__text:00000001011FFA04 SUB X1, X29, #-var_68
__text:00000001011FFA08 LDR X19, [SP,#0x120+var_118]
__text:00000001011FFA0C MOV X0, X19
__text:00000001011FFA10 BL _objc_copyWeak
__text:00000001011FFA14 MOV X0, X23
__text:00000001011FFA18 BL _objc_retain
;第二个block参数 #0x120+var_C8

__text:00000001011FFA1C STR X0, [SP,#0x120+var_A8]
__text:00000001011FFA20 ADRP X8, #selRef_checkHongbaoOpenLicense_acceptCallback_denyCallback_@PAGE
__text:00000001011FFA24 LDR X1, [X8,#selRef_checkHongbaoOpenLicense_acceptCallback_denyCallback_@PAGEOFF]
__text:00000001011FFA28 ADD X3, SP, #0x120+var_98
__text:00000001011FFA2C ADD X4, SP, #0x120+var_C8
__text:00000001011FFA30 MOV X0, X27
__text:00000001011FFA34 MOV X2, X20
__text:00000001011FFA38 BL _objc_msgSend
;- (void)checkHongbaoOpenLicense:(id)arg1 acceptCallback:(CDUnknownBlockType)arg2 denyCallback:(CDUnknownBlockType)arg3;
; [payLogicMgrCls checkHongbaoOpenLicense:agreeDuty acceptCallback: denyCallback: ]

__text:00000001011FFA3C MOV X0, X20
__text:00000001011FFA40 BL _objc_release
__text:00000001011FFA44 MOV X0, X24
__text:00000001011FFA48 BL _objc_release
__text:00000001011FFA4C MOV X0, X27
__text:00000001011FFA50 BL _objc_release
__text:00000001011FFA54 MOV X0, X26
__text:00000001011FFA58 BL _objc_release
__text:00000001011FFA5C LDR X0, [SP,#0x120+var_A8]
__text:00000001011FFA60 BL _objc_release
__text:00000001011FFA64 MOV X0, X19
__text:00000001011FFA68 BL _objc_destroyWeak
__text:00000001011FFA6C LDR X0, [SP,#0x120+var_70]
__text:00000001011FFA70 BL _objc_release
__text:00000001011FFA74 LDR X0, [SP,#0x120+var_78]
__text:00000001011FFA78 BL _objc_release
__text:00000001011FFA7C MOV X0, X22
__text:00000001011FFA80 BL _objc_release
__text:00000001011FFA84 SUB X0, X29, #-var_68
__text:00000001011FFA88 BL _objc_destroyWeak
__text:00000001011FFA8C LDR X0, [SP,#0x120+var_F8]
__text:00000001011FFA90 BL _objc_release
__text:00000001011FFA94 LDR X0, [SP,#0x120+var_110]
__text:00000001011FFA98 BL _objc_release
__text:00000001011FFA9C LDR X0, [SP,#0x120+var_F0]
__text:00000001011FFAA0 BL _objc_release
__text:00000001011FFAA4 LDR X0, [SP,#0x120+var_E8]
__text:00000001011FFAA8 BL _objc_release
__text:00000001011FFAAC LDR X0, [SP,#0x120+var_E0]
__text:00000001011FFAB0 BL _objc_release
__text:00000001011FFAB4 LDP X29, X30, [SP,#0x120+var_s0]
__text:00000001011FFAB8 LDP X20, X19, [SP,#0x120+var_10]
__text:00000001011FFABC LDP X22, X21, [SP,#0x120+var_20]
__text:00000001011FFAC0 LDP X24, X23, [SP,#0x120+var_30]
__text:00000001011FFAC4 LDP X26, X25, [SP,#0x120+var_40]
__text:00000001011FFAC8 LDP X28, X27, [SP,#0x120+var_50]
__text:00000001011FFACC LDP D9, D8, [SP,#0x120+var_60]
__text:00000001011FFAD0 ADD SP, SP, #0x130
__text:00000001011FFAD4 RET
__text:00000001011FFAD4 ; End of function -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]



__text:00000001011FFAD4
__text:00000001011FFAD8
__text:00000001011FFAD8 ; =============== S U B R O U T I N E =======================================
__text:00000001011FFAD8
__text:00000001011FFAD8 ; Attributes: bp-based frame
__text:00000001011FFAD8 ; 第一个block参数里面的代码
__text:00000001011FFAD8 sub_1011FFAD8 ; DATA XREF: -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+650↑o
__text:00000001011FFAD8
__text:00000001011FFAD8 var_20 = -0x20
__text:00000001011FFAD8 var_10 = -0x10
__text:00000001011FFAD8 var_s0 = 0
__text:00000001011FFAD8
__text:00000001011FFAD8 STP X22, X21, [SP,#-0x10+var_20]!
__text:00000001011FFADC STP X20, X19, [SP,#0x20+var_10]
__text:00000001011FFAE0 STP X29, X30, [SP,#0x20+var_s0]
__text:00000001011FFAE4 ADD X29, SP, #0x20
__text:00000001011FFAE8 MOV X19, X0
__text:00000001011FFAEC ADRP X8, #classRef_MMServiceCenter@PAGE
__text:00000001011FFAF0 LDR X0, [X8,#classRef_MMServiceCenter@PAGEOFF] ; void *
__text:00000001011FFAF4 ADRP X8, #selRef_defaultCenter@PAGE
__text:00000001011FFAF8 LDR X1, [X8,#selRef_defaultCenter@PAGEOFF] ; char *
__text:00000001011FFAFC BL _objc_msgSend
__text:00000001011FFB00 MOV X29, X29
__text:00000001011FFB04 BL _objc_retainAutoreleasedReturnValue
; [MMServiceCenter defaultCenter]

__text:00000001011FFB08 MOV X20, X0
__text:00000001011FFB0C ADRP X8, #classRef_WCRedEnvelopesLogicMgr@PAGE
__text:00000001011FFB10 LDR X0, [X8,#classRef_WCRedEnvelopesLogicMgr@PAGEOFF] ; void *
__text:00000001011FFB14 ADRP X8, #selRef_class@PAGE
__text:00000001011FFB18 LDR X1, [X8,#selRef_class@PAGEOFF] ; char *
__text:00000001011FFB1C BL _objc_msgSend
; [WCRedEnvelopesLogicMgr class]

__text:00000001011FFB20 MOV X2, X0
__text:00000001011FFB24 ADRP X8, #selRef_getService_@PAGE
__text:00000001011FFB28 LDR X1, [X8,#selRef_getService_@PAGEOFF] ; char *
__text:00000001011FFB2C MOV X0, X20 ; void *
__text:00000001011FFB30 BL _objc_msgSend
__text:00000001011FFB34 MOV X29, X29
__text:00000001011FFB38 BL _objc_retainAutoreleasedReturnValue
; WCRedEnvelopesLogicMgr *redEnvelopesLogicMgr = [[MMServiceCenter defaultCenter] getService: [WCRedEnvelopesLogicMgr class]];

__text:00000001011FFB3C MOV X21, X0
__text:00000001011FFB40 LDR X2, [X19,#0x20] ;[X19,#0x20] 是
__text:00000001011FFB44 ADRP X8, #selRef_OpenRedEnvelopesRequest_@PAGE
__text:00000001011FFB48 LDR X1, [X8,#selRef_OpenRedEnvelopesRequest_@PAGEOFF] ; char *
__text:00000001011FFB4C BL _objc_msgSend
; [redEnvelopesLogicMgr OpenRedEnvelopesRequest: ]

;下面是打开红包的后的UI操作
__text:00000001011FFB50 MOV X0, X21
__text:00000001011FFB54 BL _objc_release
__text:00000001011FFB58 MOV X0, X20
__text:00000001011FFB5C BL _objc_release
__text:00000001011FFB60 LDR X8, [X19,#0x28]
__text:00000001011FFB64 ADRP X9, #_OBJC_IVAR_$_WCBaseControlLogic.m_uiLogicStatus@PAGE ; unsigned int m_uiLogicStatus;
__text:00000001011FFB68 NOP
__text:00000001011FFB6C LDRSW X9, [X9,#_OBJC_IVAR_$_WCBaseControlLogic.m_uiLogicStatus@PAGEOFF] ; unsigned int m_uiLogicStatus;
__text:00000001011FFB70 MOV W10, #4
__text:00000001011FFB74 STR W10, [X8,X9]
__text:00000001011FFB78 LDR X8, [X19,#0x28]
__text:00000001011FFB7C ADRP X9, #_OBJC_IVAR_$_WCRedEnvelopesReceiveControlLogic.introView@PAGE ; WCRedEnvelopesReceiveHomeView *introView;
__text:00000001011FFB80 LDRSW X9, [X9,#_OBJC_IVAR_$_WCRedEnvelopesReceiveControlLogic.introView@PAGEOFF] ; WCRedEnvelopesReceiveHomeView *introView;
__text:00000001011FFB84 LDR X0, [X8,X9]
__text:00000001011FFB88 ADRP X8, #selRef_startReceiveAnimation@PAGE
__text:00000001011FFB8C LDR X1, [X8,#selRef_startReceiveAnimation@PAGEOFF]
__text:00000001011FFB90 LDP X29, X30, [SP,#0x20+var_s0]
__text:00000001011FFB94 LDP X20, X19, [SP,#0x20+var_10]
__text:00000001011FFB98 LDP X22, X21, [SP+0x20+var_20],#0x30
__text:00000001011FFB9C B _objc_msgSend
;显示打开红包的UI

__text:00000001011FFB9C ; End of function sub_1011FFAD8
__text:00000001011FFB9C


_
__text:00000001011FFBF0 sub_1011FFBF0 ; DATA XREF: -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes]+690↑o
__text:00000001011FFBF0
__text:00000001011FFBF0 var_10 = -0x10
__text:00000001011FFBF0 var_s0 = 0
__text:00000001011FFBF0
__text:00000001011FFBF0 STP X20, X19, [SP,#-0x10+var_10]!
__text:00000001011FFBF4 STP X29, X30, [SP,#0x10+var_s0]
__text:00000001011FFBF8 ADD X29, SP, #0x10
__text:00000001011FFBFC MOV X19, X0
__text:00000001011FFC00 ADD X0, X19, #0x28
__text:00000001011FFC04 BL _objc_loadWeakRetained
__text:00000001011FFC08 MOV X20, X0
__text:00000001011FFC0C ADRP X8, #selRef_WCRedEnvelopesReceiveHomeViewBack@PAGE
__text:00000001011FFC10 LDR X1, [X8,#selRef_WCRedEnvelopesReceiveHomeViewBack@PAGEOFF] ; char *
__text:00000001011FFC14 BL _objc_msgSend
__text:00000001011FFC18 MOV X0, X20
__text:00000001011FFC1C BL _objc_release
__text:00000001011FFC20 LDR X8, [X19,#0x20]
__text:00000001011FFC24 ADRP X9, #_OBJC_IVAR_$_WCRedEnvelopesReceiveControlLogic.introView@PAGE ; WCRedEnvelopesReceiveHomeView *introView;
__text:00000001011FFC28 LDRSW X9, [X9,#_OBJC_IVAR_$_WCRedEnvelopesReceiveControlLogic.introView@PAGEOFF] ; WCRedEnvelopesReceiveHomeView *introView;
__text:00000001011FFC2C LDR X0, [X8,X9]
__text:00000001011FFC30 ADRP X8, #selRef_endAnimation@PAGE
__text:00000001011FFC34 LDR X1, [X8,#selRef_endAnimation@PAGEOFF]
__text:00000001011FFC38 LDP X29, X30, [SP,#0x10+var_s0]
__text:00000001011FFC3C LDP X20, X19, [SP+0x10+var_10],#0x20
__text:00000001011FFC40 B _objc_msgSend ;结束动画
__text:00000001011FFC40 ; End of function sub_1011FFBF0

通过反汇编分析出的OC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
CMessageWrap *messageWrap = [self.m_data m_oSelectedMessageWrap];
WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];
NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
NSInterger index = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrlData = [m_c2cNativeUrl substringFromIndex:index];
NSDictionary *nativeUrlDict = [WCBizUtil dictionaryWithDecodedComponets:nativeUrlData separator:@"&"]
NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
[dictM setObject:@1 forKey:@"msgType"];
id sendId = [nativeUrlData objectForKey:@"sendid"];
[dictM setObject:sendId forKey: @"sendId"]
id channelId = [nativeUrlData objectForKey:@"channelid"]
[dictM setObject:channelId forKey:@"channelId"]
MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];
Class contactMgrCls = [CContactMgr class];
CContactMgr *contactMgrSer = [serviceCenter getService: contactMrgCls]
CBaseContact *contactMgrSelfContact = [contactMgrSer getSelfContact];
NSString *displayName = [contactMgrSelfContact getContactDisplayName];
[dictM setObject:displayName forKey: @"nickName"];
NSString *headImgUrl = [contactMgrSelfContact m_nsHeadImgUrl];
[dictM setObject: headImgUrl forKey:@"headImg"]

if([self.m_data m_oSelectedMessageWrap]){
CMessageWrap *messageWrap = [self.m_data m_oSelectedMessageWrap];
WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];
NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
[dictM setObject:m_c2cNativeUrl forKey: @"nativeUrl"];
}
MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];
Class logicMgrCls = [MMMsgLogicManager class];
MMMsgLogicManager *logicMgrSer = [serviceCenter getService:logicMgrCls];
BaseMsgContentLogicController *currentVC = [logicMgrSer GetCurrentLogicController];
if([currentVC m_contact];){
id contact = [currentVC m_contact];
NSString *userName = [contact m_nsUsrName];
id contact = [currentVC m_contact];
NSString *userName = [contact m_nsUsrName];
[dictM setObject:userName forKey:@"sessionUserName"]
}
NSDictionary* baseInfoDict = [self.m_data m_structDicRedEnvelopesBaseInfo];
NSString *timingIdentifier = [baseInfoDict stringForKey:@"timingIdentifier"];
if([timingIdentifier length] > 0){
[dictM setObject:timingIdentifier forKey:@"timingIdentifier"];
}
MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];
Class payLogicMgrCls = [WCPayLogicMgr class];
WCPayLogicMgr *payLogicMgrSer = [serviceCenter getService: payLogicMgrCls];
[payLogicMgrSer setRealnameReportScene:@"0x3EB"]

MMServiceCenter *serviceCenter = [MMServiceCenter defaultCenter];
NSDictionary* baseInfoDict = [self.m_data m_structDicRedEnvelopesBaseInfo];
id agreeDuty = [baseInfoDict objectForKeyedSubscript:@"agree_duty"];

//点击打开红包后的操作
[payLogicMgrSer checkHongbaoOpenLicense:agreeDuty acceptCallback: denyCallback: ];

acceptCallback block里面的相关的代码:

1
2
3
WCRedEnvelopesLogicMgr *redEnvelopesLogicMgr = [[MMServiceCenter defaultCenter] getService: [WCRedEnvelopesLogicMgr class]];

[redEnvelopesLogicMgr OpenRedEnvelopesRequest: dictM]

编写Tweak工程相关的代码,其中点击打开红包后的操作只使用 acceptCallback block里面的操作,其它的涉及到UI操作的省略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134


@interface WCBizUtil
+ (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2;
@end

@interface MMServiceCenter
+ (id)defaultCenter;
- (id)getService:(id)cls;
@end

@interface WCRedEnvelopesReceiveHomeView{
id m_delegate;
NSDictionary *m_dicBaseInfo;
}
@end

@interface WCPayInfoItem
@property(retain, nonatomic) NSString *m_c2cNativeUrl; // @synthesize m_oSelectedMessageWrap;
@end

@interface CMessageWrap
@property(retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem;
@end

@interface WCRedEnvelopesControlData

@property(retain, nonatomic) CMessageWrap *m_oSelectedMessageWrap;
@property(retain, nonatomic) NSDictionary *m_structDicRedEnvelopesBaseInfo;
@end

@interface WCRedEnvelopesReceiveControlLogic
{
WCRedEnvelopesControlData *m_data;
}
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes;
@end



@interface CContactMgr
- (id)getSelfContact;
@end

@interface CBaseContact

@property(retain, nonatomic) NSString *m_nsHeadImgUrl;
@property(retain, nonatomic) NSString *m_nsUsrName;
- (id)getContactDisplayName;

@end

@interface MMMsgLogicManager

- (id)GetCurrentLogicController;

@end

@interface BaseMsgContentLogicController

@property(retain, nonatomic) CBaseContact *m_contact;
@end

@interface WCPayLogicMgr
-(void)setRealnameReportScene:(int)sence;
@end

@interface WCRedEnvelopesLogicMgr
- (void)OpenRedEnvelopesRequest:(id)arg1;
@end

%hook WCRedEnvelopesReceiveControlLogic

- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes {
// %orig;
WCRedEnvelopesControlData *mData = MSHookIvar<WCRedEnvelopesControlData *>(self, "m_data");
CMessageWrap *messageWrap = [mData m_oSelectedMessageWrap];
WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];

NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
NSInteger index = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrlData = [m_c2cNativeUrl substringFromIndex:index];

NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrlData separator:@"&"];
NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
[dictM setObject:@"1" forKey:@"msgType"];
id sendId = [nativeUrlDict objectForKey:@"sendid"];
[dictM setObject:sendId forKey: @"sendId"];
id channelId = [nativeUrlDict objectForKey:@"channelid"];
[dictM setObject:channelId forKey:@"channelId"];

MMServiceCenter *serviceCenter = [%c(MMServiceCenter) defaultCenter];
Class contactMgrCls = [%c(CContactMgr) class];
CContactMgr *contactMgrSer = [serviceCenter getService: contactMgrCls];
CBaseContact *contactMgrSelfContact = [contactMgrSer getSelfContact];
NSString *displayName = [contactMgrSelfContact getContactDisplayName];
[dictM setObject:displayName forKey: @"nickName"];
NSString *headImgUrl = [contactMgrSelfContact m_nsHeadImgUrl];
[dictM setObject: headImgUrl forKey:@"headImg"];

if([mData m_oSelectedMessageWrap]){
CMessageWrap *messageWrap = [mData m_oSelectedMessageWrap];
WCPayInfoItem *payInfoItem = [messageWrap m_oWCPayInfoItem];
NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
[dictM setObject:m_c2cNativeUrl forKey: @"nativeUrl"];
}

Class logicMgrCls = [%c(MMMsgLogicManager) class];
MMMsgLogicManager *logicMgrSer = [serviceCenter getService:logicMgrCls];
BaseMsgContentLogicController *currentVC = [logicMgrSer GetCurrentLogicController];
if([currentVC m_contact]){
CBaseContact *contact = [currentVC m_contact];
NSString *userName = [contact m_nsUsrName];
[dictM setObject:userName forKey:@"sessionUserName"];
}
NSDictionary* baseInfoDict = [mData m_structDicRedEnvelopesBaseInfo];
NSString *timingIdentifier = [baseInfoDict objectForKey:@"timingIdentifier"];
if([timingIdentifier length] > 0){
[dictM setObject:timingIdentifier forKey:@"timingIdentifier"];
}

Class payLogicMgrCls = [%c(WCPayLogicMgr) class];
WCPayLogicMgr *payLogicMgrSer = [serviceCenter getService: payLogicMgrCls];
[payLogicMgrSer setRealnameReportScene:0x3EB];

NSLog(@"\nDictM\n\n %@", dictM);

//block 调用
WCRedEnvelopesLogicMgr *redEnvelopesLogicMgr = [serviceCenter getService: [%c(WCRedEnvelopesLogicMgr) class]];
[redEnvelopesLogicMgr OpenRedEnvelopesRequest: dictM];

}

%end

到这里我们会感觉越来越接近了,然后将编写的Tweak.xm运行起来,发送红包已抢成功!
到这我们进行分析WCRedEnvelopesLogicMgr

/opt/theos/bin/logify.pl ./WXHeaders/WCRedEnvelopesLogicMgr.h > Tweak.xm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

%hook WCRedEnvelopesLogicMgr
// - (void).cxx_destruct { %log; %orig; }
- (void)AsyncBizSubcribeRequest:(id)arg1 { %log; %orig; }
- (void)CheckAuthBizEnterpriseRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)ClearserSendOrReceiveRedEnveloperListRequest:(id)arg1 { %log; %orig; }
- (void)DeleteRedEnvelopesRecord:(id)arg1 { %log; %orig; }
- (void)GenH5RedEnvelopesPayRequest:(id)arg1 { %log; %orig; }
- (void)GenRedEnvelopesPayRequest:(id)arg1 { %log; %orig; }
- (void)GenYearRedEnvelopesPayRequest:(id)arg1 { %log; %orig; }
- (void)GetEnterpriseHongbaoBizRequest:(id)arg1 CMDID:(unsigned int)arg2 SendKey:(id)arg3 OutputType:(unsigned int)arg4 { %log; %orig; }
- (void)GetEnterpriseHongbaoBusinessRequest:(id)arg1 CMDID:(unsigned int)arg2 SendKey:(id)arg3 OutputType:(unsigned int)arg4 ShouldSubscribe:(_Bool)arg5 { %log; %orig; }
- (void)GetHongbaoBusinessRequest:(id)arg1 CMDID:(unsigned int)arg2 OutputType:(unsigned int)arg3 { %log; %orig; }
- (void)GetYearHongbaoRequest:(id)arg1 CMDID:(unsigned int)arg2 OutputType:(unsigned int)arg3 { %log; %orig; }
- (void)OnWCToAsyncBizSubscribeResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToBizHBCommonErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToBizHBCommonResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToBizHBCommonSystemErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToEnterpriseHBCommonErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToEnterpriseHBCommonResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToEnterpriseHBCommonSystemErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToHongbaoCommonErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToHongbaoCommonResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OnWCToHongbaoCommonSystemErrorResponse:(id)arg1 Request:(id)arg2 { %log; %orig; }
- (void)OpenBizEnterpriseRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)OpenEnterpriseRedEnvelopesRequest:(id)arg1 SendKey:(id)arg2 ShouldSubscribe:(_Bool)arg3 { %log; %orig; }
- (void)OpenRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)QueryRedEnvelopesDetailRequest:(id)arg1 { %log; %orig; }
- (void)QueryRedEnvelopesUserInfo:(id)arg1 { %log; %orig; }
- (void)QueryRedEnvelopesUserInfoNoCache:(id)arg1 { %log; %orig; }
- (void)QueryUserSendOrReceiveRedEnveloperListRequest:(id)arg1 { %log; %orig; }
- (void)ReceiveBizEnterpriseRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)SendShareRedEnvelopesoRequest:(id)arg1 { %log; %orig; }
- (void)ThanksForRedEnvelopesRequest:(id)arg1 { %log; %orig; }
- (void)addReceiveSystemMsgWithDic:(id)arg1 { %log; %orig; }
- (id)init { %log; id r = %orig; HBLogDebug(@" = %@", r); return r; }
// - (void)setM_senderNickNameHelper:(ContactUpdateHelper *)m_senderNickNameHelper { %log; %orig; }
// - (ContactUpdateHelper *)m_senderNickNameHelper { %log; ContactUpdateHelper * r = %orig; HBLogDebug(@" = %@", r); return r; }
- (NSString *)debugDescription { %log; NSString * r = %orig; HBLogDebug(@" = %@", r); return r; }
- (NSString *)description { %log; NSString * r = %orig; HBLogDebug(@" = %@", r); return r; }
- (unsigned long long )hash { %log; unsigned long long r = %orig; HBLogDebug(@" = %llu", r); return r; }
- (Class )superclass { %log; Class r = %orig; HBLogDebug(@" = %@", r); return r; }
%end

运行查看日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
打开红包View的日志:
Nov 15 19:02:36 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:31 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> ReceiverQueryRedEnvelopesRequest:{
agreeDuty = 0;
channelId = 1;
inWay = 1;
msgType = 1;
nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039401201711157020140209144&sendusername=wxid_y9bs6i3qil6m21&ver=6&sign=cb7ee087ec43110c0bc02a9120e5f2cca5194d7249f2384ec67a8a6d140a2664cc91bd9f3a6df2a1413e740620ddc015796f7d21d18da3c60ac48f0fe06044f5ac0b87b4724ca218adb6345e25f573e5";
sendId = 1000039401201711157020140209144;
}]
Nov 15 19:02:36 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:11 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> GetHongbaoBusinessRequest:{
agreeDuty = 0;
channelId = 1;
inWay = 1;
msgType = 1;
nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039401201711157020140209144&sendusername=wxid_y9bs6i3qil6m21&ver=6&sign=cb7ee087ec43110c0bc02a9120e5f2cca5194d7249f2384ec67a8a6d140a2664cc91bd9f3a6df2a1413e740620ddc015796f7d21d18da3c60ac48f0fe06044f5ac0b87b4724ca218adb6345e25f573e5";
sendId = 1000039401201711157020140209144;
} CMDID:3 OutputType:1]
Nov 15 19:02:36 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:21 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> OnWCToHongbaoCommonResponse:<HongBaoRes: 0x1609aa360> Request:<HongBaoReq: 0x160901060>]



点击红包view上面的开后的日志:
Nov 15 19:06:03 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:25 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> OpenRedEnvelopesRequest:{
channelId = 1;
headImg = "http://wx.qlogo.cn/mmhead/ver_1/dE3om8P2WCFmIe3beWMRicvRPveuUVF7X8xqpOle86QY9iaoqiazgaujFibEu9MhjLFtV4SoY8xZ2ExbrFYH4oxVRA/132";
msgType = 1;
nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039401201711157020140209144&sendusername=wxid_y9bs6i3qil6m21&ver=6&sign=cb7ee087ec43110c0bc02a9120e5f2cca5194d7249f2384ec67a8a6d140a2664cc91bd9f3a6df2a1413e740620ddc015796f7d21d18da3c60ac48f0fe06044f5ac0b87b4724ca218adb6345e25f573e5";
nickName = "\U6e05\U53f6\U6a80";
sendId = 1000039401201711157020140209144;
sessionUserName = "wxid_y9bs6i3qil6m21";
timingIdentifier = DEF5E3380DD95D53177182E094AB8619;
}]
Nov 15 19:06:03 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:11 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> GetHongbaoBusinessRequest:{
channelId = 1;
headImg = "http://wx.qlogo.cn/mmhead/ver_1/dE3om8P2WCFmIe3beWMRicvRPveuUVF7X8xqpOle86QY9iaoqiazgaujFibEu9MhjLFtV4SoY8xZ2ExbrFYH4oxVRA/132";
msgType = 1;
nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039401201711157020140209144&sendusername=wxid_y9bs6i3qil6m21&ver=6&sign=cb7ee087ec43110c0bc02a9120e5f2cca5194d7249f2384ec67a8a6d140a2664cc91bd9f3a6df2a1413e740620ddc015796f7d21d18da3c60ac48f0fe06044f5ac0b87b4724ca218adb6345e25f573e5";
nickName = "\U6e05\U53f6\U6a80";
sendId = 1000039401201711157020140209144;
sessionUserName = "wxid_y9bs6i3qil6m21";
timingIdentifier = DEF5E3380DD95D53177182E094AB8619;
} CMDID:4 OutputType:1]
Nov 15 19:06:04 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:21 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> OnWCToHongbaoCommonResponse:<HongBaoRes: 0x16094c730> Request:<HongBaoReq: 0x160883210>]
Nov 15 19:06:04 iPhone WeChat[8954] <Notice>: [redpocket] Tweak.xm:34 DEBUG: -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> addReceiveSystemMsgWithDic:{
SystemMsgContext = "<img src=\"SystemMessages_HongbaoIcon.png\"/> \U4f60\U9886\U53d6\U4e86$wxid_y9bs6i3qil6m21$\U7684<_wc_custom_link_ color=\"#FD9931\" href=\"weixin://weixinhongbao/opendetail?sendid=1000039401201711157020140209144&sign=cb7ee087ec43110c0bc02a9120e5f2cca5194d7249f2384ec67a8a6d140a2664cc91bd9f3a6df2a1413e740620ddc015796f7d21d18da3c60ac48f0fe06044f5ac0b87b4724ca218adb6345e25f573e5&ver=6\">\U7ea2\U5305</_wc_custom_link_>";
amount = 10;
canShare = 0;
changeWording = "\U5df2\U5b58\U5165\U96f6\U94b1\Uff0c\U53ef\U76f4\U63a5\U8f6c\U8d26";
hasWriteAnswer = 0;
hbStatus = 4;
hbType = 0;
headTitle = "";
isContinue = 0;
isSender = 0;
jumpChange = 1;
operationHeader = (
);
"real_name_info" = {
"guide_flag" = 0;
};
recAmount = 10;
recNum = 1;
receiveId = 1000039401000711157020140209144;
receiveStatus = 2;
record = (
{
answer = "";
receiveAmount = 10;
receiveId = 1000039401000711157020140209144;
receiveOpenId = 1000039401000711157020140209144;
receiveTime = 1510743964;
state = 1;
userName = "wxid_3ylu53d9rpy712";
}
);
sendId = 1000039401201711157020140209144;
sendUserName = "wxid_y9bs6i3qil6m21";
sessionUserName = "wxid_y9bs6i3qil6m21";
statusMess = "";
totalAmount = 10;
totalNum = 1;
watermark = "";
wishing = "\U606d\U559c\U53d1\U8d22\Uff0c\U5927\U5409\U5927\U5229";
}]

通过日志分析可知:

  1. -[WCRedEnvelopesLogicMgr ReceiverQueryRedEnvelopesRequest:{}] 类似获取红包信息的操作,拆开红包前调用
  2. -[<WCRedEnvelopesLogicMgr: 0x1600e9e30> OnWCToHongbaoCommonResponse:<HongBaoRes: 0x1609aa360> Request:<HongBaoReq: 0x160901060>] 拆开红包前后都调用
  3. -[WCRedEnvelopesLogicMgr OpenRedEnvelopesRequest:{}]拆开红包后调用,是真正决定抢红包的方法

重点分析这三个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

%hook WCRedEnvelopesLogicMgr
- (void)OnWCToHongbaoCommonResponse:(HongBaoRes *)arg1 Request:(HongBaoReq *)arg2 {
// %log;
%orig;
NSLog(@"HongBaoRes ---> cgiCmdid: %d platRet: %d retText: %@ platMsg : %@ ",arg1.cgiCmdid, arg1.platRet, arg1.retText, arg1.platMsg);

NSLog(@"HongBaoReq ---> cgiCmdid: %d outPutType : %d reqText: %@ ",arg2.cgiCmd, arg2.outPutType, arg2.reqText);

NSLog(@"HongBaoRes buffer: %@", [[NSString alloc] initWithData:arg1.retText.buffer encoding:NSUTF8StringEncoding]);
NSLog(@"HongBaoReq buffer: %@", [[NSString alloc] initWithData:arg2.reqText.buffer encoding:NSUTF8StringEncoding]);

if (arg1.retText.buffer.length>0)
{
// NSLog(@"arg1.retText.buffer:\n");

NSDictionary *retTextObj = [NSJSONSerialization JSONObjectWithData:arg1.retText.buffer options:0 error:nil];
NSLog(@"%@", retTextObj);
// NSString *retTextStr = [[NSString alloc] initWithData:arg1.retText.buffer encoding:NSUTF8StringEncoding];
// NSDictionary *retTextDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:retTextStr separator:@"&"];
// NSLog(@"retTextDict: %@",retTextDict);
}

if (arg2.reqText.buffer.length>0)
{
// NSLog(@"arg2.reqText.buffer :\n");
NSString *reqTextStr = [[NSString alloc] initWithData:arg2.reqText.buffer encoding:NSUTF8StringEncoding];
NSDictionary *reqTextDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:reqTextStr separator:@"&"];
NSLog(@"reqTextDict: %@",reqTextDict);
}


}

%end

%hook WCRedEnvelopesLogicMgr
- (void)OpenRedEnvelopesRequest:(id)arg1 {
%orig;
%log;
NSLog(@"OpenRedEnvelopesRequest param: %@", [arg1 class]);

}

- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1 { %log; %orig; }
%end

拼接参数,编写自动抢红包代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276


#import "YCHongBaoMgr.h"

@interface WCBizUtil
+ (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2;
+ (void)showAlert:(NSString *)msg;
+ (void)enableAutoOpenWithNativeUrl:(NSString *)nativeUrl;
+ (BOOL)isEnableAutoOpenWithNativeUrl:(NSString *)nativeUrl;
+ (void)autoOpenWithNativeUrl:(NSString *)nativeUrl;
@end

@interface SKBuiltinBuffer_t

+ (id)skBufferWithData:(id)arg1;

// Remaining properties
@property(retain, nonatomic) NSData *buffer; // @dynamic buffer;
@property(nonatomic) unsigned int iLen; // @dynamic iLen;

@end

@interface HongBaoReq

@property(retain, nonatomic) SKBuiltinBuffer_t *reqText; // @dynamic reqText;
@property(nonatomic) unsigned int cgiCmd; // @dynamic cgiCmd;
@property(nonatomic) unsigned int outPutType; // @dynamic outPutType;



@end

@interface HongBaoRes

@property(retain, nonatomic) SKBuiltinBuffer_t *retText; // @dynamic reqText;
@property(nonatomic) unsigned int cgiCmdid; // @dynamic cgiCmd;
@property(retain, nonatomic) NSString *platMsg; // @dynamic platMsg;
@property(nonatomic) int platRet; // @dynamic platRet;

@end

@interface MMServiceCenter
+ (id)defaultCenter;
- (id)getService:(id)cls;
@end

@interface CContactMgr
- (id)getSelfContact;
@end

@interface CBaseContact

@property(retain, nonatomic) NSString *m_nsHeadImgUrl;
@property(retain, nonatomic) NSString *m_nsUsrName;
- (id)getContactDisplayName;

@end

@interface WCPayInfoItem
@property(retain, nonatomic) NSString *m_c2cNativeUrl; // @synthesize m_oSelectedMessageWrap;
@end

@interface CMessageWrap
@property(retain, nonatomic) NSString *m_nsContent; // @synthesize m_nsContent;
@property(retain, nonatomic) NSString *m_nsDisplayName; // @synthesize m_nsDisplayName;
@property(retain, nonatomic) NSString *m_nsFromUsr; // @synthesize m_nsFromUsr;
@property(retain, nonatomic) NSString *m_nsToUsr; // @synthesize m_nsToUsr;
@property(nonatomic) int m_uiMessageType; // @synthesize m_uiMessageType;
@property(retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem;

@end

@interface WCRedEnvelopesLogicMgr

- (void)OpenRedEnvelopesRequest:(id)arg1;
- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1;
@end


%hook CMessageMgr

- (void)AsyncOnAddMsg:(NSString *)wxid MsgWrap:(CMessageWrap *)msg {

%orig;

int messageType = [msg m_uiMessageType];
NSString *fromUsr = [msg m_nsFromUsr];

if (messageType == 49)
{
NSLog(@"红包消息、转账消息");

WCPayInfoItem *payInfoItem = [msg m_oWCPayInfoItem];
NSString *m_c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
NSInteger index = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrlData = [m_c2cNativeUrl substringFromIndex:index];
NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrlData separator:@"&"];

BOOL isGroupHB = [fromUsr containsString:@"chatroom"];

//if msgtype == 1 is enable auto open red envelopes
id msgType = [nativeUrlDict valueForKey:@"msgtype"];
if([msgType isEqual: @"1"]){
[%c(WCBizUtil) enableAutoOpenWithNativeUrl:m_c2cNativeUrl];

//************ auto get red envelopes info ****************//
NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
//msgType: group and friend are same , value is 1
[dictM setObject:@"1" forKey:@"msgType"];
// agreeDuty is 0
[dictM setValue:@"0" forKey:@"agreeDuty"];
[dictM setValue:m_c2cNativeUrl forKey:@"nativeUrl"];
id sendId = [nativeUrlDict objectForKey:@"sendid"];
[dictM setObject:sendId forKey: @"sendId"];
id channelId = [nativeUrlDict objectForKey:@"channelid"];
[dictM setObject:channelId forKey:@"channelId"];
//group hb is 0 ,friend hb is 1
if(isGroupHB){
[dictM setObject:@"0" forKey:@"inWay"];
}else{
[dictM setObject:@"1" forKey:@"inWay"];
}

NSLog(@"dictM: %@", dictM);
// auto get red envelope info
WCRedEnvelopesLogicMgr *redEnvelopesLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService: [%c(WCRedEnvelopesLogicMgr) class]];
[redEnvelopesLogicMgr ReceiverQueryRedEnvelopesRequest:dictM];


}else{
NSLog(@"msgtype : %@ mgtype class: %@", msgType, [msgType class]);
}
}

}
%end


%hook WCRedEnvelopesLogicMgr
- (void)OnWCToHongbaoCommonResponse:(HongBaoRes *)arg1 Request:(HongBaoReq *)arg2 {
%orig;

//HongBaoRes.cgiCmdid = 3 is get hongbao info, .cgiCmdid = 4 is open hongbao
if(arg1.retText.buffer.length>0 && arg2.reqText.buffer.length>0 && arg1.cgiCmdid == 3 ){

//********** auto open red envelopes **********//

//HonBaoRes
NSDictionary *retTextObj = [NSJSONSerialization JSONObjectWithData:arg1.retText.buffer options:0 error:nil];
//HonBaoReq
NSString *reqTextStr = [[NSString alloc] initWithData:arg2.reqText.buffer encoding:NSUTF8StringEncoding];
NSDictionary *reqTextDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:reqTextStr separator:@"&"];

NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
[dictM setValue:@"1" forKey:@"msgType"];
//m_c2cNativeUrl is url encode
NSString *m_c2cNativeUrl = [reqTextDict valueForKey:@"nativeUrl"];

//decode url
m_c2cNativeUrl = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,(CFStringRef)m_c2cNativeUrl, CFSTR(""),kCFStringEncodingUTF8));


if(![%c(WCBizUtil) isEnableAutoOpenWithNativeUrl:m_c2cNativeUrl]){
return;
}else{
[%c(WCBizUtil) autoOpenWithNativeUrl:m_c2cNativeUrl];
}

NSInteger index = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrlData = [m_c2cNativeUrl substringFromIndex:index];

NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrlData separator:@"&"];
id sendId = [nativeUrlDict valueForKey:@"sendid"];
[dictM setValue:sendId forKey: @"sendId"];
id channelId = [nativeUrlDict valueForKey:@"channelid"];
[dictM setValue:channelId forKey:@"channelId"];

MMServiceCenter *serviceCenter = [%c(MMServiceCenter) defaultCenter];
Class contactMgrCls = [%c(CContactMgr) class];
CContactMgr *contactMgrSer = [serviceCenter getService: contactMgrCls];
CBaseContact *contactMgrSelfContact = [contactMgrSer getSelfContact];
NSString *displayName = [contactMgrSelfContact getContactDisplayName];
[dictM setValue:displayName forKey: @"nickName"];
NSString *headImgUrl = [contactMgrSelfContact m_nsHeadImgUrl];
[dictM setValue: headImgUrl forKey:@"headImg"];
[dictM setValue:m_c2cNativeUrl forKey: @"nativeUrl"];

NSString *userName = [nativeUrlDict valueForKey:@"sendusername"];
if(userName.length > 0){
[dictM setValue:[nativeUrlDict valueForKey:@"sendusername"] forKey:@"sessionUserName"];
}

NSString *timingIdentifier = [retTextObj valueForKey:@"timingIdentifier"];
if([timingIdentifier length] > 0){
[dictM setValue:timingIdentifier forKey:@"timingIdentifier"];
}

NSLog(@"dictM Count:%lu data: %@",[dictM count], dictM);

//等待0.5s
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//auto open red envelopes
WCRedEnvelopesLogicMgr *redEnvelopesLogicMgr = [serviceCenter getService: [%c(WCRedEnvelopesLogicMgr) class]];
[redEnvelopesLogicMgr OpenRedEnvelopesRequest: dictM];
});
}
}


%end

%hook WCRedEnvelopesLogicMgr
- (void)OpenRedEnvelopesRequest:(id)arg1 {
%orig;
%log;
}

- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1 { %log; %orig; }
%end


%hook MicroMessengerAppDelegate

- (_Bool)application:(id)arg1 didFinishLaunchingWithOptions:(id)arg2 {
%log;
[%c(YCHongBaoMgr) showAlert:@"start...."];
return %orig;
}

%end

%hook WCBizUtil

%new
+ (void)enableAutoOpenWithNativeUrl:(NSString *)nativeUrl{

NSMutableDictionary *dictM = [[NSUserDefaults standardUserDefaults] valueForKey:@"AutoOpenWithNativeUrl"];

if (!dictM) {
dictM = [NSMutableDictionary dictionary];
}else{
dictM = [NSMutableDictionary dictionaryWithDictionary:dictM];
}
[dictM setValue:@1 forKey:nativeUrl];
[[NSUserDefaults standardUserDefaults] setObject:dictM forKey:@"AutoOpenWithNativeUrl"];
}
%new
+ (BOOL)isEnableAutoOpenWithNativeUrl:(NSString *)nativeUrl{
NSMutableDictionary *dictM = [[NSUserDefaults standardUserDefaults] valueForKey:@"AutoOpenWithNativeUrl"];
if (dictM) {
NSNumber *val = [dictM valueForKey:nativeUrl];
if (val.intValue == 1) {
return true;
}
}

return false;
}
%new
+ (void)autoOpenWithNativeUrl:(NSString *)nativeUrl {
NSMutableDictionary *dictM = [[NSUserDefaults standardUserDefaults] valueForKey:@"AutoOpenWithNativeUrl"];
if (dictM) {
dictM = [NSMutableDictionary dictionaryWithDictionary:dictM];
[dictM setValue:@0 forKey:nativeUrl];
[[NSUserDefaults standardUserDefaults] setObject:dictM forKey:@"AutoOpenWithNativeUrl"];
}

}


%new
+ (void)showAlert:(NSString *)msg {
[[[UIAlertView alloc] initWithTitle:msg message:nil delegate:nil cancelButtonTitle:@"confirm" otherButtonTitles:nil, nil] show];
}

%end