Contents
  1. 1. 越狱
  2. 2. Unix环境下常用命令
  3. 3. iOS系统也是一个操作系统,那么一个操作系统就可以进行编写代码、编译代码、执行程序,就跟我们在Mac机器上的Mac os X系统上做的事情基本差不多
  4. 4. 下面通过编写一个c程序,然后编译生成二进制可执行文件,再查看其里面的内容
  5. 5. 接下来使用otool命令将上面的可执行二进制文件test进行反汇编
    1. 5.1. 如上有T、U,其实还有很多标记
  6. 6. 查看上面得到Test可执行文件的符号表
  7. 7. 书上使用的是gdb来调试可执行二进制文件,但是随着Xcode版本升级与Mac OS X系统升级,gdb已经被lldb取代了
  8. 8. framework与App结构类似,内部都有一个bundle包,包含所有的代码以及资源文件,但有所区别
  9. 9. 在逆向App时,主要关注点
  10. 10. iOS平台上支持的安装包格式
  11. 11. Dynamic Liabrary 与 Static Liabrary
  12. 12. iOS是具备后台多任务的 – daemon守护进程

越狱

  • 越狱是指移除设备厂商为操作系统添加的一些限制性
  • 越狱是修改iOS操作系统,使得iOS系统的强制性证书签名与验签的机制半永久性失效
  • 一般越狱工具本身就是一个可以运行在iOS系统的App程序
  • 这个App程序首先是禁用iOS系统进行证书签名的机制
  • 然后通过App程序进行下载安装其所在服务器上的其他没有经过证书签名、非正规发布的其他App

Unix环境下常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ps ——显示进程状态,CPU使用率,内存使用情况等
sysctl ——检查设定Kernel配置
netstat ——显示网络连接,路由表,接口状态等
route ——路由修改
renice ——调整程序运行的优先级
ifconfig ——查看网络配置
tcpdump ——截获分析网络数据包
lsof ——列出当前系统打开的文件列表,别忘记一切皆文件,包括网络连接、硬件等
otool ① ——查看程序依赖哪些动态库信息,反编代码段……等等等等
nm ② ——显示符号表
ldid ③ ——签名工具
gdb ——调试工具
patch ——补丁工具
SSH ——远程控制

① otool,可查看可执行程序都链接了那些库(二进制文件)

这个命令很多用处,非常重要,可以查看二进制文件的很多信息

1
otool -L 二进制可执行文件名

反编译WQAlbum的TEXT段内容, 截前10行

1
otool -tV 二进制可执行文件名 |head -n 10

② nm,显示二进制文件的符号表(符号表: 类名、函数名、内存地址…)

符号表用于还原二进制文件中的程序代码

1
nm -g 二进制可执行文件名 ( -g 代表 global)

gdb调试命令

  • 已经集成在Xcode中去了用于调试App程序
  • 但是直接在硬件设备上执行时,可以获得更多的功能
  • 可以调试设备上所有的进程
  • 快速分离和重新附着到某个进程上
  • 没有桌面形式的操作系统上进行开发程序时的调试

  • 攻击者可以修改gdb命令的脚本文件,来达到操作设备上任何程序的

  • 运行、修改、监控设备上的所有的程序

iOS系统也是一个操作系统,那么一个操作系统就可以进行编写代码、编译代码、执行程序,就跟我们在Mac机器上的Mac os X系统上做的事情基本差不多

  • 比如一个iOS手机上的一个App,可以进行编写JS代码,然后运行JS代码,手机系统上的编写程序
  • iOS系统上进行程序编写的工具:

  • 一些可以公开下载到的App程序

  • ARM架构的编译器
  • ldid(连接识别编辑器,用于给一些二进制文件进行代码签名与应用软件的授权)

  • 还可以在iOS系统上运行完成SSH终端能力的App程序,完全可以将当前iOS手机设备/ipad设备作为一个攻击其他人的便携式环境

  • 然后集合iOS系统命令,make、patch、bison等

下面通过编写一个c程序,然后编译生成二进制可执行文件,再查看其里面的内容

  • 查看当前系统安装的gcc版本
1
gcc -v

补一个常用的find命令用法

1
sudo find . -name *模糊查询*
  • 编译写一个 test.c 源码文件,代码如下
1
2
3
4
5
6
7
#include <stdio.h>
#include <stdlib.h>

int main(){
printf("Hello world !!!\n");
return 0;
}
  • 然后执行编译生成二进制 .out 文件
