转载

iOS安全–在非越狱平台进行越狱开发(附分析流程)

目的:在不越狱的前提下,使用动态库库注入的方式来hook应用的某些函数以篡改应用行为。

需要的工具:

砸壳: dumpdecrypted

class-dump: class-dump

Cycript: cycript

IDA: ida demo

theos: theos

iosopendev: iosopendev

调试: lldb+debugserver

本文以微信自动抢红包为例,虽然教程很多了,但还是从如何获取关键调用函数的过程来分析。

以下内容仅供研究学习,请不要用于非法用途,笔者概不负责。

进入正题:

1.砸壳:

参考文章: http://www.blogfshare.com/dumpdecrypted-app.html

获取Document目录:

[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]

iOS安全–在非越狱平台进行越狱开发(附分析流程)

iOS安全–在非越狱平台进行越狱开发(附分析流程)

如果不想自己砸壳,可以直接从PP助手上下载一个即可,已经砸过壳的。

2.class-dump:

参考文章: http://www.blogfshare.com/ioss-class-dump-z.html

使用:class-dump-z WeChat.decrypted -H -o OutPutHeaders

拿到头文件后,新建一个Xcode工程,然后把头文件拖进去备用查找。

iOS安全–在非越狱平台进行越狱开发(附分析流程)

3.开始分析工作:

先要找到从别人发来的消息是哪个函数在处理。

首先还是从界面入手,随便进入一个群聊天界面,使用Cycript显示出界面结构:

iOS安全–在非越狱平台进行越狱开发(附分析流程)

随便找一个其中的控件,然后找到它的controller。

iOS安全–在非越狱平台进行越狱开发(附分析流程)

找到了一个叫BaseMsgContentViewController的ViewController,使用theos Logify的方法来跟踪这个类。

参考博文: http://www.blogfshare.com/ioss-theos-logify.html

打开群聊界面,往该群组发送消息,从log输出可以看到添加消息节点的调用:

- [<BaseMsgContentViewController: 0x1638b200> addMessageNode:{m_uiMesLocalID=76, m_ui64MesSvrID=2873926057328047596, m_nsFromUsr=1759668824@chatroom, m_nsToUsr=wxi*l12~19, m_uiStatus=4, type=1, msgSource=”<msgsource>

<silence>0</silence>

<membercount>3</membercount>

</msgsource>

“}  layout:1 addMoreMsg:0]

为了获取这个消息包的来源,下面要使用lldb进行调试,查看堆栈调用。

附加微信进程,使用 image list -o -f 获取微信模块加载的基地址,这里基地址为:    0xad000

-[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]:的文件偏移地址为:0x0154a084

下断点:

br s -a ’0xad000+0x0154a084′

iOS安全–在非越狱平台进行越狱开发(附分析流程)

计算0x017dd7f4在文件中的地址:

0x017dd7f4 – 0xad000 = 0x17307F4

而这个地址在:

-[BaseMsgContentLogicController DidAddMsg:]

继续 回溯:

0×01149684 – 0xad000 = 0x109C684

这个地址在:

-[RoomContentLogicController DidAddMsg:]

0x017dda3e -  0xad000 = 0x1730A3E

这个地址在:

-[BaseMsgContentLogicController OnAddMsg:MsgWrap:]:

0x01e44d42 – 0xad000 = 0x1D97D42

这个地址在:

-[CMessageMgr MainThreadNotifyToExt:]:

到此,整个流程基本就出来了:

-[CMessageMgr MainThreadNotifyToExt:]:

–>

-[BaseMsgContentLogicController OnAddMsg:MsgWrap:]:

——>

-[RoomContentLogicController DidAddMsg:]

———->

-[BaseMsgContentLogicController DidAddMsg:]

—————->

-[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]:

跟踪类CMessageMgr,继续发送消息测试。

通过log可以获取到大致的流程如下:

-[CMessageMgr MessageReturn:MessageInfo:Event:]

–>

-[CMessageMgr AsyncOnAddMsg:MsgWrap:]

——>

-[CMessageMgr MainThreadNotifyToExt:]

这就是为什么很多文章都说要在-[CMessageMgr AsyncOnAddMsg:MsgWrap:]这个函数拦截消息的原因了。

接着发个红包看看消息包的内容:

mesType:49

sender:175***68824@chatroom

to:wxid_wtrsjdfy64il12

content:xia***g28:

