iOS 底层 day 14 真机任意app调试 破解命令行程序
一、真机调试任意 APP
-
通过 Mac 的 lldb 链接到 iPhone 上 debugserver 调试 QQ
-
通过 Xcode 上查看真机日志,当我们在 qq 上输入
真机日志12345
并发送会调用的方法如下。
-
我们锁定,我们想动态调试
-[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345]
这个方法的一些信息。 -
打开
Hopper Disassembler
找到-[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345]
这个方法,获取他的方法地址0x1003f5740
。 -
用指令
image list
拿到 qq 这个程序当前的 ASLR 地址0xee8000
。 -
将 Hopper 地址加上 ASLR,获得方法在内存中的位置
0x1003f5740 + 0xee8000 = 0x1012DD740
-
我们拿着这个地址去打断点
breakpoint set -a 0x1012DD740
(lldb) breakpoint set -a 0x1012DD740
Breakpoint 1: where = QQ`___lldb_unnamed_symbol17899$$QQ, address = 0x00000001012dd740
- 如何确定我们断点位置打对了呢?如下验证方法,qq输入框输入
1234
,程序进入断点:
(lldb) po $x0
<QQChatViewController: 0x14c3d1600>
(lldb) x/s $x1
0x1035cc40e: "sendData:showText:"
(lldb) po $x2
<>
(lldb) po $x3
12345
-
看到
x/s $x1
的输出,我们知道断点的位置完全正确。思考为什么 x0 是控制器 x1 是方法名 x2 x3 是参数呢? -
因为 OC 代码最终都会完成如下转换:
QQChatViewController *vc;
[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345];
// 最终会转换成
objc_msgSend(vc,@selector(sendData:showText:),data,text);
- 如果我想从qq启动开始调试程序我们该怎么做呢?
$debugserver -x auto *:端口号 APP 的可执行文件路径
二、破解 Mac 命令行工具
- 创建一个 mac 命令行项目,在 main.m 中加入如下代码:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
int password = 0;
while (password != 123456) {
printf("请输入正确的密码:");
scanf("%d", &password);
}
printf("密码输入正确,欢迎使用 xx 管理系统! \n");
}
return 0;
}
- 运行项目,生成一个 Product 可执行文件,进入该文件目录:
carrotdeMacBook-Pro:Debug carrot__lsp$ ./XXSystem
请输入正确的密码:12
请输入正确的密码:12345
请输入正确的密码:123456
密码输入正确,欢迎使用 xx 管理系统!
-
这是不是非常像我们 mac 上的一个登陆系统,需要输入正取的密码,才能通过密码校验,才能访问内部程序。
-
接下来我们思考下如何破解他,达到不输入密码,或者随便输入密码,或者直接就登录完毕的功能。
-
我们将可执行文件,拖入
hopper
中分析,假设我们各种分析后,分析出上面程序主要逻辑位于 main 函数内。
- 我们利用前面汇编知识做如下代码分析
0000000100000eb6 cmp dword [rbp+var_14], 0x1e240 // 比较后面两个值
0000000100000ebd je loc_100000eeb // 如果上一行比较结果相同,就跳转到 `100000eeb` 继续执行
0000000100000ec3 lea rdi, qword [0x100000f60]
0000000100000eca mov al, 0x0
0000000100000ecc call imp___stubs__printf
0000000100000ed1 lea rdi, qword [0x100000f7a]
0000000100000ed8 lea rsi, qword [rbp+var_14]
0000000100000edc mov dword [rbp+var_24], eax
0000000100000edf mov al, 0x0
0000000100000ee1 call imp___stubs__scanf
0000000100000ee6 jmp loc_100000eb6 // 跳转到100000eb6
loc_100000eeb:
0000000100000eeb lea rdi, qword [0x100000f7d]
-
结合分析和程序输入页面,我们可以猜测出可能就是我们的登陆逻辑。接下来我们尝试把回调的逻辑抹除掉,再生成新的可执行文件试一下。选中
第三行开始 到 jmp 的代码
选择hopper
的modify
的NOP Region
选项,把它抹掉,点击hopper
左上角的file
,选择Produce New Executable
,导出一份新的可执行文件。 -
访问可执行文件,我们可以发现,我们已经成功
hook
掉了登陆验证逻辑。
carrotdeMacBook-Pro:macLine carrot__lsp$ ./XXSystem2
密码输入正确,欢迎使用 xx 管理系统!
三、加密解密
- 对称加密
- DES(Data Encryption Standard):已过时,不安全
- 3DES :也几乎过时
- AES(Advanced Encryption Standard):这个是现代通用加密算法
- 优点:加密解密速度快
- 缺点:对称密码存在秘钥传输安全性难以保障的问题
- 对称加密
- RSA
- 优点:解决了传输秘钥时泄露的问题
- 缺点:加密解密速度慢
- 混合加密
使用 AES 和 RSA,吸取各自的优点,弥补缺点。比如 Hppts/SSL 等等都是用的是混合加密
Alice 发送消息约 Bob
- Bob 使用
非对称加密算法
生成公钥
和私钥
,将公钥
发送给 Alice(暂时认为Alice拿到的公钥
是正确的) - Alice 用
对称加密的算法
生成会话秘钥
加密约会信息
生成密文
- Alice 再使用 Bob 的
公钥
加密会话秘钥
,然后把加密会话秘钥
和密文
发送给 Bob
Bob 收到 Alice 的消息
- Bob 使用
私钥
将加密会话秘钥
解密,获得会话秘钥
- Bob 使用
会话秘钥
解密密文
,获得 Alice 的约会信息
- 会话结束,Bob 和 Alice 去约会了,没有人知道。