iOS 开发 Objective-C

iOS 底层 day 14 真机任意app调试 破解命令行程序

2020-08-06  本文已影响0人  望穿秋水小作坊

一、真机调试任意 APP

  1. 通过 Mac 的 lldb 链接到 iPhone 上 debugserver 调试 QQ

  2. 通过 Xcode 上查看真机日志,当我们在 qq 上输入 12345 并发送会调用的方法如下。

    真机日志
  3. 我们锁定,我们想动态调试 -[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345] 这个方法的一些信息。

  4. 打开 Hopper Disassembler 找到 -[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345] 这个方法,获取他的方法地址 0x1003f5740

  5. 用指令 image list 拿到 qq 这个程序当前的 ASLR 地址 0xee8000

  6. 将 Hopper 地址加上 ASLR,获得方法在内存中的位置 0x1003f5740 + 0xee8000 = 0x1012DD740

  7. 我们拿着这个地址去打断点 breakpoint set -a 0x1012DD740

(lldb) breakpoint set -a 0x1012DD740
Breakpoint 1: where = QQ`___lldb_unnamed_symbol17899$$QQ, address = 0x00000001012dd740
  1. 如何确定我们断点位置打对了呢?如下验证方法,qq输入框输入1234,程序进入断点:
(lldb) po $x0
<QQChatViewController: 0x14c3d1600>
(lldb) x/s $x1
0x1035cc40e: "sendData:showText:"
(lldb) po $x2
<>
(lldb) po $x3
12345
  1. 看到 x/s $x1 的输出,我们知道断点的位置完全正确。思考为什么 x0 是控制器 x1 是方法名 x2 x3 是参数呢?

  2. 因为 OC 代码最终都会完成如下转换:

QQChatViewController *vc;
[<QQChatViewController: 0x14c3d1600> sendData:<> showText:12345];
// 最终会转换成
objc_msgSend(vc,@selector(sendData:showText:),data,text);
  1. 如果我想从qq启动开始调试程序我们该怎么做呢?
$debugserver -x auto *:端口号 APP 的可执行文件路径

二、破解 Mac 命令行工具

  1. 创建一个 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;
}

  1. 运行项目,生成一个 Product 可执行文件,进入该文件目录:
carrotdeMacBook-Pro:Debug carrot__lsp$ ./XXSystem 
请输入正确的密码:12
请输入正确的密码:12345
请输入正确的密码:123456
密码输入正确,欢迎使用 xx 管理系统! 
  1. 这是不是非常像我们 mac 上的一个登陆系统,需要输入正取的密码,才能通过密码校验,才能访问内部程序。

  2. 接下来我们思考下如何破解他,达到不输入密码,或者随便输入密码,或者直接就登录完毕的功能。

  3. 我们将可执行文件,拖入 hopper 中分析,假设我们各种分析后,分析出上面程序主要逻辑位于 main 函数内。

hopper 分析结果
  1. 我们利用前面汇编知识做如下代码分析
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]
  1. 结合分析和程序输入页面,我们可以猜测出可能就是我们的登陆逻辑。接下来我们尝试把回调的逻辑抹除掉,再生成新的可执行文件试一下。选中第三行开始 到 jmp 的代码 选择 hoppermodifyNOP Region 选项,把它抹掉,点击hopper左上角的 file,选择 Produce New Executable ,导出一份新的可执行文件。

  2. 访问可执行文件,我们可以发现,我们已经成功 hook 掉了登陆验证逻辑。

carrotdeMacBook-Pro:macLine carrot__lsp$ ./XXSystem2
密码输入正确,欢迎使用 xx 管理系统! 

三、加密解密

  1. 对称加密
  1. 对称加密
  1. 混合加密

使用 AES 和 RSA,吸取各自的优点,弥补缺点。比如 Hppts/SSL 等等都是用的是混合加密

Alice 发送消息约 Bob

Bob 收到 Alice 的消息

上一篇下一篇

猜你喜欢

热点阅读