1
gcc -o test test.c

就会生成一个二进制可执行文件 test

  • 使用file命令查看这个二进制可执行文件的信息
1
file test

输出如下

1
2
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ file test
test: Mach-O 64-bit executable x86_64

可以总结为如下几点

1
2
3
1. 文件类型: Mach-O
2. 运行cpu架构: 64-bit
3. executable: 是一个可执行文件

Mac os X/iOS系统内核,可以直接运行Mach-O格式的文件,我们可以双击运行编译生成的test文件,那么就会弹出一个终端窗口

Snip20160320_6.md.png

还可以通过终端执行test文件

1
./test

终端输出如下

1
2
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ ./test
Hello world !!!

接下来使用otool命令将上面的可执行二进制文件test进行反汇编

  • 反汇编出test文件中的 main主函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ otool -tV test -p _main
test:
(__TEXT,__text) section
_main:
0000000100000f40 pushq %rbp
0000000100000f41 movq %rsp, %rbp
0000000100000f44 subq $0x10, %rsp
0000000100000f48 leaq 0x3b(%rip), %rdi ## literal pool for: "Hello world !!!\n"
0000000100000f4f movl $0x0, -0x4(%rbp)
0000000100000f56 movb $0x0, %al
0000000100000f58 callq 0x100000f6a ## symbol stub for: _printf
0000000100000f5d xorl %ecx, %ecx
0000000100000f5f movl %eax, -0x8(%rbp)
0000000100000f62 movl %ecx, %eax
0000000100000f64 addq $0x10, %rsp
0000000100000f68 popq %rbp
0000000100000f69 retq
  • 查看test依赖的其他二进制文件(库)
1
2
3
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ otool -L test
test:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
  • 查看test的符号表
1
2
3
4
5
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ nm -g test
0000000100000000 T __mh_execute_header
0000000100000f40 T _main
U _printf
U dyld_stub_binder

如上有T、U,其实还有很多标记

  • T标记,表明该项资源(函数)并不存在于当前二进制文件中
  • 被标记为T的符号,可以在二进制文件的 __TEST段的 __test节中找到

其他的就不列举了


###使用Class-dump工具对一个二进制文件反编译出所有的.h头文件

  • 去官方下载dmg或tar压缩包,然后解压
  • 将解压文件夹中的文件拖入到/usr/local/bin/目录下
  • class-dump二进制文件
  • src目录

  • 接下来打开Xcode,创建一个OS X ApplicationMac程序工程,然后编写代码

  • 最后将代码编译生成可执行二进制文件

  • 使用file命令查看
1
2
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ file Test
Test: Mach-O 64-bit executable x86_64
  • 然后使用class-dump
1
class-dump -H Test -o ~/Desktop/headers
  • 就会在桌面生成headers文件夹,里面存放反编译出来的 .h 头文件

主要是两个文件,CDStructures.hPerson.h

  • 打开由class-dump反编译出来的Person.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//

#import "NSObject.h"

@interface Person : NSObject
{
}

- (void)say:(id)arg1;

@end

其代码与我们自己之前写的代码几乎一致.

  • 也可以尝试对一个.ipd/Playload/.app可执行文件进行class-dump反汇编所有的头文件
1
class-dump -H /Applications/xxxxx.app -o /Users/Rio/Desktop/calculate\ heads
  • 注意,如果class-dump执行失败,原因如下

class-dump 虽然非常有用,但有时我们会发现 class-dump 执行失败,无法得到我们想要的 .h 文件,或者 .h 文件的内容是加密的密文。出现这种现象的原因是:class-dump 额作用对象必须是未经加密的可执行文件,而从 App Store 下载的 App 都是经过签名加密的,可执行文件被加上了一层“壳”。可以使用 AppCrackr 来自动砸壳。

那么如果某一些AppStore中的App没有经过开发者证书私钥 进行 代码签名的App,很容易就可以通过ipa包内的 .app文件 直接反汇编出所有的.h头文件,继而做出一些猜测性的攻击.

上面的话乍一听起来很合理,但是非越狱iOS设备上,没有被签名过的任何文件,都不能在iOS设备的系统中执行或使用。


