邀请码的优势

期待已久的产品要增加邀请功能,为啥优先选择了a?

邀请方式:
a) 通过链接和图片二维码(也是链接)
b)通过邀请码


问题:
1. 你是个新用户已经下载了app (在app store无意搜到的,刚注册和没注册情况)? 你怎么做能拿到10元钱?要通过别人链接邀请才有?
2. 如果一个人有多个账号使用一个邀请链接都可以使用?(还是只要是手机绑定用户并发了视频都可以?)


1.不要给邀请人增加负担 ,因为在链接和图片发出去后没有有效期限制,没有个数限制,别人很难在去发… 因为发了以后自己的邀请概率非常小 (邀请收益难)

2.正因为有效期不收限制和没个数限制 ,心里上并没太大价值(比如脉脉也是这种,有很多都是这种 并不算成功 只是一个邀请功能,达不到简单操作去疯狂传播)(应狼多肉少)(增加价值)

3.缺少用户间的互动,(比如在要找邀请码 在百度,或群里问下,或者找别人要个,达到互动又增加了量)(应增加互动)

4.心里作用,比如通过淘宝客的链接去购买就能给双方给来好处,有一部分人会主动的恢复链接(删除链接邀请人信息) 宁愿不要好处(不要透露过多邀请人信息,最好不要透露) (心里作用)


建议:
1)先用b邀请码 (像网易星球和度宇宙这样,有效期和个数限制),比如8个(8*10=80元)用完在去用a方式
2)a邀请方式 (3*n = 3n元)

修改微信运动步数

如果你用过MonkeyDev(github搜下),和logos(不熟悉请看下面文章)这里就非常容易了。

利用class-dump (不熟悉请看下面文章)把微信的头文件全部导出找到WCDeviceStepObject文件,里面有个- (unsigned int)m7StepCount方法,hook住

逆向class-dump(一)

Logos

注意这里是用的MonkeyDev重签名安装,logos按照上面几行写就行

手机越狱

问题:在通过xcode的Windos/Devices and Smilators/安装ipa 安装不上(越狱)?

解:要通过Cydia安装AppSync  Unified就可以了 (绕过苹果检查机制)

 

Cycript

ssh连接,在手机端的公钥发给mac端,mac端拿到公钥加密要输入的密码,给手机端,手机端在进行验证(并不安全,公钥可拦截串改,最好在mac端验证下手机端的公钥是否有效)

删除ssh rsa对应IP公钥


免密码登入原理:

  1. 客户端将自己公钥发给远程服务端
  2. 服务端利用公钥加密生成一段字符串给客户端
  3. 客户端用私钥解密字符串

 

恢复符号表

有时在断点看堆栈信息,看不到具体的函数名字

解决:

https://github.com/tobefuturer/restore-symbol

进入restore-symbol 直接make restore-symbol或者运行获取restore-symbol可执行文件

1.  然后把第三方的可执行文件也放进来,直接make restore-symbol,注意:第三方可执行文件必须是单一架构,可以分解(如分解成arm64)

2.恢复单一架构符号表

这里是利用MonkeyDev来调试的


恢复block符号表

https://github.com/macRong/ida_search_block

1.先用ida打开可执行文件选择导入ida_search_block (file/script file)会生成一个block_symbol.json文件(在ida当前目录下)

2.把block_symbol.json文件放到restore-symbol文件夹下 执行得到一个可执行文件去替换就好

Logos

logos(CydiaSubstruct框架):http://iphonedevwiki.net/index.php/Logos

非越狱机上主要是通过动态库的注入来修改程序。在越狱机上是把CydiaSubstruct框架导入到手机上

%hook (%end结束)

开始hook


%group、%ctor、%init

%group组,%ctor构造函数, %init初始化

  • 对于没有写group的,它会有个隐士的”_ungrouped”group
  • 定义多少个group必须在构造函数中初始化几个,初始化是后面覆盖前面的

%new、%c

就是新增一个方法。%c相当于objc_getClass或NSClassFromString

注意:

