逆向常用工具

把.m 编译成 c

$xcrun -sdk iphoneos clang -rewrite-objc -F Foundation -arch armv7 main.m

man security

Security是Mac系统中钥匙串和安全模块的命令行管理工具,(图形化工具为Keychain Access.app)。
钥匙串(Keychain)实质上就是一个用于存放证书、密钥、密码等安全认证实体的仓库,在计算机中保存为一个.keychain的文件。

# 语法
security [-hilqv] [-p prompt] [command] [command_options] [command_args]

名称:安全-钥匙串和安全框架的命令行界面

概要:安全性[-hilqv] [-p提示符] [命令] [command_options] [command_args]

描述:一个简单的命令行界面,可让您管理钥匙串,操纵钥匙和证书,以及从命令行执行安全框架能够执行的几乎所有操作。默认情况下,安全性将执行提供的命令并报告是否出现任何错误。如果提供了-i或-p选项,则安全性将进入交互模式,并允许用户输入多个在stdin上的tiple命令。从标准输入中读取EOF时,安全性将退出。

以下是可用选项的完整列表:

-h如果未指定任何参数,则显示所有命令的列表。如果提供了参数,请显示用法对于每个指定的命令。此选项本质上与help命令相同。

-i以交互方式运行安全性。将显示提示(默认情况下为“安全性”>),并且用户将能够在stdin上键入命令,直到遇到EOF。

-l在安全退出之前,运行/usr/bin/leaks -nocontext自行查看您执行的命令是否泄漏。

-p提示此选项暗含-i选项,但将默认提示更改为指定的参数代替。

-q将使安全性不再那么冗长。