查看上面得到Test可执行文件的符号表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ nm Test
0000000100000e20 t -[Person say:]
U _NSLog
U _OBJC_CLASS_$_NSObject
0000000100001198 S _OBJC_CLASS_$_Person
U _OBJC_METACLASS_$_NSObject
0000000100001170 S _OBJC_METACLASS_$_Person
U ___CFConstantStringClassReference
0000000100000000 T __mh_execute_header
U __objc_empty_cache
0000000100000e70 T _main
U _objc_autoreleasePoolPop
U _objc_autoreleasePoolPush
U _objc_msgSend
U _objc_storeStrong
U dyld_stub_binder
  • 可以看到类本身和Meta类,之前的Meta Class文章说的Meta类终于看到了
1
2
3
4
U _OBJC_CLASS_$_NSObject
0000000100001198 S _OBJC_CLASS_$_Person
U _OBJC_METACLASS_$_NSObject
0000000100001170 S _OBJC_METACLASS_$_Person

书上使用的是gdb来调试可执行二进制文件,但是随着Xcode版本升级与Mac OS X系统升级,gdb已经被lldb取代了

通常我们都是对写好的源程序然后编译运行之后,连接Xcode的环境下进行代码调试的。其实,在没有源程序而只有编译后的二进制可执行文件情况下,一样是可以进行对其程序逻辑进行调试的.

  • 使用lldb 来调试上面的 Test 这个可执行二进制文件
1
2
3
4
xiongzenghuideMacBook-Pro:Desktop xiongzenghui$ lldb ./Test
(lldb) target create "./Test"
Current executable set to './Test' (x86_64).
(lldb)

可以看到,命令行已经进入了lldb调试的状态了。所有我们在Xcode中使用的lldb命令,均可以在终端命令行中一样的使用.


framework与App结构类似,内部都有一个bundle包,包含所有的代码以及资源文件,但有所区别

  • framework的bundle内,存放的是一个动态链接库,并不是可执行程序
  • App的bundle内,存放的就是一个可执行程序(Mach-O格式),以及所需的所有资源文件

在逆向App时,主要关注点

  • Info.plist
  • bundle identifier(很重要)
  • 可以通过bundle identifier对App进行hook
  • 主执行文件的名字

  • 主要的Mach-O可执行文件(Unix Executable)逆向
  • class-dump反编译出所有的 .h头文件
  • IDA反编译出源代码
  • GDB/LLDB调试器

iOS平台上支持的安装包格式

  • deb >>> 此种格式的安装包经常涉及系统比较底层的操作,可以获取比较高的系统权限

  • ipa >>> 是苹果目前唯一向外公开的安装包格式,获取的权限比较小,sandbox操作限制大

  • pxl >>> 起源于Mac系统的pkg格式安装包,现在已经用的很少了,基本上可以忽略


Dynamic Liabrary 与 Static Liabrary

  • Static Liabrary

  • App程序编译时,就直接将冬静态库链接App程序中,编译在一起了

  • App程序运行时,静态库代码与App代码同时加载到内存
  • 是 可执行程序

  • Dynamic Liabrary

  • App程序编译时,并不会将动态库链接到App程序中

  • App程序运行时,也不会立刻加载动态库到内存
  • 而是当App需要用到动态库时,才会去将动态库加载到App程序的内存中
  • 并不是 可执行文件

iOS是具备后台多任务的 – daemon守护进程

  • 一个程序运行在一个进程上
  • 而系统又会新开一个守护进程,来保证主程序进程能够顺利执行,以及提供一些其他的功能

eg、imagent守护来确保iMessage能够正确收发短信.


Contents
  1. 1. 越狱
  2. 2. Unix环境下常用命令
  3. 3. iOS系统也是一个操作系统,那么一个操作系统就可以进行编写代码、编译代码、执行程序,就跟我们在Mac机器上的Mac os X系统上做的事情基本差不多
  4. 4. 下面通过编写一个c程序,然后编译生成二进制可执行文件,再查看其里面的内容
  5. 5. 接下来使用otool命令将上面的可执行二进制文件test进行反汇编
    1. 5.1. 如上有T、U,其实还有很多标记
  6. 6. 查看上面得到Test可执行文件的符号表
  7. 7. 书上使用的是gdb来调试可执行二进制文件,但是随着Xcode版本升级与Mac OS X系统升级,gdb已经被lldb取代了
  8. 8. framework与App结构类似,内部都有一个bundle包,包含所有的代码以及资源文件,但有所区别
  9. 9. 在逆向App时,主要关注点
  10. 10. iOS平台上支持的安装包格式
  11. 11. Dynamic Liabrary 与 Static Liabrary
  12. 12. iOS是具备后台多任务的 – daemon守护进程