在调用类方法是用[%c(Myclass Leifunc]; 如果直接用[Myclass Leifunc];  会报错

  •  self.view提示没定义,把class-dump的头文件复制到上面或者单独写到HookHeader文件中
  • + (void)myClassMethod要复制到上面或者单独写到HookHeader文件中

%log


%orig

调用之前的方法(调用自己)


MSHookIvar: 拿到对象的成员变量 (如果不想引用的话),记得<xx*> 不然可能变错


Hook第三方类多个方法?

通过Monkey/thoes/logify, 在~/.bash_profile配置下PATH路径为/opt/theos/bin/

logify通过命令执行

然后编译下处自动生成一个xxxxa.mm文件,把xxxxa.mm,但是错误就一堆了

解决:

  1. 通过class-dump把所有的头文件导入到monkey中 然后在引用的地方引用xxxxa.mm
  2. 通过Monkey/Config/

防护App

以下是简单基本防护:

1.先反想怎么攻击别人App?

重签名,静态,动态注入自己代码,Hook函数…


所以下面主要讲怎么做基本防护,不让别人Hook你的app

怎么注入看这http://shengshui.com/?p=3406

这是你要注入的(如果那个app没做基本防护的话可以直接成功 修改执行流程)

怎么才能不让别人hook自己app?

把自己程序的hook全写到专门的静态库中,这样可以优先加载你写的防护代码(不然防护无效),比如下面代码,外部有人调method_exchangeImplementations就直接退出

但是用MonkeyDev logos还是可以Hook的

底层调用objc的runtimefishhook来替换系统或者目标应用的函数,其实它能hook住是调用了method_setImplementationmethod_getImplementation 所以防护的代码再加上这2个就可以,如下

问题:

如何才能防护住? 删除他的防护? 在它防护之前先加载?修改MachO文件?

HOOK原理

Hook就是改变程序执行流程

1.常见几种Hook方式

 1.Method Swizzle

利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关系,达到OC方法调用流程改变的目的。主要用于OC方法

2.fishhook

Facebook提供的一个动态修改链接mach-O文件的工具。利用MachO文件加载原理,通过修改懒加载和非懒加载两个表的指针达到C函数HOOK的目的。(自定义不行).  C静态是怎么修改的?请看下面问题

3.Cydia Substrate

Cydia Substrate 原名为 Mobile Substrate ,它的主要作用是针对OC方法、C函数以及函数地址进行HOOK操作。Android,iOS都能用。官方地址:http://www.cydiasubstrate.com/

Cydia Substrate主要由3部分组成:

  • MobileHooker

    MobileHooker顾名思义用于HOOK。它定义一系列的宏和函数,底层调用objc的runtimefishhook来替换系统或者目标应用的函数.
    其中有两个函数:

    • MSHookMessageEx 主要作用于Objective-C方法

    • MSHookFunction 主要作用于C和C++函数

    Logos语法的%hook 就是对此函数做了一层封装

  • MobileLoader

    MobileLoader用于加载第三方dylib在运行的应用程序中。启动时MobileLoader会根据规则把指定目录的第三方的动态库加载进去,第三方的动态库也就是我们写的破解程序.

  • safe mode

    因为APP程序质量参差不齐崩溃再所难免,破解程序本质是dylib,寄生在别人进程里。 系统进程一旦出错,可能导致整个进程崩溃,崩溃后就会造成iOS瘫痪。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基于CydiaSubstratede 的三方dylib都会被禁用,便于查错与修复。


2.fishHook原理

fishhook简单例子:

但是这个只能是系统自己的函数可以,不能hook自定义的函数(因为符号表中没有自定义的函数)

1.MachO是通过DYLD动态加载进的 (可以lldb: image list 看下 先加载MachO在加载一些它需要的库)

2.MachO文件每次加载时随机地址(ARLR :http://shengshui.com/?p=3268

3.NSLog并没有在你程序的Macho中,而是在系统的动态库中,当Macho加载进内存,它和NSLog动态库是地址相对改变的

4.PIC位置代码独立

  • 如果程序调用系统库函数时,首先在MachO中_DATA段中建立一个指针(符号)(也就是0x00000),指向外部函数 (通过DYLD动态加载)
  • DYLD会动态绑定,将MachO中的_DATA段的指针指向外部函数

  1. 在MachO中找到Lazy Sysbol Pointers符号表
  2. 再找Dynamic Symbol Table/Indirect Symbols (它和Lazy Sysbol Pointers符号表一一对应)找到Data拿到它的Index去Symbol Table/Symbols表然后拿到data
  3. 拿到data去String Table找(开始地址+编译地址)

也就是它符号表指向外部函数指针改变为指向内容函数指针


问题:

1.C是静态语言但是finshhook是怎么替换的函数?

在MachO加载内存之前它根本不知道系统函数地址,自己编写的程序在build一样确定了,但是外部并不能确定

通过PIC位置代码独。它是通过符号表来查找,通过dyld动态绑定,finshhook就是重新绑定符号表(查看下面验证)

它是怎么通过字符串找到系统函数地址的?

系统共享缓存库中函数固定地址? 不对,它每次加载其实也是改变的

查看上面图通过MachO的Lazy Sysbol Pointers符号表找到 Dynamic Symbol Table/Indirect Symbols (它们一一对应)

  1. 在MachO中找到Lazy Sysbol Pointers符号表
  2. 再找Dynamic Symbol Table/Indirect Symbols (它和Lazy Sysbol Pointers符号表一一对应)找到Data拿到它的Index去Symbol Table/Symbols表然后拿到data
  3. 拿到data去String Table找(开始地址+编译地址)
  • 如果程序调用系统库函数时,首先在MachO中_DATA段中建立一个指针(也就是0x00000),指向外部函数 (通过DYLD动态加载)
  • DYLD会动态绑定,将MachO中的_DATA段的指针指向外部函数

验证:

用上面例子先断点rebind_symbols处查看MachO文件

通过地址拿到反汇编代码

关于签名,是对每一个dylib单独签名加载进MachO,单个验证


怎么反Hook

防护App

逆向代码注入三方app(九)

如何改变第三方app代码

  1. 动态库(FrameWork,Dylib)(工程和动态库有关联,动态库加载进app中)
  2. 静态注入
  3. 修改MachO文件的Load Commans

比如一些简单的代码注入,hook第三方app上的函数去改成自己的

framework注入

  1. 在xcode TARGETS增加一个framework
  2. 点击项目TARGETS/Build Phases 添加New Copy Files Phases (Destination选择Frameworks, 点击+进刚才新建的framework,然后勾选Copy only when installing(编译,主要是把刚才新建的framework加载到Products/app 的Frameworks,打包进app里面,可以用image list查看)) (不用勾选Copy only when installing)
  3. 在刚才新建的Framework下新加类文件, 在+load方法中加进你的代码
  4. 上面的frame只是加载进.app/FrameWorks下,但是在.app的macho并没有把rongframework加载进macho中
  5. 然后可以通过yololib把rongframework的macho加载到app的macho中  (链接:https://pan.baidu.com/s/1JWQzPvi7ufMb5sKwNW2w2Q 密码:y6wg)(把yololib文件放在usr/local/bin 中就行,可以直接调用)
  6. yololib用法(后面的路径是.app/Frameworks下载rongframework)(也就是加载二进制 规则修改)(注意:Wechat修改的不是编译后的Products的Wechat 是要被替换的ipa下的Wechat执行yololib 然后在打包成ipa,然后在替换)然后看下wechat包含了rongframework,然后运行就执行你的代码了(这里主要看上一遍签名文章有写)(把Payload打包成ipa  zip -ry WeChat.ipa Payload)
  7. 打包成新的ipa放在App下就行了 (这里主要看上一遍签名文章有写 App这些是有脚本在执行)

 

注意:

1. 第6步最容易犯错,在找到App下的WeChatMacho文件执行(找到rongframework的macho文件对.app/相对路径

yololib 就是告诉WeChat要加载Frameworks/RongFramework.framework/RongFramework的macho文件,注意路径一定不要错,否则代码注入失败

2.然后勾选Copy only when installing作用?

就是把framework打包进app中,可以展示包文件在FrameWorks/下有你的framework,(这一步并没有在可执行文件中包含 第6步做就行)


Dylib注入

  1. 在xcode TARGETS增加一个Libary(mac)
  2. 点击项目TARGETS/Build Phases 添加New Copy Files Phases (Destination选择Frameworks, 点击+进刚才新建的Dylib,然后勾选Copy only when installing(编译,主要是把刚才新建的Dylib加载到Products/app 的Dylib,打包进app里面,可以用image list查看))和上面framework那步一样的
  3. 然后编译可以会出错dylib路径不对(dylib路径没有在Debug-iphoneos,在Debug路径下,把Debug下copy到Debug-iphoneos下就行了)(target/Build Setting搜Per-configuration Intermediate Build Files Path), 注意:在target下的Debug路径复制后copy到2个地方一个是target和dylib路径下,但是不同的target下同一变量名路径不一样,所以在dylib强制改下路径,这样就是把Debug下的lib放到Debug-iphoneos下


  4. 出现这个错误是dylib是x86,所以在TARGETS/RongHook/ 改下架构。看最下面

注意:很容易出现错误,检查app/frameworks是否包含了dylib,然后在检查macho是否加载进dylib


问题:

1. 自定义动态库打包到macho中,需要注意点

出现这个错误是dylib是x86,所以在TARGETS/RongHook/ 改下架构如图

但是这里改这么多太麻烦。有简单办法就是

  1. 直接改Base SDk位iOS的,它会自动把上面的一些mac改为iOS
  2. 然后把Signing选iphone 证书就好

app签名原理

解析:xcode怎么运行到手机上的?(苹果主要保证app安装时它认证的,并且是他有安装到指定的设备上,在app线上是没有这些描述文件)

第一步: mac电脑上要生成一对公钥M和私钥M (公钥是从私钥生成),CSR文件(包含公钥M,可以直接cat CSR文件看下面)(CSR文件包含信息看下面)中(也就是 钥匙串访问/证书助理/从证书颁发机构请求证书.. (CertificateSigningRequest.certSigningRequest))发给苹果服务器申请证书

通过 命令获得

CSR信息如下

第二步: 苹果用私钥S加密公钥M去生成证书一个证书和一个Provision profile文件,下载到本地,然后mac上会把私钥M和证书关联到一起(验证是否公私钥对应)也就是钥匙串中情况看图

比如如果别的mac也要编译app安装,要把私钥打成p12给他。其中证书包含mac上的公钥M和公钥M的hash值(防止篡改)

另外还有个Provision profile文件是注册的devices和cers等看图  ,可以通过这个路径找到(包含多个系统会进行匹配获取)

可以通过命令得到描述文件的信息(是xml文件可以在xcode的plist查看,也就是下面图的内容):

第三步: 通过私钥M进行app加密签名和第2步的证书和Provision profile文件打包到app中

问题:怎么验证Provision profile文件加入到app中?

解压app后得到其中有个embedded.mobileprovision就是第2步下载的描述文件,可以对比看下

第四步:  取出第3步的证书通过公钥A(苹果内置)进行解密得到公钥M(验证Hash值是否合法),然后通过公钥M解密app签名判断app是否被修改过,在手机上2次签名认证

问题:怎么签名证书在app中?

看上面解压app后的图 其中有个_CodeSignature/CodeResources这个就是,不止是app包中有,在macho可执行文件中也包含看图(通过machoView查看)

快速重签名app安装到手机上

1.手动重签名 (重签app安装到手机上)(验证通过✅)

注意这里ipa是已经砸壳后的ipa

查看本电脑所以证书 (也就是~/Library/MobileDevice/Provisioning Profiles 路径下的证书)

查看app是否签名?

Authority=(unavailable) 没有签名信息 越狱应用,被砸过壳。如果有签名信息:

  • Authority=Apple iPhone OS Application Signing
  • Authority=Apple iPhone Certification Authority

查看app是否加密?

cryptid 0 没有加密的(这个是越狱应用),非越狱cryptid 1


真正步骤开始

  1. 解压app后其中这些Plugins插件个人账户没办法重签名,可以直接删除这个Plugins文件夹
  2. 其中有Watch也没办法重签名 直接删除
  3. 对Framework要重签名

4. 给可执行文件执行权限  (chmod +x WeChat)

5.把xcode中的Demo编译的app包的embedded.mobileprovision描述文件到Wechat的app包中

6.把xcode中Demo的BundleID赋值到Wechat的info.plist文件的名字中(可以使用通配符com.shengshui.* (后面名字随便起))

7.查看下WeChat中的描述文件(刚才copy的那个)

找到权限文件Entitlements把<dict> </dict>copy生成entitlements.plist(可以用xcode生成)

8.把7步生成的entitlements.plist放在WeChat.app同级目录下

9.签名整个app

10.把app搞到一个单独文件夹中打包成ipa

11.在Xcode中Widow/Devicesa and Simulators/Installed apps 点击+ 把ipa安装上就ok了 (注意中间细节如果出错一步可能就不行了)


2.Xcode重签名(更方便调试)(重签app安装到手机上)(验证通过✅)

  1. 进入Xcode编译的Demo.app,找到越狱wechat.app 替换Demo.app (名字要一样 用Demo.app)
  2. Demo.app(上面被wechat替换的)显示包内容 找到info.plist文件把bundleID改为Demo的bundleID
  3. 对Framework/所以framework要重签名
  4. 给可执行文件执行权限  (chmod +x WeChat)
  5. 删除Plugins文件夹
  6. Watch也没办法重签名 直接删除
  7. 然后执行运行Demo到手机上就行了

3.脚本自动重签名app(重签app安装到手机上)(验证通过✅)

  1. xcode demo能运行手机上
  2. 把下面脚本copy到 TRAGETS/Bunild Phases 点击+新建一个Shell script ,然后copy里面
  3. 先编译下,把ipa放工程下的App文件夹中就行
  4. 直接运行到手机上了

4.MonkeyDev

了解上面过程后也可以使用第三方的签名 很简单

https://github.com/AloneMonkey/MonkeyDev