千家信息网

怎么使用radare2逆向iOS Swift应用程序

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容介绍了"怎么使用radare2逆向iOS Swift应用程序"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,
千家信息网最后更新 2026年11月01日怎么使用radare2逆向iOS Swift应用程序

本篇内容介绍了"怎么使用radare2逆向iOS Swift应用程序"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

0x01 前言

使用 radare2 逆向 iOS Swift 应用程序,我们将使用iGoat应用程序。我们的目标是反编译iOS Swift应用程序的外观。这是以前iGoat Objective C项目的Swift版本。使用OWASP iGoat,您可以学习iOS Swift应用程序中的漏洞。

KeychainExerciseVC.swift

class KeychainExerciseVC: UIViewController {    @IBOutlet weak var usernameTextField: UITextField!    @IBOutlet weak var passwordTextField: UITextField!    override func viewDidLoad() {        super.viewDidLoad()        secureStore(userName: "iGoat", password: "taoGi")    }    func secureStore(userName: String, password: String) {        do {            // This is a new account, create a new keychain item with the account name.            let passwordItem = KeychainPasswordItem(service: "SaveUser",                                                    account: userName,                                                    accessGroup: nil)            // Save the password for the new item.            try passwordItem.savePassword(password)        } catch {            fatalError("Error updating keychain - \(error)")        }    }

一旦viewDidLoad()被调用,它会调用secureStore与userName: "iGoat"和password: "taoGi"。我们研究的目的就是了解这些方法在反汇编中是什么样子的。

准备开始

在我们开始之前,我们必须减少二进制文件体积。这可以使用radare2的rabin2完成:

$ cd Payload/iGoat-Swift.app$ rabin2 -x iGoat-Swift

这将创建一个包含两个二进制文件(32/64位)的文件夹iGoat-Swift.fat/,打开32位二进制,进行分析,并启用字符串模拟:

$ r2 -e bin.demanglecmd=true -e emu.str=true iGoat-Swift.fat/iGoat-Swift.arm_32.0[0x000bfe60]> aaaa

让我们看看我们可以找到关于二进制各部分中的swift的内容:

iS~swift09 0x0022f400 10501 0x00233400 10501 -r-x 9.__TEXT.__swift3_typeref10 0x00231d08   456 0x00235d08   456 -r-x 10.__TEXT.__swift3_assocty11 0x00231ed0   656 0x00235ed0   656 -r-x 11.__TEXT.__swift2_proto12 0x00232160  3284 0x00236160  3284 -r-x 12.__TEXT.__swift3_fieldmd13 0x00232e34    60 0x00236e34    60 -r-x 13.__TEXT.__swift3_builtin14 0x00232e70  2772 0x00236e70  2772 -r-x 14.__TEXT.__swift3_reflstr16 0x002339ec  1552 0x002379ec  1552 -r-x 16.__TEXT.__swift3_capture

我们当前的方法不是很好(仅使用r2检查二进制,仅静态方法),我们不能指望在反汇编中找到很多东西。 我们将在以后的学习中了解如何获取更多信息(小小剧透:也涉及r2)。我们假装我们没有看到源代码,因为我们现在就是在做"Keychain Exercise"。输入ic?

$ r2 -- -- Radare2, what else?[0x00000000]> ic?| ic                 List classes, methods and fields| icc                List classes, methods and fields in Header Format

检查classes

首先我们来看看这些类:

ic~+class | grep iGoat...0x00281678 [0x000efe48 - 0x000f0378] (sz 1328) class 0 iGoat_Swift.HTMLViewController0x002816b0 [0x000f4b48 - 0x000f4d60] (sz 536) class 0 iGoat_Swift.CenterContainmentSegue0x002816c8 [0x000f4f68 - 0x000f5578] (sz 1552) class 0 iGoat_Swift.KeychainExerciseVC0x002816ec [0x000f86bc - 0x000f8a6c] (sz 944) class 0 iGoat_Swift.CutAndPasteExerciseVC0x00281704 [0x000f8bf0 - 0x000f92c4] (sz 1748) class 0 iGoat_Swift.BinaryPatchingVC0x00281720 [0x000f94e4 - 0x000f9fa8] (sz 2756) class 0 iGoat_Swift.URLSchemeAttackExerciseVC...

我们可以iGoat_Swift.KeychainExerciseVC在地址中找到0x002816c8。

检查flags

另一种选择是查看flags(f)和grep(~)case insensitive(+)Keychain:

[0x00044798]> f~+Keychain0x001f2330 38 str.TtC11iGoat_Swift18KeychainExerciseVC...0x001f2450 26 str.Error_updating_keychain0x001f4ccf 52 str.Unexpected_error__d_deleting_identity_from_keychain0x001f801a 49 str.CBLOpenIDConnectAuthorizer_keychainAttributes0x001f80fd 34 str.:_No_ID_token_found_in_Keychain0x001f8170 32 str.:_Read_ID_token_from_Keychain...0x002816c8 1 class.iGoat_Swift.KeychainExerciseVC0x000f4f68 1 method.iGoat_Swift.KeychainExerciseVC.usernameTextField0x000f4f8c 1 method.iGoat_Swift.KeychainExerciseVC.setUsernameTextField:0x000f4fa4 1 method.iGoat_Swift.KeychainExerciseVC.passwordTextField0x000f4fc8 1 method.iGoat_Swift.KeychainExerciseVC.setPasswordTextField:0x000f4fe0 1 method.iGoat_Swift.KeychainExerciseVC.viewDidLoad0x000f5094 1 method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender:0x000f5290 368 method.iGoat_Swift.KeychainExerciseVC.initWithNibName:bundle:0x000f5578 1 method.iGoat_Swift.KeychainExerciseVC.initWithCoder:

我们再次看到iGoat_Swift.KeychainExerciseVC地址中的类0x002816c8。

class信息

我们还可以获得有关此class的完整信息:

[0x00044f44]> ic iGoat_Swift.KeychainExerciseVCclass iGoat_Swift.KeychainExerciseVC0x000f4f68 method iGoat_Swift.KeychainExerciseVC      usernameTextField0x000f4f8c method iGoat_Swift.KeychainExerciseVC      setUsernameTextField:0x000f4fa4 method iGoat_Swift.KeychainExerciseVC      passwordTextField0x000f4fc8 method iGoat_Swift.KeychainExerciseVC      setPasswordTextField:0x000f4fe0 method iGoat_Swift.KeychainExerciseVC      viewDidLoad0x000f5094 method iGoat_Swift.KeychainExerciseVC      loginActionWithSender:0x000f5290 method iGoat_Swift.KeychainExerciseVC      initWithNibName:bundle:0x000f5578 method iGoat_Swift.KeychainExerciseVC      initWithCoder:0x000f5140 method iGoat_Swift.KeychainExerciseVC      .cxx_destruct

注意viewDidLoad位于的方法0x000f4fe0。提示:icc用于一个很好的类似c-header的输出:

@interface iGoat_Swift.KeychainExerciseVC :{   iGoat_Swift.KeychainExerciseVC::(ivar)usernameTextField   iGoat_Swift.KeychainExerciseVC::(ivar)passwordTextField}- (void) setUsernameTextField:- (void) setPasswordTextField:- (void) viewDidLoad- (void) loginActionWithSender:@end

如果您需要,可以将其保存到文件中,icc > iGoat-Swift.arm_32.0.h或者只显示内部较少的文件:icc~..func viewDidLoad():在视图控制器将其视图层次结构加载到内存后调用此方法。无论视图层次结构是从nib文件加载还是在loadView()方法中以编程方式创建,都会调用此方法。我们通常会覆盖此方法以对从nib文件加载的视图执行其他初始化。在这里,我们将找到练习的主要代码。如果我们要找0x000f4fe0,我们会看到它被标记为method.iGoat_Swift.KeychainExerciseVC.viewDidLoad(我们之前在旗帜中看到过)。

反编译

我们找到了"切入点",让我们仔细检查一下。

viewDidLoad

r2显示以下反汇编:

[0x000f4ff4]> pdf            ;-- method.iGoat_Swift.KeychainExerciseVC.viewDidLoad:╭ (fcn) sub.objc_retain_fe0 180│   sub.objc_retain_fe0 ();│           ; var int local_0h @ sp+0x0│           ; var int local_4h @ sp+0x4│           ; var int local_8h @ sp+0x8│           ; var int local_ch @ sp+0xc│           ; UNKNOWN XREF from str. (+0x14)│           0x000f4fe0      b0402de9       push {r4, r5, r7, lr}│           0x000f4fe4      08708de2       add r7, sp, 8│           0x000f4fe8      10d04de2       sub sp, sp, 0x10            ; "T"│           0x000f4fec      e4560ce3       movw r5, 0xc6e4│           0x000f4ff0      0040a0e1       mov r4, r0│           0x000f4ff4      185040e3       movt r5, 0x18│           0x000f4ff8      05509fe7       ldr r5, [0x000f5000]        ; [0xf5000:4]=0xe3550000│           0x000f4ffc      0aae03eb       bl sym.imp.objc_retain│           ; DATA XREF from sub.objc_retain_fe0 (0xf4ff8)│           0x000f5000      000055e3       cmp r5, 0│       ╭─< 0x000f5004      0a00001a       bne 0xf5034                 ; likely│       │   0x000f5008      2c0009e3       movw r0, 0x902c│       │   0x000f500c      180040e3       movt r0, 0x18│       │   0x000f5010      00008fe0       add r0, pc, r0│       │   0x000f5014      080080e2       add r0, r0, 8               ; 0x27e04c ; aav.0x0027e04c│       │   0x000f5018      6076ffeb       bl sym.func.000d29a0; sym.func.000d29a0(0x27e04c)│       │   0x000f501c      0050a0e1       mov r5, r0                  ; aav.0x0027e04c│       │   0x000f5020      b0060ce3       movw r0, 0xc6b0│       │   0x000f5024      180040e3       movt r0, 0x18│       │   0x000f5028      5bf07ff5       dmb ish│       │   0x000f502c      00008fe0       add r0, pc, r0│       │   0x000f5030      005080e5       str r5, [r0]│       │   ; CODE XREF from sub.objc_retain_fe0 (0xf5004)│       ╰─> 0x000f5034      08408de5       str r4, [sp + local_8h]│           0x000f5038      08008de2       add r0, sp, 8│           0x000f503c      0c508de5       str r5, [sp + local_ch]│           0x000f5040      641203e3       movw r1, 0x3264             ; 'd2'│           0x000f5044      181040e3       movt r1, 0x18│           0x000f5048      01109fe7       ldr r1, [0x000f5050]        ; [0xf5050:4]=0xe30a085c│           0x000f504c      e6ad03eb       bl sym.imp.objc_msgSendSuper2│           ; DATA XREF from sub.objc_retain_fe0 (0xf5048)│           0x000f5050      5c080ae3       movw r0, 0xa85c│           0x000f5054      0010a0e3       mov r1, 0│           0x000f5058      0f0040e3       movt r0, 0xf│           0x000f505c      30330de3       movw r3, 0xd330│           0x000f5060      0f3040e3       movt r3, 0xf│           0x000f5064      04108de5       str r1, [sp + local_4h]│           0x000f5068      0510a0e3       mov r1, 5│           0x000f506c      00008fe0       add r0, pc, r0              ; 0x1ef8d0 ; "iGoat" ; str.iGoat│           0x000f5070      03308fe0       add r3, pc, r3              ; 0x1f23a8 ; "taoGi" ; str.taoGi│           0x000f5074      00108de5       str r1, [sp]│           0x000f5078      0510a0e3       mov r1, 5│           0x000f507c      0020a0e3       mov r2, 0│           0x000f5080      c50100eb       bl sub.SaveUser_79c│           0x000f5084      0400a0e1       mov r0, r4│           0x000f5088      e3ad03eb       bl sym.imp.objc_release│           0x000f508c      08d047e2       sub sp, r7, 8╰           0x000f5090      b080bde8       pop {r4, r5, r7, pc}        ; r13

方法摘要:

[0x000f4ff4]> pds0x000f4ffc bl sym.imp.objc_retain0x000f5018 bl sym.func.000d29a00x000f504c bl sym.imp.objc_msgSendSuper20x000f506c str.iGoat0x000f5070 str.taoGi0x000f5080 bl sub.SaveUser_79c0x000f5088 bl sym.imp.objc_release;-- method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender::0x000f50a8 bl sym.imp.objc_retain0x000f50b0 bl sym.imp.objc_retain0x000f50b8 bl sub.swift_unknownWeakLoadStrong_d5c0x000f50c0 bl sym.imp.objc_release0x000f50d0 b sym.imp.objc_release

需要注意的事项:1.func viewDidLoad()变成objc_retain: sub.objc_retain_fe02.我们可以看到,即使在摘要中我们也可以找到字符串iGoat和taoGi。3.它sub.SaveUser_79c使用这些字符串调用子例程。

sub.SaveUser_79c

子程序sub.SaveUser_79c位于0x000f579c:

[0x000f4ff4]> s sub.SaveUser_79c[0x000f579c]> pdf╭ (fcn) sub.SaveUser_79c 516│   sub.SaveUser_79c ();│           ; var int local_0h @ sp+0x0│           ; var int local_4h @ sp+0x4│           ; var int local_8h @ sp+0x8│           ; var int local_ch @ sp+0xc│           ; var int local_10h @ sp+0x10│           ; var int local_14h @ sp+0x14│           ; var int local_18h @ sp+0x18│           ; var int local_1ch @ sp+0x1c│           ; var int local_20h @ sp+0x20│           ; var int local_24h @ sp+0x24│           ; var int local_28h @ sp+0x28│           ; var int local_2ch @ sp+0x2c│           ; var int local_30h @ sp+0x30│           ; var int local_34h @ sp+0x34│           ; var int local_48h @ sp+0x48│           ; var int local_4ch @ sp+0x4c│           ; CALL XREF from sub.objc_retain_fe0 (0xf5080)│           0x000f579c      f0402de9       push {r4, r5, r6, r7, lr}│           0x000f57a0      0c708de2       add r7, sp, 0xc│           0x000f57a4      00052de9       push {r8, sl}│           0x000f57a8      028b2ded       vpush {d8}│           0x000f57ac      58d04de2       sub sp, sp, 0x58            ; 'X'│           0x000f57b0      0340a0e1       mov r4, r3│           0x000f57b4      a53b0ce3       movw r3, 0xcba5│           0x000f57b8      0f3040e3       movt r3, 0xf│           0x000f57bc      0c5097e5       ldr r5, [r7, 0xc]│           0x000f57c0      03308fe0       add r3, pc, r3              ; 0x1f236d ; "SaveUser" ; str.SaveUser│           0x000f57c4      2c308de5       str r3, [sp + local_2ch]│           0x000f57c8      0830a0e3       mov r3, 8│           0x000f57cc      0060a0e3       mov r6, 0│           0x000f57d0      30308de5       str r3, [sp + local_30h]│           0x000f57d4      38308de2       add r3, sp, 0x38│           0x000f57d8      34608de5       str r6, [sp + local_34h]│           0x000f57dc      470083e8       stm r3, {r0, r1, r2, r6}│           0x000f57e0      0100a0e3       mov r0, 1│           0x000f57e4      48608de5       str r6, [sp + local_48h]│           0x000f57e8      4c608de5       str r6, [sp + local_4ch]│           0x000f57ec      5000cde5       strb r0, [sp, 0x50]│           0x000f57f0      0500a0e1       mov r0, r5│           0x000f57f4      30ae03eb       bl sym.imp.swift_unknownRetain│           0x000f57f8      081097e5       ldr r1, [r7, 8]│           0x000f57fc      2c308de2       add r3, sp, 0x2c│           0x000f5800      0400a0e1       mov r0, r4│           0x000f5804      0520a0e1       mov r2, r5│           0x000f5808      0080a0e3       mov r8, 0│           0x000f580c      dea400eb       bl sub._b8c; sub._b8c(0x0, 0x4042f04f)│           0x000f5810      000058e3       cmp r8, 0│           0x000f5814      1cd04702       subeq sp, r7, 0x1c│           0x000f5818      028bbd0c       vpopeq {d8}│           0x000f581c      0005bd08       popeq {r8, sl}│           0x000f5820      f080bd08       popeq {r4, r5, r6, r7, pc}  ; aav.0x000cf2c0│           0x000f5824      2fe1ffeb       bl sym.func.000edce8│           0x000f5828      3810a0e3       mov r1, 0x38                ; '8'│           0x000f582c      0320a0e3       mov r2, 3│           0x000f5830      0350a0e3       mov r5, 3│           0x000f5834      99c2ffeb       bl sym.func.000e62a0; sym.func.000e62a0(0x0)│           0x000f5838      0040a0e1       mov r4, r0│           0x000f583c      000c0ce3       movw r0, 0xcc00             ; "xD"│           0x000f5840      0f0040e3       movt r0, 0xf│           0x000f5844      0610a0e3       mov r1, 6│           0x000f5848      00008fe0       add r0, pc, r0              ; 0x1f2450 ; "Error updating keychain - " ; str.Error_updating_keychain...

方法摘要:

[0x000f579c]> pds0x000f57c0 str.SaveUser0x000f57f4 bl sym.imp.swift_unknownRetain0x000f580c bl sub._b8c0x000f5824 bl sym.func.000edce80x000f5834 bl sym.func.000e62a00x000f5848 str.Error_updating_keychain0x000f5868 bl sym.func.000f0e34

需要注意的事项:1.XREF来自viewDidLoad:; CALL XREF from sub.objc_retain_fe0 (0xf5080)。2.字符串 SaveUser。3.函数调用:sym.func.000edce8和sym.func.000e62a0和sym.func.000f0e34>。4.字符串 Error updating keychain -所以我们猜测它试图在这里更新Keychain。现在我们看到了这个字符串Error updating keychain - ......想象一下,我们还没有通过查看classes(ic)而是通过查看strings(iz)来开始,这也是一种非常常见的方法。

iz~+keychain1530 0x001ee330 0x001f2330  37  38 (4.__TEXT.__cstring) ascii _TtC11iGoat_Swift18KeychainExerciseVC1533 0x001ee380 0x001f2380  39  40 (4.__TEXT.__cstring) ascii Error reading password from keychain -1535 0x001ee3b0 0x001f23b0 154 155 (4.__TEXT.__cstring) ascii /Users/swaroop.yermalkar/AWS/iGoat-Swift-master/iGoat-Swift/iGoat-Swift/Source/Exercises/InsecureLocalDataStorage/KeychainAnalyze/KeychainExerciseVC.swift1536 0x001ee450 0x001f2450  26  27 (4.__TEXT.__cstring) ascii Error updating keychain -...axt @ 0x001f2450sub.SaveUser_79c 0xf5848 [DATA] add r0, pc, r0

"怎么使用radare2逆向iOS Swift应用程序"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

方法 文件 应用程序 程序 应用 字符 字符串 二进制 视图 检查 信息 内容 摘要 更多 此方法 学习 事项 地址 就是 层次 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海睿民互联网科技有限公司 互联网科技行业发展 中国互联网科技股 互联网科技股票 腾讯科技 互联网女皇 奔汉互联网科技 顺玮阁互联网科技 互联网金融监管科技 甘肃拓世互联网科技有限公司 顺网科技2021年互联网排名 北京三清互联网科技 团飞科技与伯堂互联网服务平台 世界互联网科技公司市值排名 宝灵互联网科技有限公司 佛山市翊博互联网络科技有限公司 城市宝互联网科技有限公司 美国互联网科技公司 广西泛欧互联网科技有限公司 每日互联网科技新闻 株洲百竞科技的互联网营销顾问 互联网和科技技术 深圳齐家互联网科技 卫星互联网科技股票 农村开互联网科技讲堂 科技类公司包括互联网吗 保险科技服务互联网营销体系 上海钢联属于互联网科技股吗 互联网科技股为什么大涨 互联网领先科技成果宣传视频 如何强化互联网金融科技
0