恢复符号表

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

解决:

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

逆向签名(八)

签名原理:

解析: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安装到手机上)

查看本电脑所以证书 (也就是~/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/所以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了


Xcode重签名

  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到手机上就行了

脚本自动化重签名

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

逆向密码(七)

比如签名的CertificateSigningRequest.certSigningRequest文件就是base64对二进制编码

ValueCharValueCharValueCharValueChar
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/
source ASCII (if <128)Man
source octets77 (0x4d)97 (0x61)110 (0x6e)
Bit pattern010011010110000101101110
Index1922546
Base64-encodedTWFu
encoded octets84 (0x54)87 (0x57)70 (0x46)117 (0x75)
Text contentM
ASCII77 (0x4d)0 (0x00)0 (0x00)
Bit pattern010011010000000000000000
Index191600
Base64-encodedTQ==
Text contentMa
ASCII77 (0x4d)97 (0x61)0 (0x00)
Bit pattern010011010110000100000000
Index192240
Base64-encodedTWE=

把要编码的字母到对应assci二进制码 每6个二进制取一个值那对应的符号(其他的=补全)

base64大多是对加密后的数据进行编码

base64编码:

base64解码:

密码:

  • 非对称 (RSA,公私钥..)(由于简单的数据运算,效率比较低,主要用于加密核心的小数据)
  • 对称
  • HASH 哈希(散列)函数(不可逆,不能用加密解密)

对称密码:

  • 分组密码 (Feistel,DES,AES)
  • 序列密码 (线性反馈寄存器,内容扰乱系统,A5/1算法,RC5算法)
  • 密码模式 (电子密码本ECB,密码块链接CBC,填充密码块链接PCBC,密文反馈CFB,计数器模式CTR)

哈希密码:

  • 用途:文件校验,数字签名
  • 算法:MD4,MD5,SHA1

Openssl(公开加密算法库):

生成私钥:

从上面private.pem私钥中生成公钥 (公钥是根据私钥算出)

查看明文的private内容


MD5

一个二进制只有一个Hash值(可用于判断一个数据有没有被修改过)

 

 

–未完.待更新

静态语言、动态语言区别?

静态语言:

比如c语言,值声明了方法不实现是报错的,如果现实了比如下面简单代码,在编译时期就已经确定了run代码段的内存地址。比如int age=27;至于在要age名字有必要吗?

动态语言:

OC只声明不现实不报错,它是根据运行时macho上查找 IMP在Symbok Table 符号表查找(sel > IMP(地址)‘对应查看)