-v将使安全性更加冗长。

  • 子命令列表如下
  1. create-keychain 创建钥匙串并加入搜索列表
  2. list-keychains 显示或设置钥匙串搜索列表
  3. default-keychain 显示或设置默认的钥匙串
  4. login-keychain 显示或设置登录钥匙串
  5. delete-keychain 删除钥匙串并从搜索列表移除
  6. lock-keychain 锁定制定的钥匙串
  7. unlock-keychain 解锁制定的钥匙串
  8. set-keychain-settings 设置钥匙串配置
  9. set-keychain-password 设置钥匙串密码
  10. dump-keychain 显示一个或多个钥匙串的内容
  11. create-keypair 创建非对称密钥对
  12. add-generic-password 向钥匙串中添加通用密码项
  13. find-generic-password 查找通用密码项
  14. delete-generic-password 删除通用密码项
  15. add-internet-password 向钥匙串中添加网络密码项
  16. find-internet-password 查找网络密码项
  17. delete-internet-password 删除网络密码项
  18. add-certificates 向钥匙串种添加证书
  19. find-certificate 查找证书
  20. delete-certificate 从钥匙串种删除证书
  21. find-identity 查找认证实体(证书+私钥)
  22. set-identity-preference
  23. get-identity-preference
  24. create-db
  25. export
  26. import
  27. cms 编码或解码CMS信息(PKCS#7)
  28. install-mds 安装/重装MDS 数据库
  29. add-trusted-cert 添加可信证书(只包含公钥,无私钥)
  30. remove-trusted-cert 删除可信证书
  31. dump-trusted-setting 显示信任配置
  32. user-trust-settings-enable 显示或管理用户级别的信任配置
  33. trust-settings-export 导出信任配置
  34. trust-settings-import 导入信任配置
  35. verify-cert 验证证书
  36. authorize 授权操作
  37. authorizationdb 变更授权策略数据库
  38. execute-with-privileges 带特权执行工具
  39. leaks 在本进程中运行/usr/bin/leaks
  40. error 显示指定错误码的描述信息
  41. create-filevaultmaster-keychain 创建一个带密钥对的钥匙串,用于FileVault恢复(FileVault是苹果系统里的一项保密机制,会自动透明地对主目录的内容进行实时加密和解密)

示例:

# 显示或设置钥匙串搜索列表
security list-keychains
# 显示或设置默认的钥匙串
security default-keychain
# 创建 create-keychain [-P] [-p <password>]   [keychainFiles...]
security create-keychain -p 123456 lz_test.keychain
# 删除钥匙串
security delete-keychain
# 解锁钥匙串 unlock-keychain  [-u] [-p <password>]  [keychainFile]
security unlock-keychain -p '1234' ~/Library/Keychains/login.keychain
security unlock-keychain -p '123456' ~/Library/Keychains/lz_test.keychain
# export 
# import
# -k <keychain> 指定要导入项目到哪个钥匙串中
# -t <type> 指定要导入的项目类型,可取值为: pub | priv | session | cert | agg
# -f <format> 指定导入项目的格式,可取值为:openssl | openssl1 | openssl2 | bsafe | raw | pkcs7 | pkcs8 | pkcs12 | netscape | pemseq
# -w 标明包装了私钥,导入时要解开
# -x 标明导入后,私钥无法提取私钥
# -P <password> 直接输入导入项目密码,默认会使用GUI输入密码
# -a 指定键值对属性,可以重复出现多次
# -A 所有程序可以使用导入的项目
# -T 指定可以使用导入项目的程序,可以重复出现多次
import <inputfile>  [-k <keychain>] [-t <type>]  [-f format] [-w]  [-P passphrase] [options...]
export [-k keychain] [-t type] [-f format] [-w] [-p] [-P passphrase] [-o outfile]
# find-certificate [-a] [-c name] [-e emailAddress] [-m] [-p] [-Z] [keychain...]


# find-identity [-p policy] [-s string] [-v] [keychain...]
# -p 按指定用途策略查找,可重复出现以指定多项,可用值有: basic, ssl-client, ssl-server, smime, eap, ipsec, ichat, codesigning, sys-default, sys-kerberos-kdc ,macappstore, appleID
# -s 为-p指定的策略提供参数
# -v 只显示有效的,默认显示所有。
# 如果未指定keychain,则使用默认的搜索列表
security find-identity -v -p codesigning    #显示默认搜索列表中有效地认证实体
security find-identity -v

codesign

  • 语法
codesign -s identity [-i identifier] [-r requirements] [-fv] [path ...]
codesign -v [-R requirement] [-v] [path|pid ...]
codesign -d [-v] [path|pid ...]
codesign -h [-v] [pid ...]
  • option
  1. -d,--display。在给定的路径上显示有关代码的信息。
  2. -f,--force。签名时,使codesign替换给定路径上的任何现有签名。
  3. -s, --sign identity。在使用此标识指定的路径上对代码签名
  4. -v, --verbose。设置(带有数字值)或增加输出的详细级别。 没有详细选项,将不产生任何输出
  5. -v, --verify。请求验证代码签名。 如果还请求其他动作(签名,显示等)-vv
  6. --entitlements path。签名时,将文件放在给定的路径上,并将其内容作为授权数据嵌入签名中
  7. -i。指定identifier
  8. -o。指定flag
  • 用法
security find-identity -v -p codesigning 
#  1) E62BA1F68D1391E4FE07EBF45049C7A648D8B445 "iPhone Developer: 泽 梁 (WVZ5JP3N7M)"
#  2) 9DBA1F6F3F55F19C4D061CCFE8B3E80AF20F4F6D "iPhone Developer: 泽 梁 (ARB84Y67A9)"
#  4) 74C538AE567879DED76B50C81489762FEC29F441 "Apple Development: 泽 梁 (WVZ5JP3N7M)"

# 签名
codesign -s 'iPhone Developer: Thomas Kollbach (7TPNXN7G6K)' Example.app
# 为了重新设置签名,你必须带上 -f 参数,有了这个参数,codesign 会用你选择的签名替换掉已经存在的那一个:
codesign -f -s 'iPhone Developer: Thomas Kollbach (7TPNXN7G6K)' Example.app
# codesign 还可以为你提供有关一个可执行文件签名状态的信息
codesign -vv -d ./empty.app
# Authority=Apple Distribution: Beijing Rongzhi Technology Co., Ltd. (58Y74FY8QK)
# Authority=Apple Worldwide Developer Relations Certification Authority
# Authority=Apple Root CA
# Authority 开头的那三行。这三行告诉你到底是哪一个证书为这个 app 设置了签名。在这里当然是我的证书,iPhone Developer: Thomas Kollbach (7TPNXN7G6K)。我的这个证书则是被证书 Apple Worldwide Developer Relations Certification Authority 设置了签名的,依此类推这个证书则是被证书 Apple Root CA 设置了签名。

# 检查一下签名是否完好
codesign --verify empty.app
echo "hello" > empty.app/hello.txt
codesign --verify empty.app
# empty.app: a sealed resource is missing or invalid
rm -rf empty.app/hello.txt
codesign --verify empty.app

# 可以尝试查看签名信息中具体包含了什么授权信息:
codesign -d --entitlements - empty.app
  • Provisioning Profiles 文件存放在 ~/Library/MobileDevice/Provisioning Profiles 目录下。
  • 配置文件并不是一个 plist 文件,它是一个根据密码讯息语法 (Cryptographic Message Syntax) 加密的文件
  • 可以用 security 来看看一个 .mobileprovision 文件内部是什么样子:
security cms -D -i  ~/Library/MobileDevice/Provisioning\ Profiles/12a5178b-11a9-412e-8ba3-6aa78da89d12.mobileprovision
# DeveloperCertificates 这项,这一项是一个列表,包含了可以为使用这个配置文件的应用签名的所有证书。如果你用了一个不在这个列表中的证书进行签名,无论这个证书是否有效,这个应用都无法运行
# 如果你打开的是一个用于开发测试的证书,你会看到一项 ProvisionedDevices,在这一项里包含了所有可以用于测试的设备列表。因为配置文件需要被苹果签名,所以每次你添加了新的设备进去就要重新下载新的配置文件。

otool

位于 Xcode开发工具链 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain 下的 usr/bin目录下

otool -h 打印Mach-O头
otool -l empty 打印加载命令Load Commands 也会把Mach Header打出来
otool -L empty 打印共享库 这里的L是link的意思

class-dump

  • class-dump
  • 简介:class-dump 是一个工具,它利用了 Objective-C 语言的运行时特性,将存储在 Mach-O 文件中的头文件信息提取出来,并生成对应的 .h 文件。
  • 只能导出OC的哦。我安装有MonkeyDev,他安装了classdump.通过which class-dump获得安装路径为:
$which class-dump 
=>/opt/MonkeyDev/bin/class-dump
  • 用法
$class-dump -H MachO文件Path -o 导出头文件需要存放路径
$class-dump -H WeChat -o ~/Desktop/wechatHeader

ASLR (Address Space Layout Randomization)

  • 小黄书第93页
  • 每次进程启动时,同一进程的所有模块在虚拟内存中的起始地址都会产生随机偏移
  • 但是他的大小是不会变的
  • 可以在LLDB下使用 image命令拿到本次的ASLR地址
    $image list -o -f
    
  • IDA,Hopper 反汇编出来的是 基地址 也就是没有偏移前的地址
    • 偏移后模块基地址 = 偏移前模块基地址 + ASLR偏移
    • funcA的偏移后的地址 = 偏移前符号地址 + ASLR偏移
    • 比如NiXaingDemo中的 aslr = 0x00000000029bc000
      [ViewController loadrequest]偏移后的Address = 00000001000068d0 + 0x00000000029bc000
      = 0x1029c28d0
      lldb中在 0x1047da924 下断点 br s -a 0x1029c28d0
      [BeiNiClass beiNiFunction7] 偏移后的Address = 0000000100006864 + 0x00000000029bc000
      =0x1029c2864 下断点 br s -a 0x1029c2864

Theos

  1. /opt/theos/bin/nic.pl -> 选择模块创建项目 一般是Tweak 写代码
  2. make 把当前的工程编译一下
  3. make package后会生成一个deb包
  4. make install安装 ,会把安装包拷贝到手机上,需要连接到手机 exprot THEOS_DEVICE_IP = 10.2.198.1.23 再 make install
    ##logify.py
    在 ~/.bash_profile 文件下 添加 alias logify="/opt/theos/bin/logify.pl"
  • logify 头文件path (> tweak.xm路径)【这个是写入文件的可以不加】

#CaptinHook

  • wiki
  • 提供了一系列方法用来hook NSObject
CHDeclareClass
CHOptimizedMethod
CHConstructor{
    CHLoadLateClass
    CHHook
    CHClassHook
    CHDeclareMethod//添加新方法
    CHPropertyRetainNonatomic//添加新属性
}

yololib

  • yololib 可执行文件path dylibpath
  • /usr/local/bin/yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/$.framework/$"
  • /usr/local/bin/yololib "$TARGET_APP_PATH/$APP_BINARY" "$.dylib"

#otool

  • otool -l exec | grep crypt 查看文件加密信息
  • otool -L yourApp.app/yourApp 查看Mach-O(可执行二进制文件)引用的framework与dylib
  • otool -h + 文件名 //查看头部
  • otool -hv + 文件名
  • otool -s __TEXT __text xxx //二进制
  • otool -tv xxx|head -n 10 //可视化

install_name_tool 动态库的依赖动态库路径修改工具

  • /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool [-change old new] ... [-rpath old new] ... [-add_rpath new] ... [-delete_rpath old] ... [-id name] input
  • -change 修改依赖路径
  • -id 修改动态库本身的install_path
  • 扩展知识点
    • install Name 本质是一个路径,告诉连接器在运行时在哪里找到需要的库
    • @executable_path 这个变量表示可执行程序所在的目录
    • @loader_path 这个变量表示每一个被加载的 binary (包括可执行程序, dylib, framework 等) 所在的目录. 在一个进程中, 对于每一个模块, @loader_path 会解析成不用的路径, 而 @executable_path 总是被解析为同一个路径(可执行程序所在目录).
    • @rpath 将告诉动态链接器去本地的列表搜索这个库。

lipo

lipo -info QQKSong 查看二进制文件信息 => QQKSong are: armv7 arm64 lipo QQKSong -thin arm64 -output ../arm64 => 提取arm64架构
lipo -create thin_onew thin_two -output fat

IDA IDA调试技巧

  • ida常用快捷键 ida常用快捷键

/opt

  1. 编译后把 binary 拖到 ~/Documents/bin 目录下
  2. 在 ~/.bash_profile 文件下 添加 alias binary="~/Documents/bin"

acextract 导出 Assets.car的资源图片

mkdir -p ~/AssetsOutput
acextract -i ~/Assets.car -o ~/AssetsOutput

restore-symbol 对bin进行符号还原

  1. 编译
cd restore-symbol && make 
  1. 对OC方法进行符号还原
restore-symbol origin_mach_o_file -o mach_o_with_symbol 
  1. 对block进行符号还原; 等IDA反编译完成后,把 ~/Documents/opt/ida_search_block.py 或者 ~/Documents/opt/restore-symbol/search_oc_block/ida_search_block.py cp到 待还原的bin目录下
  2. 在IDA点File -> Script file, 选ida_search_block.py 会生成 一个 block_symbol.json 文件,下方的命令 -j 就是选json文件
restore-symbol origin_mach_o_file -o mach_o_with_block_symbol  -j block_symbol.json

ida-swift-demangle 一个ida脚本来解析swift函数名

  1. 等IDA分析完成后 点File -> Script file,选 ~/Documents/opt/ida-swift-demangle.py 或者 ~/Documents/opt/ida-swift-demangle/ida-swift-demangle.py ,copy到ida分析的bin目录下比较好

frida-ios-dump 一键砸壳和查看进程id bundleid

  1. 下载源码,切换分支 起别名 frida-ios-dump
  2. 连上手机 端口转发 并使用
$ iproxy 2222 22
$ frida-ios-dump -l  //查看所有的进程 可以用 grep 过滤
$ frida-ios-dump Display name or Bundle identifier  砸到电脑的下载目录

sbr 使用Python脚本强化LLDB调试器 例子

cd ~/Documents/opt
mkdir lldbScript
touch sbr.py

然后在 ~/.lldbinit 文件写下 command script import ~/Documents/opt/lldbScript/sbr.py 重启即可

LLDB别名/正则表达式和Python脚本的集合

  1. 下载源码 然后在 ~/.lldbinit 文件写下 command script import ~/Documents/opt/LLDB/lldb_commands/dslldb.py

Hopper Disassembler

  • 理论知识:能通过 Mach-O 做代码分析代码的一个重要原因就是机器语言可以反推成汇编语言,是可逆的。原因就是在同一种架构平台下,每一条汇编指令都有与之对应的唯一的机器指令,这种反推行为一般叫反编译。但是 汇编语言不能百分百反推oc等高级语言,因为有些不同但相似的代码,编译成汇编语言是一模一样的。比如具有相同元素的结构体和数组,编译后汇编语言就是一样的。所以说不能百分百还原,但是因为部分代码还是相似的,所以还是可以看个大概的。下面就借助 Hopper disassembler 工具将 Mach-O 文件的机器语言代码反编译成汇编代码、OC伪代码或者Swift伪代码。参考
  • 在左边的控制面板中,可以通过字符串搜索字段,函数名类名等等
  • 控制面板上面的导航条不同颜色代表了不同的含义
    • 蓝色 部分表示代码(code)
    • 黄色 部分表示程序(procedure)
    • 绿色 部分表示ASCII字符串(string)
    • 紫色 部分表示数据(data)
    • 灰色 部分是不能识别的类型 红色小箭头表示当前你的光标所在的位置
    • 一旦一个可执行文件被加载入Hopper,你就可以使用键盘或者界面上顶部的工具条改变它的类型。
  • 导航条上面 Transformations 上的 DACPU 此工具条包含了你能设置的(D即Date,A即ASCII,依此类推)类型按钮,这些字母同样也有快捷键,你可以直接通过快捷键直接进行类型转换。 Date类型有一些具体的表示形式:比如当你第一次选择这个类型时,Hopper将这个你选择的一块区域转换为字节型,如果你再次选择它,这个字节将会被转换为一个16位的整数型,然后再是32位的整数型,依此类推。Hopper提供了一个“取消”/“重做”的功能,让你可以随意的去更改和探索可执行文件。
    • Data :当Hopper认为数据中的一块区域表示常量的时候,这块区域将被设置为data(数据)类型。例如一段int数组,这样的情况就会被设置。
    • ASCII : 一个以空值为终止的C字符串。
    • Code :一个指令。
    • Procedure (程序):一旦确定它是由Hopper重新构建的函数的一部分,则该字节接受该类型。
    • Undefined (无法识别):这是目前为止还未被Hopper探索的一块区域。
    • D 按键不断点击,在汇编代码区会有不同的变化
  • 再右边的 View Mode 的4个按钮代表了4种不同的显示方式依次为
  • 显示模式
    • 汇编模式
      • Hopper将一行一行的汇编代码,这是很多反汇编软件都提供的一种模式。
      • 第一栏(蓝色数字处)代表指令的地址位置。它在每条指令、操作元(或者寄存器)的最前端。作为一项选择,在应用的偏好设置中,你能选择在地址和伪指令(the instruction mnemonic)之间显示指令编码。
      • 在边缘,你能看到一些有眼色的箭头服务好。这些箭头代表指令可能跳转的位置。例如,在0x100002d82和0x100002db4地址之间的蓝色箭头代表了在0x100002d82的je指令如果满足je判断的条件,则跳转至0x100002db4这个位置。当这个指令跳转为向高地址(向下跳转)跳转时,则箭头为蓝色。如果这个指令向上(向低地址)跳转时,则箭头为红色。
      • 需要注意的是在左边两个竖条(红和蓝),如果你点击红色栏,你将在相应的地址设置一个断点,如果你点击蓝色栏,你将在相应的地址设置一个书签。
    • 控制浮动图表模式
      • 控制浮动图表模式将程序以更具有结构化的方式显示出来。
      • 在此界面上你仍然可以进行编辑一些事项,比如备注和标签。鼠标可以从一个基础块移动到另一个基础块;简单地移动鼠标至当前的基础块上,使用你键盘上的方位键来跳转至最近的基础块。如果你按下向上或者向下的按键,鼠标光标将移至最近的基础块,不过请使用相同的栏目。同样,你按右键、左键也移到对应的位置。
      • 在右边的控制面板中(检测窗),你会发现存在该模式的总览图。控制浮动图表的组成展示了当前程序展示的一个整体缩略图,被称为“迷你图”。每一个方块代表一个基础块,其中的线表示它们之间的联系。在“迷你图”中,我们可以看到一个蓝色的基础块,基础块被填充为蓝色意味着光标的位置在此基础块中。在高亮灰色方块表示当前你所看到的控制浮动图表部分。你可以直接在这个“迷你图”中点击移动它。
      • 图表上的这些节点可以被修饰。例如,当你认为某块与某块具有密切联系时,可以对它们进行分组。选择这些节点并在“检测窗”点击“Group Nodes(组节点)”按钮。
      • 你也能给一个节点设置一个你常用背景色,或者插入一段文本。
    • 伪代码模式
      • 在这个模式中,Hopper将尝试着生成一些“假”代码,功能上相当于原始的CPU指令,但是它们更像是Objective-C的函数。
      • 这种模式让你分析以及阅读更加容易,不过你需要记住的是这些并不是“魔法”,有时,它并不能够将构建一个该程序完美的“假”代码展现出来,并且有些部分可能不会显示出来。因为Hopper可能将它们定义为没有联系的代码(也称之为dead code),为了尽量的避免这个问题,你可以尝试在界面的上方切换相应复选框。
    • 十六进制模式
  • 图表模式用红绿蓝三种线
    • 红色代表条件不成立时执行
    • 绿色代表条件成立
    • 代表执行