转载于2016/07/25,搬迁到思否。
如果您有急躁看完这篇文章,您将懂得如何着手进行app的剖析、追踪、注入等实用的破解技术,另外,通过“入侵”,将帮忙您了解如何躲避常见的安全漏洞,文章纲要:
- 简略介绍ios二进制文件构造与入侵的原理
- 介绍入侵罕用的工具和办法,包含pc端和手机端
- 解说黑客技术中的动态剖析和动静分析法
- 通过一个简略的实例,来介绍如何综合使用砸壳、寻找注入点、lldb近程调试、追踪、反汇编技术来进行黑客实战
- 解说越狱破解补丁和不需越狱的破解补丁制作方法和差异
黑客的素养
- 敏锐的嗅觉 有时候通过一个函数名,一个类名,就能大抵的判断出它的作用,这就是嗅觉;功力已臻化境时,甚至能够应用第六感判断出一些注入点
- 面对失败的勇气 破解有时候很耗时,和程序开发正好相同,它耗时不是耗在写代码上,而是耗在寻找注入点和逆向工程上,有可能你花了3天工夫去找程序的漏洞,然而最终的破解代码可能就2行,不到一分钟就搞定了;然而你也须要做好面对失败的筹备,如果路选错了,有可能你这3天齐全是在节约脑细胞
- 洪荒之力 洪荒之力-即入侵过程中须要借助的各种工具,工欲善其事,必先利其器,工具都是前人智慧的结晶,能用工具解决的,绝不要手动去搞
iOS黑客关键字
iOS的入侵离不开越狱开发,所有的破解、入侵都是建设在越狱的根底上的,如果没有拿到零碎级权限,所有的想法都是空谈了,当然,市面上存在免越狱的破解补丁,然而它的开发过程,也是基于越狱环境的
tweak
在iOS的黑客界,要做破解或越狱开发,就必须理解tweak,它是各种破解补丁的统称,在google上,如果你想搜寻一些越狱开发材料或者开源的破解补丁代码,它是最好的关键字。
iOS的tweak大抵分为两种:
- 第一种是在cydia上公布的,须要越狱能力装置,大部分是deb格局的安装包,iOS在越狱后,会默认装置一个名叫mobilesubstrate的动静库,它的作用是提供一个零碎级的入侵管道,所有的tweak都能够依赖它来进行开发,目前支流的开发工具有theos和iOSOpenDev,前者是采纳makefile的一个编译框架,后者提供了一套xcode我的项目模版,能够间接应用xcode开发可调试,然而这个我的项目曾经进行更新了,对高版本的xcode反对不好,大家酌情抉择(本文中的例子全副采纳theos)
- 第二种是间接打包成ipa安装包,并应用本人的开发证书或者企业证书签名,不需越狱也能够装置,可间接放到本人的网站上,可实现在线装置;对于没有越狱的手机,因为权限的限度,咱们是没有方法写零碎级的tweak的,例如springboard的补丁是没法运行的,这种tweak大多是针对某个app,把指标app进行批改注入解决,再从新签名和公布,有点相似于windows软件的xxx破解版、xxx免注册版
没有越狱的机器因为零碎中没有mobilesubstrate这个库,咱们有二个抉择,第一个是间接把这个库打包进ipa当中,应用它的api实现注入,第二个是间接批改汇编代码;第一个实用于较为简单的破解行为,而且越狱tweak代码能够复用,第二种实用于破解一些if…else…之类的条件语句
Mobilesubstrate
上面的图展现的就是oc届驰名的method swizzling技术,他就是iOS的注入原理,相似于windows的钩子,所以咱们注入也称为hook
Mobilesubstrate为了不便tweak开发,提供了三个重要的模块:
- MobileHooker 就是用来做下面所说的这件事的,它定义一系列的宏和函数,底层调用objc-runtime和fishhook来替换零碎或者指标利用的函数
- MobileLoader 用来在目标程序启动时依据规定把指定目录的第三方的动静库加载进去,第三方的动静库也就是咱们写的破解程序,他的原理上面会简略解说一下
- Safe mode 相似于windows的平安模式,比方咱们写的一些零碎级的hook代码产生crash时,mobilesubstrate会主动进入平安模式,平安模式下,会禁用所有的第三方动静库
app注入原理
下面讲到了mobileloader,他是怎么做到把第三方的lib注入进目标程序的呢?这个咱们要从二进制文件的构造说起,从上面的图来看,Mach-O文件的数据主体可分为三大部分,别离是头部(Header)、加载命令(Load commands)、和最终的数据(Data)。mobileloader会在目标程序启动时,会依据指定的规定查看指定目录是否存在第三方库,如果有,则会通过批改二进制的loadCommands,来把本人注入进所有的app当中,而后加载第三方库。
为了让大家看的更分明,上面我用machoview来关上一个实在的二进制文件给大家看看,能够看出,二进制当中所有援用到的动静库都放在Load commands段当中,所以,通过给这个段减少记录,就能够注入咱们本人写的动静库了
那么问题来了,在这里插入咱们本人的动静库有什么用?咱们本人写的代码没有执行的入口,咱们一样没发干坏事,嗯,祝贺你问到点子上了,咱们还须要一个"main"函数来执行咱们本人的代码,这个"main"函数在oc外面称为构造函数,只有在函数前申明 “attribute((constructor)) static” 即可,有了它咱们就能够施展想象力,进行偷天换日干点好事了:
#import <CaptainHook/CaptainHook.h>CHDeclareClass(AnAppClass);CHMethod(1, void, AnAppClass, say, id, arg1){ NSString* tmp=@"Hello, iOS!"; CHSuper(1, AnAppClass, say, tmp);}__attribute__((constructor)) static void entry(){ NSLog(@"Hello, Ice And Fire!"); CHLoadLateClass(AnAppClass); CHClassHook(1, AnAppClass,say);}
到这里为止,咱们曾经晓得了怎么在目标程序注入本人的代码,那么咱们怎么晓得须要hook哪些办法?怎么找到关键点进行理论的破解呢?上面讲一下常见的app入侵分析方法
iOS逆向分析方法
逆向剖析最罕用的有三种办法:
- 网络分析 通过剖析和篡改接口数据,能够无效的破解通过接口数据来管制客户端行为的app,罕用的抓包工具备Tcpdump, WireShark, Charles等,windows平台有fidller
- 动态剖析 通过砸壳、反汇编、classdump头文件等技术来剖析app行为,通过这种形式能够无效的剖析出app实用的一些第三方库,甚至剖析出app的架构等内容,罕用的工具有dumpdecrypted(砸壳)、hopper disassembler(反汇编)、class_dump(导头文件)
- 动态分析 有静就有动,万物都是相生相克的,动态分析指的是通过剖析app的运行时数据,来定位注入点或者获取要害数据,罕用的工具有cycript(运行时控制台)、 lldb+debugserver(近程断点调试)、logify(追踪)
demo:微信抢红包插件
下面讲了很多原理性的货色,置信大家曾经看的不耐烦了,上面咱们一起动点真格的,咱们从头开始,一步一步的做一个微信的主动抢红包插件,当然,网上可能曾经有相干的开源代码了,然而我这里要讲的是,这些代码是怎么得进去的,我么重点讲一讲剖析过程
工欲善其事,必先利其器
一台越狱的手机,并装有以下软件
- cycript
- dumpdecrypted
- debug server
- openssh
一台苹果电脑,并装有以下软件
- class_dump
- Theos
- Hopper Disassembler v3
- xcode
- insert_dylib
- pp助手
寻找注入点
砸壳
首先咱们要做的就是把微信的壳砸掉,砸壳其实是为了把它的头文件classdump进去,因为从appstore下载的app二进制都是通过加密的,间接进行classdump操作是啥也看不出来的
- 用pp助手把dumpdecrypted.dylib文件copy到微信的documents目录
- ssh到手机的终端,cd到documents目录中,执行上面的命令进行砸壳操作
xxx$ cp /usr/lib/dumpdecrypted.dylib /path/to/app/documentxxx$ DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /path/to/WeChat
- 最初砸壳实现后会在documents目录生成砸了壳后的二进制文件,用pp助手copy进去并class-dump他的头文件备用
执行完这几行命令后,会在微信的documents目录生成一个WeChat.decrypted文件,这就是砸壳后的二进制文件;当然了,这一步不是必须的,咱们能够间接从91或者pp助手下载一个曾经砸过壳的版本
动态分析-cycript
要想实现主动抢红包,咱们必须找到收到红包音讯的handler办法,怎么动手呢?咱们先从界面登程,进入微信的音讯首发窗口:
- ssh进手机的终端,输出ps命令,查找到微信的过程id
ps aux | grep WeChat
- 祭起神器cycript,依据上一步找到的pid注入到微信的过程
cycript -p pidxxx
- 在cycript的终端输出这一串办法,作用就是打印出以后界面的view层级,(cycript还有很多妙用,大家能够上官网看文档,这里不具体介绍)
UIApp.keyWindow.recursiveDescription().toString()
最终的输入如下,内容太多,大家必定看不清楚,不过没关系,这个不是重点,这里只是展现一下打印的后果模式:
咱们能够随机的选取一个节点不要太靠树叶,也不要太靠树根,例如我选的是标红的局部,把这个节点的内存地址copy进去,这个内存地址,就代表了这个节点的view对象,ios开发的老油条们都晓得,通过view的nextResponder办法,能够找出它所属的视图控制器ViewController,所以我么在cycript的控制台中继续输出如下的命令:
看到没有,通过四个nextResponder办法调用,我么找到了以后聊天窗口的ViewController类名,他就是BaseMsgContentViewController,当初咱们放大了指标范畴,上面咱们还须要持续放大范畴,要找到具体的音讯处理函数才行。
动态分析-Logify
要持续放大范畴,就得祭起神器Logify了,它是theos的一个模块,作用就是依据头文件主动生成tweak,生成的tweak会在头文件的所有办法中注入NSLog来打印办法的入参和出参,非常适合追踪办法的调用和数据传递
当初咱们依据此前砸壳后class_dump进去的头文件,找到BaseMsgContentViewController在pc终端执行如下命令:
logify.pl /path/to/BaseMsgContentViewController.h > /out/to/Tweak.xm
输入的tweak文件大略是这个样子的:
这里带百分号的关键字,例如 %hook、%log、%orig 都是mobilesubstrate的MobileHooker模块提供的宏,其实也就是把method swizzling相干的办法封装成了各种宏标记,应用起来更简略,大家想要更深刻理解各种标记,能够google一下logos语言
theos创立tweak
下面咱们用logify生成了一个tweak代码,咱们要把它装置到手机上,首先须要应用theos进行编译,装置了theos之后,在pc终端输出nic.pl:
首先抉择我的项目模版当然是tweak啦,而后是项目名称、作者,前面两个选项要留神:
- 首先是bundle filter,这个须要填你须要注入的指标app的bundle id,MobileLoader模块会依据它来寻找你的tweak的注入指标
- 最初是list id applications to terminate upon installation,这里指定当tweak装置胜利之后,须要kill的过程,咱们要hook微信,这里就填微信的二进制文件名就能够了,为什么要kill? 因为我么的插件是须要在app启动时加载进去的,如果不重启app,插件是不会失效的
最初所有都实现后,在当前目录会生成下列文件:
把下面logify生成的tweak文件笼罩到当前目录,并用文本编辑器关上makefile文件,在文件的结尾减少你的ios设施的ip地址和ssh端口:
最初在pc终端进入我的项目目录,输出 make package install 命令:
期间会让你输出设施的ssh明码,越狱机器的默认ssh明码是alpine,make命令会生成deb安装包,放在debs目录,咱们如果想对外公布本人的插件,能够把生成的安装包上传到cydia即可
装置胜利后再次进入微信的聊天界面,并应用另外一个微信在群里发个一般音讯,连贯xcode关上越狱机器控制台,查看输入,会发现有相似上面的输入:
Jun 7 09:56:13 Administratorde-iPhone WeChat[85972] <Notice>: [1;36m[WxMsgPreview] [m[0;36mTweak.xm:308[m [0;30;46mDEBUG:[m -[<BaseMsgContentViewController: 0x15e0c9a00> addMessageNode:{m_uiMesLocalID=2, m_ui64MesSvrID=0, m_nsFromUsr=ccg*675~9, m_nsToUsr=1037957572@chatroom, m_uiStatus=1, type=1, msgSource="(null)"} layout:1 addMoreMsg:0]
看进去了吧,音讯处理函数是BaseMsgContentViewController的**addMessageNode:layout:addMoreMsg:**办法,大家能够看出,办法的参数内容也打印进去了
动态分析-lldb
到目前为止,我么曾经把范畴放大到了具体的函数,看起来注入点曾经找到了,然而请大家思考一下,如果咱们在这个函数中注入抢红包逻辑,那咱们的tweak会不会有什么致命的缺点?
是的,因为BaseMsgContentViewController这个类是微信群聊天窗口对应的controller,我么必须进入到群的聊天界面,这个类才会创立,如果不进入聊天窗口,咱们的插件就不失效了,而且,即便进入聊天窗口,也只是能自动枪以后群的红包而已,其余群就无能为力了,是不是有点low?
所以为了使咱们的插件显得上流一些,我么还要持续追根溯源,寻找音讯的源头,这里就用到了lldb近程调试,应用lldb打断点的形式,通过调用栈,咱们能够就能够看到当音讯来到时,办法的调用程序,找到最先执行的音讯处理函数。
要在刚刚追踪到的**addMessageNode:layout:addMoreMsg:**办法中打断点,首先咱们得晓得它在运行时的内存地址,那么内存地址怎么来呢?有这么一个公式:
- 内存地址=过程内存基地址+函数在二进制中的偏移量
首先偏移量咱们能够通过反汇编工具hooper来查,在pc上用hooper关上微信的二进制文件(留神,关上时会让你抉择armv7或者arm64,这须要依据你越狱手机的cpu类型来选,肯定要和你的手机统一),hooper的界面十分简洁,左侧有个搜寻框,能够输出函数名,间接找到函数在二进制中的地位
通过左侧的搜寻框搜addMessageNode关键字,找到它的偏移量是0x00000001017d7c6c:
找到了偏移量,还须要过程的基地址,这个地址须要连lldb,所以上面讲一下如何连贯lldb进行近程调试,先ssh进越狱手机的终端,在终端输出如下命令(留神,你的手机必须连xcode调试过才会有这个命令):
debugserver *:19999 -a WeChat
而后在pc端新起一个终端窗口,输出如下命令来连贯手机端进行调试:
lldb -> process connect connect://deviceIP:19999
如果连贯胜利,会进入lldb的控制台,咱们在lldb的控制台输出如下命令来获取微信过程的基地址:
image list -o -f
执行这个命令会打印很多行数据,像上面图中这样,我么要找到微信的二进制文件所在的行,记录它的内存地址0X00000000000E800:
到这里咱们两个地址都找到了,再通过br命令打断点:
br s -a '0X00000000000E800+0x00000001017d7c6c'
打好断点后持续向群外面发消息,咱们会发现过程被断掉了,这时输出bt指令,就能够看到以后的调用栈,就像下图这样:
剖析堆栈的时候,重点找出模块时WeChat的项,这些都是微信模块的办法调用,有了堆栈,咱们须要依据堆栈的内存地址找出它的具体函数名,思路还是先依据下面讲到的公式来计算出栈地址在二进制中的偏移量,而后用hooper找到偏移量对应的函数名
- 函数在二进制中的偏移量=内存地址 - 过程内存基地址
例如依据箭头所指的内存地址和刚刚失去的过程基地址,计算偏移量:
0x0000000101ad02f4 – 0x00000000000e8000 = 1019E82F4
而后在hooper中搜寻这个地址,失去后果如下:
最终把所有的栈都进行还原,得出调用栈是这个样子的:
-[CMessageMgr MainThreadNotifyToExt:]:–> -[BaseMsgContentLogicController OnAddMsg:MsgWrap:]:——>-[RoomContentLogicController DidAddMsg:]———->-[BaseMsgContentLogicController DidAddMsg:]—————->-[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]:
CMessageMgr这个类浮出水面了,是时候施展黑客的嗅觉了,依据办法名咱们能判断出MainThreadNotifyToExt:这个办法仅仅是用来发送告诉的,如果hook这个办法,咱们是拿不到音讯内容的
因为这里可能是一个异步调用,用断点的形式,可能曾经打印不进去栈信息了,所以还得应用logify来持续追踪CMessageMgr这个类,讲过的内容我就不反复了,间接失去最终的音讯处理函数:
-(void)AsyncOnAddMsg:(id)message MsgWrap:(CMessageWrap* )msgWrap
实现“抢”的动作
上一节咱们曾经找到了hook的关键点,那么该如何去实现抢的动作?同样咱们须要联合动态分析和动态剖析,首先失去红包音讯体的数据特色,而后再剖析解决音讯的关键点
数据包剖析
首先咱们的代码须要分辨哪些才是红包音讯,办法很简略,用logify追踪BaseMsgContentViewController,而后向微信群发一个红包,察看手机日志输入,咱们能够看出音讯的数据结构中有个type字段,值是49,这个type应该就是标记音讯类型的,如果不确定,能够再发个图片或者文本之类的音讯,这个值是不同的:
Administratorde-iPhone WeChat[47410] <Notice>: [1;36m[WxMsgPreview] [m[0;36mTweak.xm:308[m [0;30;46mDEBUG:[m -[<BaseMsgContentViewController: 0x15e0c9a00> addMessageNode:{m_uiMesLocalID=16, m_ui64MesSvrID=1452438635530425509, m_nsFromUsr=1037957572@chatroom, m_nsToUsr=ccg*675~9, m_uiStatus=4, type=49, msgSource="<msgsource> <silence>0</silence> <membercount>3</membercount> </msgsource> "} layout:1 addMoreMsg:0]
当初咱们能分辨音讯类型了,重点来了,怎么实现抢这个事呢,可能聪明人曾经猜到了,从ui动手,先找到微信自身的抢红包函数,咱们本人来给它结构参数并调用他不就行了?
把红包点开后,用cycript打印出以后view的档次,就像上面这个,一眼就能够看到重点,WCRedEnvelopesReceiveHomeView就是开红包弹框的类名
晓得类名后,用cycript追踪它,点击开红包,在日志中找到了下图中的内容,从名字来看,这是一个事件处理函数,咱们当初要做的,就是把他还原成oc代码,真正实现抢红包性能
Administratorde-iPhone WeChat[91173] <Notice>: [1;36m[WxMsgPreview] [m[0;36mTweak.xm:8[m [0;30;46mDEBUG:[m -[<WCRedEnvelopesReceiveHomeView: 0x13cdda8c0> OnOpenRedEnvelopes]
动态分析法
怎么把他还原成oc代码,真正实现抢红包性能呢?还得借助一点点汇编技能,只是一点点而已,因为当初的反汇编工具曾经很弱小了,咱们不须要挨个去看寄存器了
在pc上用hooper关上微信的二进制文件,搜寻OnOpenRedEnvelopes,查看汇编代码,留神在图片中最初一行调用了一个WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes函数
持续搜寻WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes这个办法,找到它的汇编代码
- 首先他不晓得从哪里获取了一个payinfoitem
- 而后又获取了payinfo的m_c2cNativeUrl属性
- 而后调用substringfromindex吧navtiveurl的前缀截断,并调用bizutil的一个办法把url参数转换成了一个字典
最终反解出的代码如下,是不是很简略?
NSString *nativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];nativeUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]];NSDictionary *nativeUrlDict = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl separator:@"&"];
持续往下看, 在这里后面三行创立了一个mutable dictionary:
- 紧接着上面三个框框处都是调用了setobject:forkey:向外面填货色,那填的货色是啥呢?
- 其实这里曾经能够看的很分明了,第一个key是msgtype,值是字符串1,第二个sendid,值是调用了一个objectforkey从另一个字典中取出来的,很显然,另一个字典就是下面从url解析失去的,前面的channelid也是同样的情理
最终失去的代码如下:
NSMutableDictionary *args = [[%c(NSMutableDictionary) alloc] init];[args setObject:nativeUrlDict[@"msgtype"] forKey:@"msgType"];[args setObject:nativeUrlDict[@"sendid"] forKey:@"sendId"];[args setObject:nativeUrlDict[@"channelid"] forKey:@"channelId"];
持续往下看从箭头所指的几处,咱们能够看见,它的代码是这样的,共分为四步
- 第一个箭头调用了mmservicecenter的defaultcenter办法来获取mmservicecenter实例
- 第二个箭头调用了CContactMgr的class办法
- 第三个箭头调用了第一步获取的mmservicecenter实例的getservice办法,而这个办法是把第二步失去的class作为参数
- 第四个箭头很明确了吧,第三步失去了CContactMgr实例,这里就是调用CContactMgr实例的getselfcontact办法获取本人的账户材料
最终还原的到的代码如下:
CContactMgr *contactManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]];CContact *selfContact = [contactManager getSelfContact];
持续往下看,这里应用刚刚失去的selfcontact来获取displayname和headimgurl,并把它们设置到刚刚的字典外面了,key别离是nickname和headimg
最终的代码:
[args setObject:[selfContact getContactDisplayName] forKey:@"nickName"];[args setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];
接着看,接下来这两段就比拟蛋疼了,齐全是从内存地址外面取的值,我也不晓得他从哪里来,怎么办呢?有没有不懂汇编就能搞定它的捷径呢,答案是有!
- 对于第一个,我能够通过它的key猜出来,还记得最开始的时候咱们取过payinfo的一个nativeurl属性吧,咱们权且把他传进去
- 对于第二个,咱们能够猜想sessionUserName大略是会话名称,也就是群名称的意思,从哪里取这个值呢?咱们先把也设置成伪代码
最终的后果如下:
[args setObject:nativeUrl forKey:@"nativeUrl"];[args setObject:xxx forKey:@"sessionUserName"];
持续往下看,接下来这一段还是用mmservicecenter来获取WCRedLogicMgr对象,而后调用WCRedLogicMgr的open办法来拆红包,能够设想open办法的参数就是下面咱们辛苦组装的字典
代码如下:
[[[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]] OpenRedEnvelopesRequest:args];
领红包逻辑
到这里,咱们再总结一下咱们下面剖析的过程…
- 失去m_oWCPayInfoItem属性
- 解析m_oWCPayInfoItem的m_c2cNativeUrl属性
- 失去selfcontact
- 组装相干参数
- 调用OpenRedEnvelopesRequest:支付红包
最终的抢红包代码合并起来如下:
#import "WxMsgPreview.h"%hook CMessageMgr-(void)AsyncOnAddMsg:(id)message MsgWrap:(CMessageWrap* )msgWrap { %log; %orig; if(msgWrap.m_uiMessageType == 49){ CContactMgr *contactManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]]; CContact *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 setObject:nativeUrlDict[@"msgtype"] forKey:@"msgType"]; [args setObject:nativeUrlDict[@"sendid"] forKey:@"sendId"]; [args setObject:nativeUrlDict[@"channelid"] forKey:@"channelId"]; [args setObject:[selfContact getContactDisplayName] forKey:@"nickName"]; [args setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"]; [args setObject:nativeUrl forKey:@"nativeUrl"]; [args setObject:msgWrap.m_nsFromUsr forKey:@"sessionUserName"]; [[[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]] OpenRedEnvelopesRequest:args]; } }}%end
方才说了,有两个疑难点没有解决:
- 第一:咱们不晓得payinfo是哪里来的,
- 第二:sessionusername咱们也不晓得是哪里来的
这时候咱们能够从咱们注入点的参数动手,首先用logify打印出addmsg办法的参数信息,会发现,它的第二个参数刚好有一个payinfo的属性,这样第一个问题迎刃而解了第二个咱们曾经猜测到它代表群名称,所以咱们从批改几次群名称,而后再察看logify打印出的参数值的变动,就能够确认出从哪里取了
通过一番折腾,得出了抢红包的外围代码,再联合下面章节所讲的theos制作tweak包的办法,打包并装置到手机,发个红包试试,是不是秒抢?
免越狱插件
查看依赖项
如果设施没有越狱,是没有mobilesubstrate等环境的,而且一些系统目录是没有读写权限的,这时我么只能从指标app的二进制文件动手,通过手动批改load commands来加载本人的dylib,那么下面咱们的插件又是应用theos基于mobilesubstrate编译的,有没有方法确定咱们的dylib有没有依赖其余的库呢?
应用osx自带的otool工具即可,能够看出,咱们的lib是依赖于substrate库的,其余的都是零碎库,所以咱们从越狱设施中把cydiasubstrate文件copy进去重命名为libsunstrate.dylib,和咱们的dylib一起放入wechat.app目录中
最初应用install_name_tool命令批改动静库的门路把它指向app二进制文件的同级目录
制作安装包
解决了依赖问题,而后要把咱们的库注入到二进制weixin的二进制文件,这一步应用开源的insert_dylib即可 (@executable_path是一个环境变量,指的是二进制文件所在的门路)
insert_dylib命令格局: ./insert_dylib 动静库门路 指标二进制文件
//注入动静库./insert_dylib [@executable_path](/user/name/executable_path)/wxmsgpreview.dylib WeChat//打包成ipaxcrun -sdk iphoneos PackageApplication -v WeChat.app -o ~/WeChat.ipa
最初应用用企业证书或者开发证书签名对ipa从新签名,就能够放到本人的渠道进行公布了!
结语
通过综合使用各种工具,进行动态和动态分析,咱们通过实战破解了微信的抢红包逻辑,明确了入侵罕用的工具,下面的抢红包代码还有很多改良之处,比方没有判断红包的发送者是不是本人、也没有判断红包外面的文字是不是抢错三倍,有趣味的童鞋能够尝试优化一下!