一.常识
- 查看设备输出信息:xcode - window - devices and simulators - logs
- 修改文件权限 : chmod +x /usr/bin
- SSL:secure sockets layer,对数据在传输层进行加密.
- SSH:secure shell(安全外壳协议),远程登录使用,防止中间人攻击.
- SSH依赖了SSL.
- 在同一架构中,每一条汇编指令都有与之对应的唯一的机器指令,所以汇编语言和机器语言可以互相推到.
- mach-o文件由三部分组成
1.header :文件类型 目标架构类型
2.Load commands : 描述文件在虚拟内存中的逻辑结构、布局
3.Raw Segment Data : 正儿八经的数据(Load commands描述的数据) - .o .a .dyld .dylib .dsym(崩溃日志相关) .framework等(共11种) 都是mach-o文件(可执行文件),但是dyld本身可以加载其他三种mach-o文件(MH-execute,MH-dylib,MH-bundle)
- file 文件 : 可以查看某一个文件的具体信息
- otool : 查看mach-o文件具体信息
- abort();直接退出应用
二.cycript(动态调试app)
- 输入 进入环境,control+d退出环境
- cycript -p neteasemusic 直接进入调试环境
- ps -A | grep "" 查看进程id
- 将a.cy添加到路径
Device/usr/lib/cycript0.9
,然后@import a.cy即可使用a.cy内部函数 - UIApp 查看[UIApplication sharedApplication]
- ObjectiveC.classes 查看这个APP所有成员变量,使用哪个类
- *UIApp 查看某一个对象的成员变量
- choose(UIViewController) 查看所有的UIViewController相关类
- scp -P 10010 ~/Desktop/1.cy root@localhost:/usr/lib/cycript0.9/1.cy 拷贝本地文件到远程服务器
- xcode/products里面的app格式文件是我们编译好的程序,例如 we.app
- we.app 里面有图片、视频等资源和Mach-O(可执行文件,二进制文件)文件.
- 把we.app放到自己新建的Payload文件夹,经过压缩改zip为ipa就是ipa文件了.
三.class-dump(导出app的头文件)
钉钉虚拟打卡
- 使用class-dump可以导出所有的.h文件
- 下载钉钉ipa(从pp助手下载越狱版本的,要不然导出.h文件会失败)
- class-dump -H DingTalkBreakJail -o ~/Desktop/classDump_DingTalk
四.Hopper Disassembler(反编译app)
- 将mach-o文件反汇编为oc或swift伪代码
- 将mach-o(最好也是越狱版)文件直接拖入Hopper中
五.加壳&脱壳
- 判断是否加壳:
1.使用mach-o工具查看load-command/LC-Encryption_INFO/cryptid的值,0代表未加密,非0代表加密.
2.使用otool命令,otool -l XX | grep crypt - 脱壳:将未加密的可执行文件还原出来(对应加壳)
1.使用Clutch,将Cluth放到usr/bin,Clutch -i查看,Clutch -d 5(数字)进行脱壳
chmod +x /usr/bin/Clutch : 没有权限时使用该命令
2.使用dumpDecrypted
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/F2A26AA8-0737-4C7D-AB0B-9CAE638E8E82/DingTalk.app/DingTalk
六.theos(注入自己的代码)
- theos用来注入自己的代码
- 配置环境变量(用户级别): ~/.bash_profile
- 运行nic.pl
- 记得配置Makefile
export THEOS_DEVICE_IP = 127.0.0.1
export THEOS_DEVICE_PORT = 10010 - make clean && make package && make install
- make package dubug=0 : 发布realease版本
- 想要加入自己的图片等资源,需要在tewak文件夹里新建layout(相当于ifunbox的Device)文件夹
- theos_tweak原理:生成文件(dylib)动态库和plist,然后使用cydia打包成deb,修改内存中的内容.
- 删除自己的tweak库:
1.通过cydia卸载
2.删除Device/Library/MobileSubstrate/DynamicLibraries里面的dylib. -
logos语法
1.%c() 等同于NSClassFromString:()
2.%ctor{}加载自己写的动态库的时候调用
3.%dtor{}应用关闭时调用
4.%new 生成新的方法, 然后在@interface lyk @end里面生命一下,就可以用了.
5.%log 打印方法的信息
6.logify.pl
七.SpringBoard
- 系统的桌面
八.ldid(权限问题)
- 比如说,访问其他的app沙河
- 查看mach-o的权限: idld -e 文件 > 文件.entitlements
- 可以把springBoard的权限放到自己写的 mach-o
九.debugServer(调试app的工具)
- 使用ldid给debugServer增加权限,然后放到device/usr/bin目录下.
- debugserver *:10011 -a WeChat 附加debugserver到WeChat上.
- process connect connect://localhost:10011 lldb连接到debugserver
十一.ALSR(防止别人访问你的函数、变量地址)
- ALSR : Address Space Lyaout Randomization -->地址空间布局随机化
- __PAGEZERO,占据0x 0000 0000个字段,在虚拟内存中.(非ARM64,占据0x4000)
- 函数放在__text段里面
- 全局变量放在__data段里面
- 函数和全局变量在编译完成后,内存地址就已经固定死了.(参考catagory实现)
局部变量是在函数栈里面.
通过alloc、new等创建的变量是在堆空间. - image list -o -f : 找到ALSR的偏移量,计算函数真实地址.
只有把mach-o文件载入内存的时候,ALSR才管用.所以使用ida应该减去偏移量
十二.汇编
寄存器
- 通用寄存器
64位架构,有29个通用寄存器. x0 - x28
32位架构,有29个通用寄存器. w0- w28(x0-x28的低32位) - pc寄存器
记录cpu将要执行的指令地址 - lr寄存器 x30
记录bl执行完,继续执行的地址
void main{
void test();
void next();
}
当进入test函数时,lr会记录next()函数的地址,这样在test() return的时候就可以找到 将要调用的函数了.
- ret 指令的本质 : 将lr的值 赋值给 pc
底层小知识
- sizeof() : 不是函数....
- cup结构
1.寄存器
2.运算器
3.控制器 - 三大总线:
地址总线:表明访问的内存地址
8086的地址总线宽度为20,每根线都有0和1两种状态,所以它的寻址能力为2的20次方=1M,也就是说8086能使用的内存最大为1M-----windowsXP的内存最大为4G
控制总线:表明是读还是写
8086cpu的数据总线为8,每次传2的8次方,也就是1个字节
数据总线:表明 读或写的 数据
8086的数据总线宽度为16,每8bit为1个字节,所以8086的内存地址对应2个字节
我们平时做说的64位操作系统,实际上就是说数据总线为64,就是说每个内存地址能存8个字节
- 8086地址总线宽度为20,数据总线为16,那么16位不能存储20位的数据,所以需要用段地址和偏移地址两个16位来合成20位
- 1word = 2byte = 16bits
- 大小端模式
小端模式:高字节放到高地址
大端模式:高字节放到低地址 - 内存知识
1.数据段:存放全局变量,全局变量的地址在编译的时候已经确定.
2.代码段:存放代码
3.栈段:存放局部变量sp(栈顶寄存器)移动时,并不会删除原来的数据,直到有新的数据才会覆盖
- 内存的高地址存放系统数据(ROM-只读-例如cpu信息等),低地址存放RAM(可读可写)
- 1.栈平衡: 函数调用前后的栈顶指针(sp)要一致,通过
add sp, 4
(给sp加4)回到栈顶
2.如果不回到栈顶,那么栈空间会被用完 - 1.函数的返回值一般放在x0(arm64)或者ax(win64)寄存器中
2.函数的参数(局部变量)放在栈(ss)里面,通过push和pop和add sp,4
维持堆栈平衡
3.递归崩溃是因为栈容纳不了那么多的布局变量
4.函数分开调用
(参数入栈出栈快速完成)和函数内继续调函数
(函数的参数会一直入栈)是不一样的.
十三.iOS签名机制
- 编译阶段:
1.iOS创建证书的时候,用mac生成的request其实就是那台mac电脑的公钥.
2.生成request文件的那台mac电脑的私钥是用来签名代码,使用那台mac电脑的私钥将代码进行签名,保证代码没有被篡改. - 安装阶段:
1.apple的fir私钥用来签名mac的公钥(CA机构的功能)------>cer文件
2.apple的sec私钥用来签名第一个签名 + app id + devices + entitlement
------->mobileProvision.profile文件 - p12是干啥的
知道为啥你得要生成证书的那台mac的p12文件了吧,因为p12就是apple用自己的私钥对那台mac的公钥进行签名的cer,给了别人以后,别人才能用apple的公钥进行解密cer拿到那台mac的公钥,才能验证那台mac对代码的签名.
总结一下流程:
1.在官网创建appID
2.本地用钥匙串生成request文件
其实就是拿到mac的公钥
3.上传request文件到apple官网,得到cer文件(apple充当CA角色)
其实就是apple用自己的fir私钥将**mac的公钥**进行签名
4.官网填写device等信息,得到mobileProvision.profile文件
其实就是apple用自己的sec私钥将**第一个签名 + app id + devices **进行签名
5.在xcode安装好pp文件,编译
其实就是 1.xcode用mac的私钥对代码进行签名 2.用apple的sec公钥验证sec私钥,如果一致就说明没有被篡改,得到**第一个签名 + app id + devices **,然后对比当前真机是否在devices列表里面或者appid是否一致 3.第二部没有问题,就用apple的fir公钥验证第一个签名(apple用自己的fir私钥将**mac的公钥**进行签名),如果一致就能拿到mac的公钥,然后用mac的公钥验证代码是否被篡改
6.如果是在appstroe下载的app,那么只需要fir签名就行了.(因为已经过了苹果的审核,所以不需要pp文件等....)
十四:重签名
- 越狱手机已经破解了系统权限,不需要验证签名,所以可以安装任何macho文件(任何应用)
- 使用codeSign进行重签名(
man codeSign 等价于 codeSign --help
)
1.将embedded.mobileprovision放进app包里面
2.查看证书idsecurity find-identity -v -p codesigning
3.从provision.profile文件里抽取entitlements文件
①:security cms -D -i embedded.mobileprovision > temp.plist
②/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist
③删除temp.plist
3.codeSign -fs 证书id --entitlements entitlements.plist xxx.app
4.新建Payload文件夹,将app放进去压缩,将Payload.zip修改为Payload.ipa.