<msg><appmsg appid=”” sdkver=””><des><![CDATA[我给你发了一个红包,赶紧去拆!]]></des><url><![CDATA[https://wxapp.tenpay.com/mmpayhb/wxhb_personalreceive?showwxpaytitle=1&msgtype=1&channelid=1&sendid=10000373012016032560109227249&ver=6&sign=3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c]]></url><type><![CDATA[2001]]></type><title><![CDATA[微信红包]]></title><thumburl><![CDATA[http://wx.gtimg.com/hongbao/img/hb.png]]></thumburl><wcpayinfo><templateid><![CDATA[7a2a165d31da7fce6dd77e05c300028a]]></templateid><url><![CDATA[https://wxapp.tenpay.com/mmpayhb/wxhb_personalreceive?showwxpaytitle=1&msgtype=1&channelid=1&sendid=10000373012016032560109227249&ver=6&sign=3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c]]></url><iconurl><![CDATA[http://wx.gtimg.com/hongbao/img/hb.png]]></iconurl><receivertitle><![CDATA[恭喜发财,大吉大利!]]></receivertitle><sendertitle><![CDATA[恭喜发财,大吉大利!]]></sendertitle><scenetext><![CDATA[微信红包]]></scenetext><senderdes><![CDATA[查看红包]]></senderdes><receiverdes><![CDATA[领取红包]]></receiverdes><nativeurl><![CDATA[wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=10000373012016032560109227249&sendusername=xia***g28&ver=6&sign=3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c]]></nativeurl><sceneid><![CDATA[1002]]></sceneid><innertype><![CDATA[0]]></innertype><scenetext>微信红包</scenetext></wcpayinfo></appmsg><fromusername><![CDATA[xia***g28]]></fromusername></msg>

mesSource:<msgsource>

<silence>0</silence>

<membercount>3</membercount>

</msgsource>

4.接着分析工作:

上面已经得到了接受消息的处理函数,然后怎么自动去打开这个红包呢?

还是从领取红包的界面入手:

iOS安全–在非越狱平台进行越狱开发(附分析流程)

hookWCRedEnvelopesReceiveHomeView这个类,可以从log看到打开红包的时候调用-[WCRedEnvelopesReceiveHomeView OnOpenRedEnvelopes]这个函数:

- [<WCRedEnvelopesReceiveHomeView: 0x1656f120; frame = (0 0; 1024 768); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x14da5c40>> OnOpenRedEnvelopes]

IDA分析:

iOS安全–在非越狱平台进行越狱开发(附分析流程)

在IDA里面搜索函数:WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes

发现只有WCRedEnvelopesReceiveControlLogic这个类里面有这个函数,用IDA跟进该函数:

iOS安全–在非越狱平台进行越狱开发(附分析流程)

基本流程如下:

获取红包的消息包,得到消息包的m_oWCPayInfoItem属性,然后拿出m_c2cNativeUrl除了wxpay://c2cbizmessagehandler/hongbao/receivehongbao?的其它部分。

wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=10000373012016032560109227249&sendusername=xia***g28&ver=6&sign=3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c

msgtype=1&channelid=1&sendid=10000373012016032560109227249&sendusername=xia***g28&ver=6&sign=3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c

按&拆分

{

channelid = 1;

msgtype = 1;

sendid = 10000373012016032560109227249;

sendusername = xia***g28;

sign = 3c0406fab3e5e2a2ed90be8e3da61374f54487b1c693ac55e8204cf045d78c36f8b2047dc28e667d2b9f451b319346f7565c756549d5843d2f44f89243fbf8539e09da7690ec31bbbf5c7c9cde86b3286bf0870e998fca308668b1d5fbf20f8c;

ver = 6;

}

生成字典:

{

channelId = 1;

msgType = 1;

sendId = 10000373012016032560109227249;

}

拿到个人资料:

[[[MMServiceCenter defaultCenter] getService:[CContactMgr class]] getSelfContact]

拿到昵称和头像:

getContactDisplayName

m_nsHeadImgUrl

加到字典:

{

channelId = 1;

headImg = “http://wx.qlogo.cn/mmhead/ver_1/c6Dx0qq06keVnF3LTicYUaZYVT572gsyzNzbUc7lMPanMdTAsmhhbZPHCLhM1AbAAPhibbEzCC1QEaVwguTgtqEsbichAcaNwaYDmVvmcj7eyE/132″;

msgType = 1;

nickName = “/U963f/U55b5″;

sendId = 10000373012016032560109227249;

}

获取nativeurl和当前群id加入字典:

[[[MMServiceCenter defaultCenter] getService:[MMMsgLogicManager class]] GetCurrentLogicController]

最后调用请求接口:

[[[MMServiceCenter defaultCenter] getService:[WCRedEnvelopesLogicMgr class]] OpenRedEnvelopesRequest:dic]

所以可以通过拦截消息包,然后构造请求参数,最后调用接口打开红包。

5.动手写Tweak:

先在越狱机器上进行越狱开发,后面再说怎么迁移到非越狱机器上去,新建一个Logos Tweak工程。

iOS安全–在非越狱平台进行越狱开发(附分析流程)

编写代码如下:

%hook CMessageMgr    -(void)AsyncOnAddMsg:(id)message MsgWrap:(CMessageWrap* )msgWrap {      %log;      if(msgWrap.m_uiMessageType == 49){          CContactMgr *contactManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]];          CBaseContact *selfContact = [contactManager getSelfContact];                    if ([msgWrap.m_nsContent rangeOfString:@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao"].location != NSNotFound) { // 红包                                NSString *nativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];                  nativeUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]];                                    NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl separator:@"&"];                                                      NSMutableDictionary *args = [[%c(NSMutableDictionary) alloc] init];                  [args addObject:nativeUrlDict[@"msgtype"] forKey:@"msgType"];                  [args addObject:nativeUrlDict[@"sendid"] forKey:@"sendId"];                  [args addObject:nativeUrlDict[@"channelid"] forKey:@"channelId"];                  [args addObject:[selfContact getContactDisplayName] forKey:@"nickName"];                  [args addObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];                  [args addObject:nativeUrl forKey:@"nativeUrl"];                  [args addObject:msgWrap.m_nsFromUsr forKey:@"sessionUserName"];                                    [[[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]] OpenRedEnvelopesRequest:args];          }      }  }    %end

运行,发送红包,秒抢成功!

6.迁移到非越狱机器:

刚刚只是在进行越狱平台的开发,如果想把代码迁移到非越狱平台运行就继续往下看。

这篇文章也提到过这种方式 http://www.blogfshare.com/inject-with-njb.html 。

编写dylib,注入load command,重新名,运行。

这里想直接只用越狱环境编译的dylib,但是该动态库依赖于libsubstrate.dylib。

➜   otool -L WeChatTweak.dylib

WeChatTweak.dylib (architecture armv7):

/Library/MobileSubstrate/DynamicLibraries/WeChatTweak.dylib (compatibility version 1.0.0, current version 1.0.0)

/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)

原来依赖的是CydiaSubstrate,这里修改为libsubstrate.dylib。

注入动态库: iOS安全–在非越狱平台进行越狱开发(附分析流程)

使用insert_dylib工具把自己的动态库注入到微信可执行文件。

./insert_dylib @executable_path/WechatTweak.dylib WeChat

动态库重签名:

codesign -f -s “iPhone Developer******”      ***.dylib 对动态库进行签名

然后拷贝两个动态库到可执行文件的目录下,再拷贝embedded.mobileprovision到可执行文件目录。

修改Info.plist文件的Bundle id。

编写Entitlements.plist文件:

<?xml version=”1.0″ encoding=”UTF-8″?>

<!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.developer.team-identifier</key>

<string>>**********.</string>

<key>application-identifier</key>

<string>**********.com.codesign.demo</string>

<key>get-task-allow</key>

<true/>

</dict>

</plist>

对已经签过名的可执行文件调用ldid -e 即可获取这些信息。

重签名:

codesign -f -s “iPhone Developer:******” –entitlements  Entitlements.plist ./WeChat.app

至于微信其它的一些extension,重签名也可以,否则直接把Watch和Plugins目录删除。

打包:

xcrun -sdk iphoneos PackageApplication -v WeChat.app -o ~/WeChat.ipa

最后使用iTools安装即可。

7.调试小技巧:

新建一个ios 应用的Target,就叫WeChat。

在工程的Build Phases加入自己的脚本,完成以上的重签名操作,然后把重签名生成的WeChat.app覆盖调用上面target生成的app。

iOS安全–在非越狱平台进行越狱开发(附分析流程)

这样就是可以在自己编写的动态库里面下好断点,然后点击运行,Xcode便会自动执行脚本,完成重签名的操作,然后安装重签名后的微信,进入调试模式。

然后就可以愉快的在微信里面调试自己的动态库了~~~~

原文  http://www.blogfshare.com/wechat-openredenvelopes.html
正文到此结束
Loading...