├── LICENSE.md └── README.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Attribution-ShareAlike 4.0 International 2 | 3 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 4 | 5 | ### Using Creative Commons Public Licenses 6 | 7 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 8 | 9 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 10 | 11 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 12 | 13 | ## Creative Commons Attribution-ShareAlike 4.0 International Public License 14 | 15 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 16 | 17 | ### Section 1 – Definitions. 18 | 19 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 20 | 21 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 22 | 23 | c. __BY-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. 24 | 25 | d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 26 | 27 | e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 28 | 29 | f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 30 | 31 | g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike. 32 | 33 | h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 34 | 35 | i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 36 | 37 | j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 38 | 39 | k. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 40 | 41 | l. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 42 | 43 | m. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. 44 | 45 | ### Section 2 – Scope. 46 | 47 | a. ___License grant.___ 48 | 49 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 50 | 51 | A. reproduce and Share the Licensed Material, in whole or in part; and 52 | 53 | B. produce, reproduce, and Share Adapted Material. 54 | 55 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 56 | 57 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 58 | 59 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 60 | 61 | 5. __Downstream recipients.__ 62 | 63 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 64 | 65 | B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. 66 | 67 | C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 68 | 69 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 70 | 71 | b. ___Other rights.___ 72 | 73 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 74 | 75 | 2. Patent and trademark rights are not licensed under this Public License. 76 | 77 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. 78 | 79 | ### Section 3 – License Conditions. 80 | 81 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 82 | 83 | a. ___Attribution.___ 84 | 85 | 1. If You Share the Licensed Material (including in modified form), You must: 86 | 87 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 88 | 89 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 90 | 91 | ii. a copyright notice; 92 | 93 | iii. a notice that refers to this Public License; 94 | 95 | iv. a notice that refers to the disclaimer of warranties; 96 | 97 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 98 | 99 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 100 | 101 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 102 | 103 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 104 | 105 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 106 | 107 | b. ___ShareAlike.___ 108 | 109 | In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. 110 | 111 | 1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License. 112 | 113 | 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. 114 | 115 | 3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. 116 | 117 | ### Section 4 – Sui Generis Database Rights. 118 | 119 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 120 | 121 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; 122 | 123 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and 124 | 125 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 126 | 127 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 128 | 129 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 130 | 131 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 132 | 133 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 134 | 135 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 136 | 137 | ### Section 6 – Term and Termination. 138 | 139 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 140 | 141 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 142 | 143 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 144 | 145 | 2. upon express reinstatement by the Licensor. 146 | 147 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 148 | 149 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 150 | 151 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 152 | 153 | ### Section 7 – Other Terms and Conditions. 154 | 155 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 156 | 157 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 158 | 159 | ### Section 8 – Interpretation. 160 | 161 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 162 | 163 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 164 | 165 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 166 | 167 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 168 | 169 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the [CC0 Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/legalcode). Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 170 | > 171 | > Creative Commons may be contacted at creativecommons.org. 172 | 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS Internals & Security Testing 2 | 3 |
4 | Dec 15 2021 by Vadim Yegorov <vadim.a.yegorov@gmail.com>, Software Engineer, R&D. 5 |
6 | Creative Commons Licence
7 | Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Author should be mentioned when copying or redistributing this work. 8 |
9 |
10 | 11 |
12 | 13 | # Table of contents 14 | 15 | 16 | - [iOS platform overview](#ios-platform-overview) 17 | * [File System](#file-system) 18 | + [UNIX system directories](#unix-system-directories) 19 | + [OS X/iOS–specific directories](#os-xiosspecific-directories) 20 | + [iOS File System Idiosyncrasies](#ios-file-system-idiosyncrasies) 21 | * [Applications](#applications) 22 | + [ipa file (iOS App Store Package)](#ipa-file-ios-app-store-package) 23 | + [ipa file contents](#ipa-file-contents) 24 | + [Application data in iOS filesystem](#application-data-in-ios-filesystem) 25 | * [Apple plist](#apple-plist) 26 | * [Privilege Separation and Sandbox](#privilege-separation-and-sandbox) 27 | * [Data Protection](#data-protection) 28 | * [App Capabilities](#app-capabilities) 29 | * [Device Capabilities](#device-capabilities) 30 | * [Entitlements](#entitlements) 31 | * [Application security features, Apple FairPlay DRM](#application-security-features-apple-fairplay-drm) 32 | * [Secure Enclave Processor](#secure-enclave-processor) 33 | * [AES Keys](#aes-keys) 34 | + [GID Key](#gid-key) 35 | + [UID Key](#uid-key) 36 | + [Derived keys](#derived-keys) 37 | * [Objective-C Basics](#objective-c-basics) 38 | + [Message exchange](#message-exchange) 39 | + [Method declaration](#method-declaration) 40 | * [iOS Frameworks](#ios-frameworks) 41 | * [iOS Network Frameworks](#ios-network-frameworks) 42 | * [iOS Private Frameworks](#ios-private-frameworks) 43 | - [Tools overview](#tools-overview) 44 | * [How to jailbreak](#how-to-jailbreak) 45 | * [How to install cydia package](#how-to-install-cydia-package) 46 | * [Access device](#access-device) 47 | + [libimobiledevice](#libimobiledevice) 48 | + [ideviceinstaller](#ideviceinstaller) 49 | + [libirecovery](#libirecovery) 50 | + [idevicerestore](#idevicerestore) 51 | + [libusbmuxd](#libusbmuxd) 52 | * [Access filesystem](#access-filesystem) 53 | * [Access command line](#access-command-line) 54 | * [Persisted data](#persisted-data) 55 | * [View application layout and more](#view-application-layout-and-more) 56 | - [Analyze application at runtime](#analyze-application-at-runtime) 57 | * [Frida](#frida) 58 | * [Frida basics](#frida-basics) 59 | * [Frida's --eval flag](#fridas---eval-flag) 60 | * [Frida Intercepter](#frida-intercepter) 61 | * [Frida-Trace](#frida-trace) 62 | * [Bypass anti-Frida checks](#bypass-anti-frida-checks) 63 | * [Objection](#objection) 64 | * [r2frida](#r2frida) 65 | * [Grapefruit (Passionfruit)](#grapefruit-passionfruit) 66 | * [Dwarf](#dwarf) 67 | * [Fermion](#fermion) 68 | - [Analyze application network traffic](#analyze-application-network-traffic) 69 | * [Disabling SSL pinning](#disabling-ssl-pinning) 70 | * [Intercepting with Charles Proxy](#intercepting-with-charles-proxy) 71 | - [Get decrypted .ipa file](#get-decrypted-ipa-file) 72 | + [With Apple mobile device – Dump](#with-apple-mobile-device--dump-it-with-bagbak-with-extensions-or-frida-ios-dump-cant-dump-extensions-or-any-other-tool) 73 | + [With or without Apple mobile device – Run the hardware AES decryption](#with-apple-mobile-device--run-the-hardware-aes-decryption) 74 | - [Analyze application binaries](#analyze-application-binaries) 75 | * [Tools](#tools) 76 | + [Mach-O Binary Analyzers:](#mach-o-binary-analyzers) 77 | + [Hex Editors](#hex-editors) 78 | + [Disassemblers](#disassemblers) 79 | + [Decompilers](#decompilers) 80 | + [Debuggers](#debuggers) 81 | + [Memory Editors](#memory-editors) 82 | + [Various Command Line Tools](#various-command-line-tools) 83 | * [Disassembling with IDA Pro](#disassembling-with-ida-pro) 84 | * [IDA Pro plugins for iOS and Mach-O](#ida-pro-plugins-for-ios-and-mach-o) 85 | + [Kernelcache analysis](#kernelcache-analysis) 86 | + [Get information about methods](#get-information-about-methods) 87 | + [Retrieving Symbols and Strings](#retrieving--symbols-and-strings) 88 | + [Cross References](#cross-references) 89 | - [ARM64 assembly](#arm64-assembly) 90 | + [Registers](#registers) 91 | + [Register manipulation](#register-manipulation) 92 | + [Memory](#memory) 93 | + [Calling convention](#calling-convention) 94 | + [Conditions](#conditions) 95 | + [Branches](#branches) 96 | + [Miscellaneous](#miscellaneous) 97 | - [iOS tweak development](#ios-tweak-development) 98 | * [Theos](#theos) 99 | * [Logos](#logos) 100 | + [%ctor](#ctor) 101 | + [%dtor](#dtor) 102 | * [Block level](#block-level) 103 | + [%group](#group) 104 | + [%hook](#hook) 105 | + [%new](#new) 106 | + [%subclass](#subclass) 107 | + [%property](#property) 108 | + [%end](#end) 109 | * [Function level](#function-level) 110 | + [%init](#init) 111 | + [%c](#c) 112 | + [%orig](#orig) 113 | + [%log](#log) 114 | * [logify.pl](#logifypl) 115 | * [Logos File Extensions](#logos-file-extensions) 116 | 117 | 118 | 119 | # iOS platform overview 120 | 121 | ## File System 122 | 123 | ### UNIX system directories 124 | 125 | As a conformant UNIX system, OS X works with the well-known directories that are standard on all UNIX flavors: 126 | 127 | - /bin: Unix binaries. This is where the common UNIX commands (for example, ls, rm, mv, df) are 128 | - /sbin: System binaries. These are binaries used for system administration, such as file-system management, network configuration, and so on. 129 | - /usr: The User directory. This is not meant for users, but is more like Windows’ program files in that third-party software can install here. 130 | - /usr: Contains in it bin, sbin, and lib. /usr/lib is used for shared objects (think, Windows DLLs and \windows\system32). This directory also contains the include/ subdirectory, where all the standard C headers are. 131 | - /etc: Et Cetera. A directory containing most of the system configuration files; for example, the password file (/etc/passwd). In OS X, this is a symbolic link to /private/etc. 132 | - /dev: BSD device files. These are special files that represent hardware devices on the system (character and block devices). 133 | - /tmp: Temporary directory. The only directory in the system that is world-writable (permissions: rwxrwxrwx). In OS X, this is a symbolic link to /private/tmp. 134 | - /var: Various. A directory for log files, mail store, print spool, and other data. In OS X, this is a symbolic link to /private/var. 135 | 136 | ### OS X/iOS–specific directories 137 | 138 | OS X adds its own special directories to the UNIX tree, under the system root: 139 | 140 | - /Applications: Default base for all applications in system. 141 | - /Developer: If XCode is installed, the default installation point for all developer tools. 142 | - /Library: Data files, help, documentation, and so on for system applications. 143 | - /Network: Virtual directory for neighbor node discovery and access. 144 | - /System: Used for System files. It contains only a Library subdirectory, but this directory holds virtually every major component of the system, such as frameworks (/System/ Library/Frameworks), kernel modules (/System/Library/Extensions), fonts, and so on. 145 | - /Users: Home directory for users. Every user has his or her own directory created here. 146 | - /Volumes: Mount point for removable media and network file systems. 147 | - /Cores: Directory for core dumps, if enabled. Core dumps are created when a process crashes, if the ulimit(1) command allows it, and contain the core virtual memory image of the process. 148 | 149 | ### iOS File System Idiosyncrasies 150 | 151 | From the file system perspective, iOS is very similar to OS X, with the following differences: 152 | 153 | - The file system (HFSX) is case-sensitive (unlike OS X’s HFS+, which is case preserving, yet insensitive). The file system is also encrypted in part. 154 | - The kernel is already prepackaged with its kernel extensions, as a kernelcache (in /System/Library/Caches/com.apple.kernelcaches). Unlike OS X kernel caches (which are compressed images), iOS kernel caches are encrypted Img3. 155 | - /Applications may be a symbolic link to /var/stash/Applications. This is a feature of the jailbreak, not of iOS. 156 | - There is no /Users, but a /User — which is a symbolic link to /var/mobile 157 | - There is no /Volumes (and no need for it, or for disk arbitration, as iOS doesn’t have any way to add more storage to a given system) 158 | - /Developer is populated only if the i-Device is selected as “Use for development” from within XCode. In those cases, the DeveloperDiskImage.dmg included in the iOS SDK is mounted onto the device. 159 | 160 | ## Applications 161 | 162 | ### ipa file (iOS App Store Package) 163 | 164 | Files with the .ipa extension can be uncompressed by changing the extension to .zip and unzipping. 165 | 166 | ### ipa file contents 167 | 168 |
169 | 170 | ``` 171 | /iTunesArtwork 172 | /iTunesArtwork@2x 173 | /iTunesMetadata.plist 174 | /WatchKitSupport/WK 175 | /META-INF 176 | /Payload/ 177 | /Payload/.app/ 178 | /Payload/.app/ ← Apple FairPlay DRM Encrypted Executable 179 | /Payload/.app/Info.plist A file that contains some of the application specific configurations 180 | /Payload/.app/_CodeSignature/ Contains a plist file with a signature over all files in the bundle 181 | /Payload/.app/Assets.car Another zipped archive that contains assets (icons) 182 | /Payload/.app/Frameworks/ Contains the app native libraries as .dylib or .framework files 183 | /Payload/.app/PlugIns/ May contain app extensions as .appex files 184 | /Payload/.app/Core Data It is used to save permanent data for offline use and sync across iCloud devices 185 | /Payload/.app/PkgInfo An alternate way to specify the type and creator codes of your application or bundle 186 | /Payload/.app/en.lproj, etc Language packs that contains resources for those specific languages 187 | ``` 188 | 189 | ### Application data in iOS filesystem 190 | 191 | ``` 192 | /var/containers/Bundle/Application/ Bundle directory; tampering invalidates signature 193 | /var/mobile/Containers/Data/ Application runtime data 194 | /var/mobile/Containers/Data//Documents/ Contains all the user-generated data 195 | /var/mobile/Containers/Data//Library/ Contains all files that aren't user-specific – caches, preferences, cookies, plist files 196 | /var/mobile/Containers/Data//Library/Caches/ 197 | Contains semi-persistent cached files 198 | /var/mobile/Containers/Data//Library/Application Support/ 199 | Contains persistent files necessary for running the app 200 | /var/mobile/Containers/Data//Library/Preferences/.plist 201 | Properties that can persist after an application is restarted. Contains NSUserDefaults 202 | /var/mobile/Containers/Data//tmp/ Temporary files that do not need to persist between app launches 203 | ``` 204 | 205 | ## Apple plist 206 | 207 | **plist** files are structured XML files that contains **key-value pairs** supporting basic object types, like dictionaries, lists, numbers and strings. Usually the top level object is a dictionary. **plist** can be **binary** or **xml** or **json** file. 208 | 209 | | Abstract type | XML element | Cocoa class | Core Foundation type | 210 | | :---------------------- | :---------------------- | :------------------------------------------------------- | :----------------------------------------------------------- | 211 | | array | `` | `NSArray` | `CFArray` (`CFArrayRef`) | 212 | | dictionary | `` | `NSDictionary` | `CFDictionary` (`CFDictionaryRef`) | 213 | | string | `` | `NSString` | `CFString` (`CFStringRef`) | 214 | | data | `` | `NSData` | `CFData` (`CFDataRef`) | 215 | | date | `` | `NSDate` | `CFDate` (`CFDateRef`) | 216 | | number - integer | `` | `NSNumber` (`intValue`) | `CFNumber` (`CFNumberRef`, integer value) | 217 | | number - floating point | `` | `NSNumber` (`floatValue`) | `CFNumber` (`CFNumberRef`, floating-point value) | 218 | | Boolean | `` or `` | `NSNumber` (`boolValue` == `YES` or `boolValue` == `NO`) | `CFBoolean` (`CFBooleanRef` ; `kCFBooleanTrue` or `kCFBooleanFalse`) | 219 | 220 |
221 | 222 | A standard Info.plist contains the following entries: 223 | 224 | - CFBundleDevelopmentRegion: Default language if no user-specific language can be found. 225 | - CFBundleDisplayName: The name that is used to display this bundle to the user. 226 | - CFBundleDocumentTypes: Document types this will be associated with. This is a dictionary, with the values specifying the file extensions this bundle handles. The dictionary also specifies the display icons used for the associated documents. 227 | - CFBundleExecutable: The actual executable (binary or library) of this bundle. Located in Contents/MacOS. 228 | - CFBundleIconFile: Icon shown in Finder view. 229 | - CFBundleIdentifier: Reverse DNS form. 230 | - CFBundleName: Name of bundle (limited to 16 characters). 231 | - CFBundlePackageType: Specifying a four letter code, for example, APPL = Application, FRMW = Framework, BNDL = Bundle. 232 | - CFBundleSignature: Four-letter short name of the bundle. 233 | - CFBundleURLTypes: URLs this bundle will be associated with. This is a dictionary, with the values specifying which URL scheme to handle, and how. 234 | 235 | ### plutil: 236 | 237 | `plutil -convert xml1 binary_file.plist` 238 | 239 | `plutil -convert xml1 data_file.json -o data_file.plist` 240 | 241 | ### python plistlib: 242 | 243 | [https://docs.python.org/3/library/plistlib.html](https://docs.python.org/3/library/plistlib.html) 244 | 245 | ## Privilege Separation and Sandbox 246 | 247 | Applications the user can access run as the **mobile** user while critical system processes run as **root**. 248 | However, the sandbox allows better control over actions that processes and applications can perform. 249 | 250 | For example, even if two processes run as the same user (mobile), they are **not allowed to access or modify each other's data**. 251 | 252 | Each application is installed under `/var/mobile/Applications/`. **UUID** is random. 253 | Once installed, applications have limited read access to some system areas and functions (SMS, phone call...). If an application wants to access a **protected area,** a **pop-up requesting permission** appears. 254 | 255 |
256 | 257 | ## Data Protection 258 | 259 | App developers can leverage the iOS *Data Protection* APIs to implement **fine-grained access control** for user data stored in flash memory. The APIs are built on top of the **Secure Enclave Processor** (SEP). The SEP is a coprocessor that provides **cryptographic operations for data protection and key management**. A device-specific hardware key-the **device UID** (Unique ID)-is **embedded in the secure enclave**, ensuring the integrity of data protection even when the operating system kernel is compromised. 260 | 261 | When a file is created on the disk, a new 256-bit AES key is generated with the help of secure enclave's hardware based random number generator. The content of the file is then encrypted with the generated key. And then, this key is saved encrypted with a class key along with the class ID, with both data encrypted by the system's key, inside the metadata of the file. 262 | 263 |
264 | 265 | For decrypting the file, the metadata is decrypted using the system's key. Then using the class ID the class key is retrieved to decrypt the per-file key and decrypt the file. 266 | 267 | Files can be assigned to one of four different protection classes, which are explained in more detail in the [iOS Security Guide](https://www.apple.com/business/docs/iOS_Security_Guide.pdf). 268 | 269 | ## App Capabilities 270 | 271 | **Each app has a unique home directory and is sandboxed**, so that they cannot access protected system resources or files stored by the system or by other apps. These restrictions are implemented via sandbox policies (aka. *profiles*), which are enforced by the [Trusted BSD (MAC) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html) via a kernel extension. 272 | 273 | Some **[capabilities/permissions](https://help.apple.com/developer-account/#/dev21218dfd6)** can be configured by the app's developers (e.g. Data Protection or Keychain Sharing) and will directly take effect after the installation. However, for others, **the user will be explicitly asked the first time the app attempts to access a protected resource**. 274 | 275 | *[Purpose strings](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy/accessing_protected_resources?language=objc#3037322)* or *usage description strings* are custom texts that are offered to users in the system's permission request alert when requesting permission to access protected data or resources. 276 | 277 |
278 | 279 | If having the original source code, you can verify the permissions included in the `Info.plist` file: 280 | 281 | - Open the project with Xcode. 282 | - Find and open the `Info.plist` file in the default editor and search for the keys starting with `"Privacy -"`. 283 | 284 | You may switch the view to display the raw values by right-clicking and selecting "Show Raw Keys/Values" (this way for example `"Privacy - Location When In Use Usage Description"` will turn into `NSLocationWhenInUseUsageDescription`). 285 | 286 | If only having the IPA: 287 | 288 | - Unzip the IPA. 289 | - The `Info.plist` is located in `Payload/.app/Info.plist`. 290 | - Convert it if needed (e.g. `plutil -convert xml1 Info.plist`) as explained in the chapter "iOS Basic Security Testing", section "The Info.plist File". 291 | - Inspect all *purpose strings Info.plist keys*, usually ending with `UsageDescription`: 292 | 293 | ``` 294 | 295 | 296 | NSLocationWhenInUseUsageDescription 297 | Your location is used to provide turn-by-turn directions to your destination. 298 | 299 | ``` 300 | 301 | ## Device Capabilities 302 | 303 | Device capabilities are used by the App Store to ensure that only compatible devices are listed and therefore are allowed to download the app. They are specified in the `Info.plist` file of the app under the `[UIRequiredDeviceCapabilities](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/plist/info/UIRequiredDeviceCapabilities)` key. 304 | 305 | ``` 306 | UIRequiredDeviceCapabilities 307 | 308 | armv7 309 | 310 | 311 | ``` 312 | 313 | Typically you'll find the armv7 capability, meaning that the app is compiled only for the armv7 instruction set, or if it’s a 32/64-bit universal app. 314 | 315 | For example, an app might be completely dependent on NFC to work (e.g. a ["NFC Tag Reader"](https://itunes.apple.com/us/app/nfc-taginfo-by-nxp/id1246143596) app). According to the [archived iOS Device Compatibility Reference](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html), NFC is only available starting on the iPhone 7 (and iOS 11). A developer might want to exclude all incompatible devices by setting the `nfc` device capability. 316 | 317 | ## Entitlements 318 | 319 | Entitlements are key value pairs that are signed in to an app and allow authentication beyond runtime factors, like UNIX user ID. Since entitlements are digitally signed, they can’t be changed. Entitlements are used extensively by system apps and daemons to perform specific privileged operations that would otherwise require the process to run as root. This greatly reduces the potential for privilege escalation by a compromised system app or daemon. 320 | 321 | For example, if you want to set the "Default Data Protection" capability, you would need to go to the **Capabilities** tab in Xcode and enable **Data Protection**. This is directly written by Xcode to the `.entitlements` file as the `com.apple.developer.default-data-protection` entitlement with default value `NSFileProtectionComplete`. In the IPA we might find this in the `embedded.mobileprovision` as: 322 | 323 | ``` 324 | Entitlements 325 | 326 | ... 327 | com.apple.developer.default-data-protection 328 | NSFileProtectionComplete 329 | 330 | 331 | ``` 332 | 333 | For other capabilities such as HealthKit, the user has to be asked for permission, therefore it is not enough to add the entitlements, special keys and strings have to be added to the `Info.plist` file of the app. 334 | 335 | ## Application security features, Apple FairPlay DRM 336 | 337 | 1. The applications need to be signed with a paid Apple developer certificate. 338 | 2. The application binaries are encrypted using **Apple FairPlay DRM**. A form of DRM exists in the IPA to control redistribution to a single Apple ID. Later we'll see how to remove it. 339 | 3. The applications are protected by code signing. 340 | 4. Patched applications cannot be installed on non-jailbroken devices. 341 | 5. Every iOS application runs in its own sandbox. After iOS 8.3+, this sandboxed data cannot be accessed without jailbreaking the iOS device. 342 | 6. No application can access data belonging to another application. Protocol handlers like URL schemes are the only way for inter-application communication to be used for message passing between applications. The data can also be stored in keychains. 343 | 7. Whenever new files are created on the iOS device, they are assigned data protection classes as specified by the developers. This helps put access restriction on these files. 344 | 8. Applications need to specifically request for permission from the user to access resources like Camera, Maps, Contacts, etc. 345 | 9. iOS devices 5s+ have a secure hardware component called Secure Enclave. It is a highlyoptimized version of ARM’s TrustZone and prevents the main processor from directly accessing sensitive data. 346 | 347 | ## Secure Enclave Processor 348 | 349 | The **Secure Enclave** is part of the A7 and newer SoCs used for data protection, Touch ID and Face ID. The purpose of the Secure Enclave is to handle keys and other info such as biometrics that is sensitive enough to not be handled by the Application Processor. It is isolated with a hardware filter so the AP cannot access it. It shares RAM with the AP, but its portion of the RAM — TZ0 is encrypted. The secure enclave itself is a flashable 4MB AKF processor core called the secure enclave processor (SEP). The technology used is similar to [ARM's TrustZone/SecurCore](http://www.arm.com/products/processors/technologies/trustzone/index.php) but contains proprietary code for Apple KF cores in general and SEP specifically. 350 | 351 | ## AES Keys 352 | 353 | The SoC in each device have an AES coprocessor with the **GID Key** and **UID Key** built in. 354 | 355 | The device’s unique ID (UID) and a device group ID (GID) are AES 256-bit keys fused (UID) or compiled (GID) into the application processor during manufacturing. No software or firmware can read them directly; they can see only the results of encryption or decryption operations performed using them. The UID is unique to each device and is not recorded by Apple or any of its suppliers. The GID is common to all processors in a class of devices and is used as an additional level of protection when delivering system software during installation and restore. Integrating these keys into the silicon helps prevent them from being tampered with or bypassed, or accessed outside the AES engine. 356 | 357 | ### GID Key 358 | 359 | The **GID key** (**Group ID key**) is a 256-bit AES key shared by all devices with the same application processor. The GID key is part of how iOS encrypts software on the device. This is one component of the iOS security system, which also includes [SHSH](https://www.theiphonewiki.com/wiki/SHSH) signatures. This key is different on each Apple SoC model. 360 | 361 | **The GID Key has so far not been extracted from any device, so the only way to use it is by going through the AES engine itself.** 362 | 363 | - But 364 | 365 | GID **can be obtained** through the expensive Cold Boot Attack procedure ([https://en.m.wikipedia.org/wiki/Cold_boot_attack](https://en.m.wikipedia.org/wiki/Cold_boot_attack)) and the next no less expensive procedure of scanning the SoC with an electron-beam lithographer Raith CHIPSCANNER ([https://minateh.ru/equipment/technological/e-beam-lithography/](https://minateh.ru/equipment/technological/e-beam-lithography/)). Such experiment is unjustifiably expensive and complex, so it never occurred to anyone to try to implement it except for the private laboratory Cellebrite. Cellebrite does not share its research. 366 | 367 | ### UID Key 368 | 369 | The **UID key** (**device's Unique ID key**) is an AES 256-bit hardware key, unique to each iPhone. 370 | 371 | ### Derived keys 372 | 373 | Some derived keys are computed by the IOAESAccelerator kernel service at boot. These keys are generated by encrypting static values either with the UID key (0x7D0 identifier) or the GID key (0x3E8 identifier). 374 | 375 | **Key 0x835** – Generated by encrypting `0x01010101010101010101010101010101` with the UID-key. Used for data protection. 376 | 377 | **Key 0x836** – Generated by encrypting `0x00E5A0E6526FAE66C5C1C6D4F16D6180` with the UID-key. This is computed by the kernel during a restore, but is zeroed out during a normal boot. It is also computed by the Secure Bootloader, and its only known use is to decrypt LLB in NOR. Like **0x835**, it is different for each device. 378 | 379 | **Key 0x837** – Generated by encrypting `0x345A2D6C5050D058780DA431F0710E15` with the [S5L8900](https://www.theiphonewiki.com/wiki/S5L8900) GID Key, resulting in `0x188458A6D15034DFE386F23B61D43774`. It is used as the encryption key for [IMG2 files](https://www.theiphonewiki.com/wiki/S5L_File_Formats#IMG2). With the introduction of [IMG3](https://www.theiphonewiki.com/wiki/IMG3_File_Format) in iPhone OS 2.0, [KBAGs](https://www.theiphonewiki.com/wiki/KBAG) are now used instead of the **0x837** key. Because iPhone OS versions 1.x were used only on the [iPhone](https://www.theiphonewiki.com/wiki/M68AP) and [iPod touch](https://www.theiphonewiki.com/wiki/N45AP) (both use the [S5L8900](https://www.theiphonewiki.com/wiki/S5L8900)) the encrypted values for other processors don't matter. 380 | 381 | **Key 0x838** – Generated by encrypting `0x8C8318A27D7F030717D2B8FC5514F8E1` with the UID-key. Another UID-AES-key-based key, it is used to encrypt everything but LLB in the NOR (iBoot, DeviceTree, pictures). 382 | 383 | **Key 0x899** – Generated by encrypting `0xD1E8FCB53937BF8DEFC74CD1D0F1D4B0` with the UID-key. Usage unknown. 384 | 385 | **Key 0x89A** – Generated by encrypting `0xDB1F5B33606C5F1C1934AA66589C0661` with the UID-key, getting a device-specific key. Used on A4 devices. It is used to encrypt the [SHSH](https://www.theiphonewiki.com/wiki/SHSH) blobs on the device. 386 | 387 | **Key 0x89B** – Generated by encrypting `0x183E99676BB03C546FA468F51C0CBD49` with the UID-key. It is used to encrypt the data partition key. 388 | 389 | **Key 0x8A3** – Generated by encrypting `0x568241656551e0cdf56ff84cc11a79ef` with the UID-key (using AES-256-CBC). It is used during software upgrades on A12 and later to encrypt the "generator" value (using AES-128-CBC) before hashing it to become the nonce. 390 | 391 | More info: 392 | [https://css.csail.mit.edu/6.858/2020/readings/ios-security-may19.pdf](https://css.csail.mit.edu/6.858/2020/readings/ios-security-may19.pdf) 393 | [https://www.securitylab.ru/contest/428454.php](https://www.securitylab.ru/contest/428454.php) 394 | [https://www.securitylab.ru/contest/429973.php](https://www.securitylab.ru/contest/429973.php) 395 | 396 | ## Objective-C Basics 397 | 398 | Objective-C module files have the “.m” extension (if a mix of C++ and Objective-C was used, the “.mm” extension). Header files - “.h”. All objects of classes created in Objective-C must be allocated in heap. Therefore, the id type, which is a pointer to an object of any class (in fact, void \*), acquires special significance. A null pointer is referred to as the constant nil. Thus, a pointer to any class can be cast to the id type. A problem arises: how to find out which class the object hiding under id belongs to? This is done thanks to the isa invariant, which is present in any object of a class that inherits a special base class NSObject (the NS prefix stands for NeXT Step). The isa invariant is of the reserved type Class. An object of this type allows you to find out the names of its own and the base class, a set of class invariants, as well as the prototypes of all methods that this object has implemented and their addresses (through a local list of selectors). All Objective-C reserved words other than C reserved words begin with an @ symbol (eg @protocol, @selector, @interface). Typically, the names of scoped class invariants (@private, @protected) begin with an underscore. For strings, Cocoa has a very handy NSString class. The string constant of this class is written as @"Hello world", and not as the usual C string constant "Hello world". The BOOL type (essentially unsigned char) can take the constant values YES and NO. All Objective-C-specific reserved words (which differ from the C language and are found in the header file objc/objc.h) are listed below: 399 | 400 | `@interface` Starts declaring a class or category (category is class extension without inheritance) 401 | `@end` Completes the declaration\definition of any class, category or protocol 402 | `@private` Limits the scope of class invariants to class methods (similar to C++) 403 | `@protected` Stands by default. Limits the scope of class invariants to class methods and methods of derived classes (similar to C++) 404 | `@public` Removes scoping restrictions (similar to C++) 405 | `@try` Defines a block with possible exception throwing (similar to C++) 406 | `@throw` Throws an exception object (similar to C++) 407 | `@catch()` Handles the exception thrown in the preceding @try block (similar to C++) 408 | `@finally` Defines the block after the @try block to which control is passed regardless of whether an exception was thrown or not 409 | `@class` Abbreviated form of class declaration (name only (similar to C++)) 410 | `@selector(method_name)` Returns the compiled selector for the method name method_name 411 | `@protocol(protocol_name)` Returns an instance of the protocol class named `protocol_name` 412 | `@encode(type_spec)` Initializes a character string that will be used to encrypt data of type `type_spec` 413 | `@synchronized()` Defines a block of code executed by only one thread at any given point in time 414 | `@implementation` Starts defining a class or category 415 | `@protocol` Begins a protocol declaration (analogous to a C++ class consisting of pure virtual functions) 416 | 417 | ### Message exchange 418 | 419 | To force an object to execute a method, you need to send it a message named the same as the required method. This message is called a method selector. The syntax for sending is as follows: 420 | 421 | `[receiver method];` 422 | 423 | ### Method declaration 424 | 425 | `- (void) addObject: (id) otherObject;` 426 | 427 | If you put a plus sign `+` at the beginning of a method prototype, then such a method will be considered a class method and, naturally, will not accept the implicit self parameter (this is similar to declaring a static method in C++). And without the isa invariant of the object pointed to by self, the super pointer, of course, will not work either. 428 | Thus, the prototype of any method is declared like this: 429 | 430 | ``` 431 | - | + () mainMethodNamePart 432 | [: () nameOfFirstFormalParameter 433 | [[optionalMethodNamePart]: () secondFormalParameterName] ... 434 | ] 435 | ``` 436 | 437 | For example: 438 | 439 | `+ (Class)class;` 440 | `+ (id)alloc;` 441 | `- (id)init;` 442 | `- (void)addObject: (id)anObject;` 443 | `+ (NSString *)stringWithCString: (const char*)aCString usingUncoding: (enum NSStringEncoding)encoding;` 444 | `- (NSString *)initStringWithFormat: (NSString *)format, ...;` 445 | 446 | ## iOS Frameworks 447 | 448 | - Bluetooth peripherals 449 | - Calendar data 450 | - Camera 451 | - Contacts 452 | - Health sharing 453 | - Health updating 454 | - HomeKit 455 | - Location 456 | - Microphone 457 | - Motion 458 | - Music and the media library 459 | - Photos 460 | - Reminders 461 | - Siri 462 | - Speech recognition 463 | - the TV provider 464 | - etc 465 | 466 | ### Official documentation 467 | 468 | [Apple Developer Documentation](https://developer.apple.com/documentation/technologies) 469 | 470 | ### Official list 471 | 472 | https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemFrameworks/SystemFrameworks.html 473 | 474 | ### Full list 475 | 476 | https://www.theiphonewiki.com/wiki//System/Library/Frameworks 477 | 478 | ### Where are they stored 479 | 480 | Frameworks are stored in several locations on the file system: 481 | 482 | - /System/Library/Frameworks. Contains Apple’s supplied frameworks — both in iOS and OS X 483 | - /Network/Library/Frameworks may (rarely) be used for common frameworks installed on the network. 484 | - /Library/Frameworks holds 3rd party frameworks (and, as can be expected, the directory is left empty on iOS) 485 | - \~/Library/Frameworks holds frameworks supplied by the user, if any 486 | 487 | Additionally, applications may include their own frameworks. 488 | 489 | ## iOS Network Frameworks 490 | 491 | [Apple Developer Documentation – Network](https://developer.apple.com/documentation/network) 492 | 493 | [Apple Developer Documentation – NetworkExtension](https://developer.apple.com/documentation/networkextension) 494 | 495 | [Apple Developer Documentation – NetworkingDriverKit](https://developer.apple.com/documentation/networkingdriverkit) 496 | 497 | ### Network Communication 498 | 499 | Most of the apps you might encounter connect to remote endpoints. Even before you perform any dynamic analysis (e.g. traffic capture and analysis), you can obtain some initial inputs or entry points by enumerating the domains to which the application is supposed to communicate to. 500 | 501 | Typically these domains will be present as strings within the binary of the application. One can extract domains by retrieving strings with `rabin2 -zz ` or in the IDA Pro. The latter option has a clear advantage: it can provide you with context, as you'll be able to see in which context each domain is being used by checking the cross-references. 502 | 503 | From here on you can use this information to derive more insights which might be of use later during your analysis, e.g. you could match the domains to the pinned certificates or perform further reconnaissance on domain names to know more about the target environment. 504 | 505 | The implementation and verification of secure connections can be an intricate process and there are numerous aspects to consider. For instance, many applications use other protocols apart from HTTP such as XMPP or plain TCP packets, or perform certificate pinning in an attempt to deter MITM attacks. 506 | 507 | ### Network Framework 508 | 509 | The Network framework was introduced at [The Apple Worldwide Developers Conference (WWDC)](https://developer.apple.com/videos/play/wwdc2018/715) in 2018 and is a replacement to the Sockets API. This low-level networking framework provides classes to send and receive data with built in dynamic networking, security and performance support. 510 | 511 | TLS 1.3 is enabled by default in the Network framework, if the argument `using: .tls` is used. It is the preferred option over the legacy [Secure Transport](https://developer.apple.com/documentation/security/secure_transport) framework. 512 | 513 | ### URLSession 514 | 515 | `URLSession` was built upon the Network framework and utilizes the same transport services. The class also uses TLS 1.3 by default, if the endpoint is HTTPS. 516 | 517 | `URLSession` should be used for HTTP and HTTPS connections, instead of utilizing the Network framework directly. The class natively supports both URL schemes and is optimized for such connections. It requires less boilerplate code, reducing the propensity for errors and ensuring secure connections by default. The Network framework should only be used when there are low-level and/or advanced networking requirements. 518 | 519 | The official Apple documentation includes examples of using the Network framework to [implement netcat](https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework) and `URLSession` to [fetch website data into memory](https://developer.apple.com/documentation/foundation/url_loading_system/fetching_website_data_into_memory). 520 | 521 | ## iOS Private Frameworks 522 | 523 | ### Dumped headers 524 | 525 | https://developer.limneos.net/ 526 | 527 | ### Full list 528 | 529 | https://www.theiphonewiki.com/wiki//System/Library/PrivateFrameworks 530 | 531 | 532 | # Tools overview 533 | 534 | ## How to jailbreak 535 | 536 | Latest tool for your device can be found here [https://canijailbreak.com](https://canijailbreak.com/) 537 | 538 | This research is basically written for checkra1ned iPhones 5s through X with iOS 10–15 and can be updated in a long term if a new bootrom pwnage tool will be released. Check it out [https://www.theiphonewiki.com/wiki/Bootrom#Bootrom_Exploits](https://www.theiphonewiki.com/wiki/Bootrom#Bootrom_Exploits) 539 | 540 | ## How to install cydia package 541 | 542 | ### Using cydia – easiest way without troubles 543 | 544 | 1. Add to cydia sources related repo (`https://repo.chariz.com` for example) 545 | 2. Search for a package and install 546 | 3. If you don't see changes or something doesn't work run `killall SpringBoard` 547 | In most cases restarting SpringBoard is required 548 | 549 | ### With .deb package or .ipa file 550 | 551 | Open .deb/.ipa file with [Filza File Manager](http://cydia.saurik.com/package/com.tigisoftware.filza/) and press Install, if you see an error with .deb installation try to find and install all dependencies 552 | 553 | ### In order to install any .ipa file 554 | 555 | Install **AppSync Unified** from `https://cydia.akemi.ai/` repo 556 | 557 | ### Add this repos to your cydia: 558 | 559 | `https://apt.bingner.com/` 560 | `https://apt.thebigboss.org/repofiles/cydia/` 561 | `https://cydia.saurik.com` 562 | `https://repo.dynastic.co/` 563 | `https://getdelta.co/` 564 | `https://cokepokes.github.io/` 565 | `https://cydia.akemi.ai/` 566 | `https://nscake.github.io/` 567 | `https://repo.chariz.com/` 568 | `https://mrepo.org/` 569 | `https://rejail.ru/` 570 | `https://repo.hackyouriphone.org/` 571 | `https://build.frida.re/` — frida 572 | `https://cydia.radare.org/` — radare2 573 | 574 | ## Access device 575 | 576 | Install on desktop 577 | 578 | `brew install libimobiledevice ideviceinstaller libirecovery` 579 | 580 | `sudo port install idevicerestore` 581 | 582 | ### libimobiledevice: 583 | 584 | `idevice_id` List attached devices or print device name of given device 585 | `idevicebackup` Create or restore backup for devices (legacy) 586 | `idevicebackup2` Create or restore backups for devices running iOS 4 or later 587 | `idevicecrashreport` Retrieve crash reports from a device 588 | `idevicedebug` Interact with the debugserver service of a device 589 | `idevicedebugserverproxy` Proxy a debugserver connection from a device for remote debugging 590 | `idevicediagnostics` Interact with the diagnostics interface of a device 591 | `ideviceenterrecovery` Make a device enter recovery mode 592 | `ideviceimagemounter` Mount disk images on the device 593 | `ideviceinfo` Show information about a connected device 594 | `idevicename` Display or set the device name 595 | `idevicepair` Manage host pairings with devices and usbmuxd 596 | `idevicescreenshot` Gets a screenshot from the connected device 597 | `idevicesetlocation` Simulate location on device 598 | `idevicesyslog` Relay syslog of a connected device 599 | 600 | ### ideviceinstaller: 601 | 602 | `ideviceinstaller --list-apps` 603 | `ideviceinstaller --install ` 604 | `ideviceinstaller --uninstall ` 605 | `idevicedebug -d run ` 606 | 607 | ### libirecovery: 608 | 609 | `irecovery --shell` Allows communication with iBoot/iBSS of iOS device 610 | 611 | ### idevicerestore: 612 | 613 | `idevicerestore --latest` Restore a new firmware to a device 614 | `idevicerestore --erase --latest` 615 | Force restoring with erasing all data 616 | 617 | ### libusbmuxd: 618 | 619 | `inetcat` Utility to expose a raw connection to the device 620 | `iproxy 2222:22` Bind local port 2222 and forward to 22 of the first USB device 621 | 622 | ## Access filesystem 623 | 624 | ### On desktop 625 | 626 | Install on device [Apple File Conduit "2"](https://cydia.saurik.com/package/com.saurik.afc2d) 627 | 628 | Use iMazing or iFunBox to access filesystem 629 | 630 | ### On device 631 | 632 | Install [Filza File Manager](http://cydia.saurik.com/package/com.tigisoftware.filza/) 633 | 634 |
635 | 636 | ## Access command line 637 | 638 | ### On desktop 639 | 640 | Install [**OpenSSH**](https://cydia.saurik.com/openssh.html) on device and run on desktop: 641 | 642 | `iproxy 2222:22` 643 | 644 | `ssh -p 2222 root@localhost` 645 | 646 | Default iOS password for `root` is `alpine`. Don't change it if you have a bad memory 647 | 648 | ### On device 649 | 650 | Install on device [**NewTerm 2**](https://4pda.to/forum/index.php?showtopic=947025) from `https://repo.chariz.com` to use local terminal 651 | 652 |
653 | 654 | ## Persisted data 655 | 656 | #### Inspect App bundle 657 | 658 | ``` 659 | cd /private/var/containers/Bundle/Application//myapp.app 660 | // Contains compiled code, statically linked files, compressed NIB files. 661 | ``` 662 | 663 | #### Inspect sandboxed data 664 | 665 | ``` 666 | cd /private/var/mobile/Containers/Data/Application/ 667 | ls -lrt // Your freshly installed IPA is at the bottom of list 668 | cd [app guid]/Documents/ 669 | cd [app guid]/Library/ 670 | ``` 671 | 672 | #### Databases to pull off a device 673 | 674 | ``` 675 | /private/var/Keychains 676 | TrustStore.sqlite3 677 | keychain-2.db 678 | pinningrules.sqlite3 679 | ``` 680 | 681 | #### File sharing 682 | 683 | ``` 684 | // Extract IPA (whether App Store encrypted or not) 685 | scp -r -P 2222 root@localhost:/var/containers/Bundle/Application//hitme.app ~/hitme.app 686 | 687 | // Different to SSH, the uppercase P for Port with SCP. Order important. 688 | scp -P 2222 root@localhost:/var/root/overflow.c localfilename.c 689 | 690 | // from Jailbroken device to local machine 691 | // Caution:no space after the root@localhost: Otherwise you copy the entire filesystem! 692 | scp -P 2222 root@localhost:/private/var/mobile/Containers/Data/Application//Library/Caches/Snapshots/com.my.app 693 | 694 | // from local machine to remote Jailbroken device 695 | scp -P 2222 hello.txt root@localhost:/var/root/ 696 | ``` 697 | 698 | ## View application layout and more 699 | 700 | Install **libFLEX** and **FLEXing** from `https://nscake.github.io/` 701 | 702 | Open NewTerm and run `killall SpringBoard` 703 | 704 | Now you can load FLEX inside any application by longpress on the statusbar 705 | 706 |
707 | 708 | 709 | 710 | 711 | 712 | 713 |
714 | 715 | # Analyze application at runtime 716 | 717 | ## Frida 718 | 719 | Frida is a dynamic binary instrumentation toolkit that allows us to execute scripts in previously locked down software. In a nutshell, Frida lets you inject snippets of JavaScript into native apps on Windows, Mac, Linux, iOS and Android. 720 | 721 | ### Install frida server: 722 | 723 | Add frida repo to the cydia – `https://build.frida.re/` 724 | - If you have 32-bit device with Apple A6 or lower (iPhone 5, iPhone 5C, iPad 2 and earlier) install **Frida for 32-bit devices** 725 | - If you have 64-bit device with Apple A11 or lower (iPhone X, iPad 7, iPod Touch 7 and earlier) install **Frida** 726 | - On a newer device you can install **Frida for A12+ devices** 727 | 728 | ### Install frida on desktop 729 | 730 | If you don't have Python 3: 731 | 732 | `brew install pyenv` 733 | `pyenv install 3.9.0` (or the latest available) 734 | 735 | Then install 736 | 737 | `pip3 install frida-tools` 738 | 739 | ### frida: 740 | 741 | `frida-ls-devices` List available devices 742 | `frida-ps -U` List all running processes names and PIDs on a USB device 743 | `frida-ps -Uai` List all installed apps on a USB device 744 | `frida-ps -Ua` List all running apps on a USB device 745 | `frida-ls-devices` List all attached devices 746 | `frida-ps -D 0216027d1d6d3a03` Connect Frida to the specific device 747 | `frida-discover` Tool for discovering internal functions in a process 748 | `frida-trace -U Twitter -i "*URL*"` Tracing native APIs 749 | `frida-trace -U -f com.toyopagroup.picaboo -I "libcommonCrypto*"` 750 | Launch the app and trace crypto API calls 751 | `frida-trace -U Twitter -m "-[NSURL* *HTTP*]"` Tracing Objective-C APIs 752 | `frida -U -n Twitter -l inject.js` Inject **script** into process on a USB device via REPL 753 | `frida -n cat` Connect to cat by name 754 | `frida -f foobar` Force open foobar 755 | `frida -U -f foobar --no-pause` Open foobar over usb and force start. starts app running 756 | `frida-ps -U | grep -i myapp` Get the target app's process ID from USB connected device 757 | `frida -U -f foobar --no-pause -q --eval 'console.log("Hi Frida");'` 758 | Run script and quit Frida 759 | 760 | ### **Calling a Native Function** 761 | 762 | At this point we have our `NativeFunction` stored in the `play_sound` variable. Call it just like a regular function `play_sound()` and also remember to give the (`int`) input parameter: `play_sound(1007)` 763 | 764 | Putting it all together: 765 | 766 | `var address = Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound')` 767 | `var play_sound = new NativeFunction(address, 'void', ['int'])` 768 | `play_sound(1007)` 769 | 770 | You have to get an instance of the object first, either: 771 | 772 | - allocating it and calling its constructor, for example `var instance = ObjC.classes.ClassName.alloc().init();` 773 | - getting an existing instance using `ObjC.choose`, like - if you know there's only one instance already created somewhere on the heap - you can to something like `var instance = ObjC.chooseSync(ObjC.classes.ClassName)[0];` 774 | - getting an existing instance from a singleton you know holds the instance in a property, for example `var instance = ObjC.classes.MySingleton.getInstance().myInterestingInstance();` 775 | 776 | and then call the method on the instance: 777 | 778 | `instance.setSomething();` 779 | 780 | or, if the method signature takes an argument, like `- setSomething:`, you can also pass the argument (just remember to put a `_` instead of ObjC's `:`): 781 | 782 | `instance.setSomething_(argument);` 783 | 784 | ## Frida basics 785 | 786 | ``` 787 | frida -U "My App" // Attach Frida to app over USB 788 | 789 | Process.id 790 | 419 791 | 792 | Process.getCurrentThreadId() 793 | 3843 794 | 795 | var b = "hello frida" 796 | 797 | console.log(b) 798 | "hello frida" 799 | 800 | c = Memory.allocUtf8String(b) 801 | "0x1067ec510" 802 | 803 | Memory.readUtf8String(c) 804 | "hello frida" 805 | 806 | console.log(c) 807 | 0x1067ec510 808 | 809 | console.log(c.readUtf8String(5)) 810 | hello 811 | 812 | console.log(c.readUtf8String(11)) 813 | hello frida 814 | 815 | ptrToC = new NativePointer(c); 816 | "0x1067ec510" 817 | 818 | console.log(ptrToC) 819 | 0x1067ec510 820 | 821 | console.log(ptrToC.readCString(8)) 822 | hello fr 823 | 824 | Memory.readUtf8String(ptrToC) 825 | "hello frida" 826 | ``` 827 | 828 | #### Frida - Objective-C 829 | 830 | Objective-C's syntax includes the `:` and `@` characters. These characters were not used in the `Frida Javascript API`. 831 | 832 | ``` 833 | // Attach to playground process ID 834 | frida -p $(ps -ax | grep -i -m1 playground |awk '{print $1}') 835 | 836 | ObjC.available 837 | true 838 | 839 | ObjC.classes.UIDevice.currentDevice().systemVersion().toString() 840 | "11.1" 841 | 842 | ObjC.classes.NSBundle.mainBundle().executablePath().UTF8String() 843 | 844 | ObjC.classes.UIWindow.keyWindow().toString() 845 | RET: 846 | 847 | // shows Static Methods and Instance Methods 848 | ObjC.classes.NSString.$ownMethods 849 | 850 | ObjC.classes.NSString.$ivars 851 | 852 | var myDate = ObjC.classes.NSDate.alloc().init() 853 | 854 | console.log(myDate) 855 | 2019-04-19 19:03:46 +0000 856 | 857 | myDate.timeIntervalSince1970() 858 | 1555700626.021566 859 | 860 | myDate.description().toString() 861 | "2019-04-19 19:03:46 +0000" 862 | 863 | var a = ObjC.classes.NSUUID.alloc().init() 864 | 865 | console.log(a) 866 | 4645BFD2-94EE-413D-9CE5-8982D41ED6AE 867 | 868 | a.UUIDString() 869 | { 870 | "handle": "0x7ff3b2403b20" 871 | } 872 | a.UUIDString().toString() 873 | "4645BFD2-94EE-413D-9CE5-8982D41ED6AE" 874 | ``` 875 | 876 | #### NSString 877 | 878 | ``` 879 | var b = ObjC.classes.NSString.stringWithString_("foo"); 880 | 881 | b.isKindOfClass_(ObjC.classes.NSString) 882 | true 883 | 884 | b.isKindOfClass_(ObjC.classes.NSUUID) 885 | false 886 | 887 | b.isEqualToString_("foo") 888 | true 889 | 890 | b.description().toString() 891 | "foo" 892 | 893 | var c = ObjC.classes.NSString.stringWithFormat_('foo ' + 'bar ' + 'lives'); 894 | 895 | console.log(c) 896 | foo bar lives 897 | ``` 898 | 899 | #### NSURL 900 | 901 | ``` 902 | var url = ObjC.classes.NSURL.URLWithString_('www.foobar.com') 903 | 904 | console.log(url) 905 | www.foobar.com 906 | 907 | url.isKindOfClass_(ObjC.classes.NSURL) 908 | true 909 | 910 | console.log(url.$class) 911 | NSURL 912 | ``` 913 | 914 | #### Frida from NSString to NSData back to Hex String 915 | 916 | ``` 917 | var b = ObjC.classes.NSString.stringWithString_("foo"); 918 | 919 | var d = ObjC.classes.NSData 920 | d = b.dataUsingEncoding_(1) // NSASCIIStringEncoding = 1, NSUTF8StringEncoding = 4, 921 | 922 | console.log(d) 923 | <666f6f> // This prints the Hex value "666f6f = foo" 924 | 925 | d.$className 926 | "NSConcreteMutableData" 927 | 928 | var x = d.CKHexString() // Get you the Byte array as a Hex string 929 | 930 | console.log(x) 931 | 666f6f 932 | 933 | x.$className 934 | "NSTaggedPointerString" 935 | 936 | var newStr = ObjC.classes.NSString.stringWithUTF8String_[d.bytes] 937 | ``` 938 | 939 | #### Frida with xCode Simulator 940 | 941 | ``` 942 | // demoapp is the iOS app name 943 | myapp=$(ps x | grep -i -m1 demoapp | awk '{print $1}') 944 | frida-trace -i "getfsent*" -p $myapp 945 | 946 | // Connect to process with Frida script 947 | frida --codeshare mrmacete/objc-method-observer -p 85974 948 | ``` 949 | 950 | #### Frida find Modules 951 | 952 | ``` 953 | Process.enumerateModules() 954 | // this will print all loaded Modules 955 | 956 | Process.findModuleByName("libboringssl.dylib") 957 | { 958 | "base": "0x1861e2000", 959 | "name": "libboringssl.dylib", 960 | "path": "/usr/lib/libboringssl.dylib", 961 | "size": 712704 962 | } 963 | 964 | Process.findModuleByAddress("0x1c1c4645c") 965 | { 966 | "base": "0x1c1c2a000", 967 | "name": "libsystem_kernel.dylib", 968 | "path": "/usr/lib/system/libsystem_kernel.dylib", 969 | "size": 200704 970 | } 971 | ``` 972 | 973 | #### Find Address and Module of function name (Export) 974 | 975 | ``` 976 | DebugSymbol.fromAddress(Module.findExportByName(null, 'strstr')) 977 | { 978 | "address": "0x183cb81e8", 979 | "fileName": "", 980 | "lineNumber": 0, 981 | "moduleName": "libsystem_c.dylib", 982 | "name": "strstr" 983 | } 984 | ``` 985 | 986 | #### Find Address of Export and use Address to find Module 987 | 988 | ``` 989 | Module.findExportByName(null, 'strstr') 990 | "0x183cb81e8" 991 | 992 | Module.getExportByName(null,'strstr') 993 | "0x183cb81e8" 994 | 995 | Process.findModuleByAddress("0x183cb81e8") 996 | { 997 | "base": "0x183cb6000", 998 | "name": "libsystem_c.dylib", 999 | "path": "/usr/lib/system/libsystem_c.dylib", 1000 | "size": 516096 1001 | } 1002 | ``` 1003 | 1004 | #### Exports inside a Module 1005 | 1006 | ``` 1007 | a = Process.findModuleByName("Reachability") 1008 | a.enumerateExports() 1009 | .... 1010 | { 1011 | "address": "0x102fab020", 1012 | "name": "ReachabilityVersionString", 1013 | "type": "variable" 1014 | }, 1015 | { 1016 | "address": "0x102fab058", 1017 | "name": "ReachabilityVersionNumber", 1018 | "type": "variable" 1019 | } 1020 | .... 1021 | ... 1022 | .. 1023 | ``` 1024 | 1025 | ## Frida's --eval flag 1026 | 1027 | #### Enumerate all Exports, grepping for one function, and quit 1028 | 1029 | ``` 1030 | frida -U -f funky-chicken.debugger-challenge --no-pause -q --eval 'var x={};Process.enumerateModulesSync().forEach(function(m){x[m.name] = Module.enumerateExportsSync(m.name)});' | grep -B 1 -A 1 task_threads 1031 | 1032 | "address": "0x1c1c4645c", 1033 | "name": "task_threads", 1034 | "type": "function" 1035 | ``` 1036 | 1037 | #### Search for Module, with the Exports' Address 1038 | 1039 | ``` 1040 | frida -U -f funky-chicken.debugger-challenge --no-pause -q --eval 'var x={};Process.findModuleByAddress("0x1c1c4645c");' 1041 | 1042 | { 1043 | "base": "0x1c1c2a000", 1044 | "name": "libsystem_kernel.dylib", 1045 | "path": "/usr/lib/system/libsystem_kernel.dylib", 1046 | "size": 200704 1047 | } 1048 | ``` 1049 | 1050 | ## Frida Intercepter 1051 | 1052 | ``` 1053 | [objc_playground]-> var a = ObjC.classes.NSString.stringWithString_("foo"); 1054 | 1055 | [objc_playground]-> a.superclass().toString() 1056 | "NSString" 1057 | 1058 | [objc_playground]-> a.class().toString() 1059 | "NSTaggedPointerString" 1060 | 1061 | // PASTE THIS CODE INTO THE FRIDA INTERFACE... 1062 | Interceptor.attach(ObjC.classes.NSTaggedPointerString['- isEqualToString:'].implementation, { 1063 | onEnter: function (args) { 1064 | var str = new ObjC.Object(ptr(args[2])).toString() 1065 | console.log('[+] Hooked NSTaggedPointerString[- isEqualToString:] ->' , str); 1066 | } 1067 | }); 1068 | 1069 | // TRIGGER YOUR INTERCEPTOR 1070 | [objc_playground_2]-> a.isEqualToString_("foo") 1071 | [+] Hooked NSTaggedPointerString[- isEqualToString:] -> foo 1072 | 1 // TRUE 1073 | [objc_playground_2]-> a.isEqualToString_("bar") 1074 | [+] Hooked NSTaggedPointerString[- isEqualToString:] -> bar 1075 | 0 // FALSE 1076 | ``` 1077 | 1078 | #### Frida Intercepter - monitor file open 1079 | 1080 | ``` 1081 | // frida -U -l open.js --no-pause -f com.yd.demoapp 1082 | 1083 | // the below javascript code is the contents of open.js 1084 | 1085 | var targetFunction = Module.findExportByName("libsystem_kernel.dylib", "open"); 1086 | 1087 | Interceptor.attach(targetFunction, { 1088 | onEnter: function (args) { 1089 | const path = Memory.readUtf8String(this.context.x0); 1090 | console.log("[+] " + path) 1091 | } 1092 | }); 1093 | ``` 1094 | 1095 | ## Frida-Trace 1096 | 1097 | `frida-trace --v` Check it works 1098 | `frida-trace --help` Excellent place to read about Flags 1099 | `frida-trace -f objc_playground` Spawn and NO trace 1100 | `frida-trace -m "+[NSUUID UUID]" -U "Debug CrackMe"` Trace ObjC UUID static Class Method 1101 | `frida-trace -m "*[ComVendorDebugger* *]" -U -f com.robot.demo.app` ObjC wildcard trace on Classes 1102 | `frida-trace -m "*[YDDummyApp.UserProfileMngr *]" -U -f com.robot.demo.app` Trace mangled Swift functions 1103 | `frida-trace -i "getaddrinfo" -i "SSLSetSessionOption" -U -f com.robot.demo` Trace C function on iOS 1104 | `frida-trace -m "*[*URLProtection* *]" -U -f com.robot.demo` For https challenge information 1105 | `frida-trace -m "*[NSURLSession* *didReceiveChallenge*]" -U -f com.robot.demo` Check whether https check delegate used 1106 | `frida-trace -U -f com.robot.demo.app -I libsystem_c.dylib` Trace entire Module. 1107 | `frida-trace -p $myapp -I UIKit` Trace UIKit Module. 1108 | `frida-trace -f objc_playground -I CoreFoundation` Trace CoreFoundation Module. 1109 | `frida-trace -I YDRustyKit -U -f com.yd.mobile` Trace my own module. 1110 | `frida-trace -m "-[NSURLRequest initWithURL:]" -U -f com.robot.demo` Get app files and APIs 1111 | `frida-trace -m "-[NSURL initWithString:]" -U -f com.robot.demo` Find the API endpoints 1112 | `frida-trace -m "*[NSURL absoluteString]" -U -f com.robot.demo` My favorite of these 1113 | 1114 | #### Frida-Trace strcpy() 1115 | 1116 | ``` 1117 | frida-trace -i "*strcpy" -f hitme aaaa bbbb 1118 | Instrumenting functions... 1119 | _platform_strcpy: Loaded handler at "/.../__handlers__/libSystem.B.dylib/_platform_strcpy.js" 1120 | Started tracing 1 function. Press Ctrl+C to stop. 1121 | ``` 1122 | 1123 | Edit the auto-generated, template Javascript file. 1124 | 1125 | ``` 1126 | ----------- 1127 | onEnter: function (log, args, state) { 1128 | // strcpy() arg1 is the Source. arg0 is the Destination. 1129 | console.log('\n[+] _platform_strcpy()'); 1130 | var src_ptr = args[1].toString() 1131 | var src_string = Memory.readCString(args[1]); 1132 | var src_byte_array = Memory.readByteArray(args[1],4); 1133 | var textDecoder = new TextDecoder("utf-8"); 1134 | var decoded = textDecoder.decode(src_byte_array); 1135 | console.log('[+] src_ptr\t-> ' , src_ptr); 1136 | console.log('[+] src_string\t-> ' + src_string); 1137 | console.log('[+] src_byte_array\t-> ' + src_byte_array); 1138 | console.log('[+] src_byte_array size\t-> ' + src_byte_array.byteLength); 1139 | console.log('[+] src_byte_array decoded\t-> ' + decoded); 1140 | }, 1141 | ``` 1142 | 1143 | The results: 1144 | 1145 | ``` 1146 | [+] _platform_strcpy() 1147 | [+] src_ptr -> 0x7ffeefbffaa6 1148 | [+] src_string -> aaaa 1149 | [+] src_byte_array -> [object ArrayBuffer] 1150 | [+] src_byte_array size -> 4 1151 | [+] decoded -> aaaa 1152 | 1153 | [+] _platform_strcpy() 1154 | [+] src_ptr -> 0x7ffeefbffaab 1155 | [+] src_string -> bbbb 1156 | [+] src_byte_array -> [object ArrayBuffer] 1157 | [+] src_byte_array size -> 4 1158 | [+] decoded -> bbbb 1159 | ``` 1160 | 1161 | #### Frida Objective-C Observer 1162 | 1163 | ``` 1164 | frida-ps -Uai // get your bundle ID 1165 | 1166 | frida --codeshare mrmacete/objc-method-observer -U -f funky-chicken.push-demo 1167 | 1168 | [+] At the Frida prompt... 1169 | 1170 | observeSomething('*[ABC* *]'); // any Class beginning with ABC, regardless of instance or static class 1171 | observeSomething('-[WKWebsiteDataStore httpCookieStore]'); 1172 | observeSomething('-[WKWebAllowDenyPolicyListener *]'); 1173 | observeSomething('-[WKWebView loadRequest:]'); // dump the URL to hit 1174 | observeSomething('-[WKWebView load*]'); // you get all HTML, js, css, etc 1175 | observeSomething('-[WKWebView loadHTMLString:baseURL:]') // really effective; see the entire request 1176 | observeSomething('-[WKWebView *Agent]'); // try to see if somebody set a custom UserAgent 1177 | observeSomething('*[* isEqualToString*]'); // watch string compares 1178 | ``` 1179 | 1180 | ## Bypass anti-Frida checks 1181 | 1182 | #### Rename Frida process 1183 | 1184 | `bash -c "exec -a YDFooBar ./frida-server &"` 1185 | 1186 | #### Set Frida-Server on host to a specific interface and port 1187 | 1188 | `frida-server -l 0.0.0.0:19999 &` 1189 | 1190 | #### Call Frida-server from Host 1191 | 1192 | `frida-ps -ai -H 192.168.0.38:19999` 1193 | 1194 | #### Trace on custom port 1195 | 1196 | `frida-trace -m "*[NSURLSession* *didReceiveChallenge*]" -H 192.168.0.38:19999 -f com.youdog.rusty.tinyDormant` 1197 | 1198 | ## Objection 1199 | 1200 | Objection is a runtime mobile exploration toolkit powered by Frida to assess the security posture of mobile applications **without needing to write scripts**. 1201 | 1202 | ### Install objection 1203 | 1204 | `pip3 install objection` 1205 | 1206 | ### objection: 1207 | 1208 | `objection device_type` Get information about an attached device 1209 | `objection explore` Start the objection exploration REPL 1210 | `objection explore --startup-command 'ios jailbreak simulate'` 1211 | `objection explore --startup-command 'ios jailbreak disable'` 1212 | Early Instrumentation 1213 | 1214 | ### objection explore: 1215 | 1216 | `ls` 1217 | `env` This will print out the locations of the applications Library, Caches and Documents directories 1218 | `!` Run OS command 1219 | `file download []` 1220 | `file upload []` 1221 | Upload/Download 1222 | `file cat ` View file 1223 | `memory dump all ` 1224 | `memory dump from_base ` 1225 | Dump all memory/Dump part 1226 | `memory list modules` List loaded modules in memory 1227 | `memory list exports ` Exports of a loaded module 1228 | `memory search "" (--string) (--offsets-only)` 1229 | `memory write "
" "" (--string)` 1230 | Search/Write 1231 | `sqlite connect pewpew.sqlite` Query the sqlite database 1232 | `sqlite execute schema` Have a look at the table structure 1233 | `sqlite execute query select * from data;` 1234 | Execute any query 1235 | `import ` Import frida script 1236 | `jobs list` List running scripts/jobs 1237 | `jobs kill ` Kill script/job 1238 | `ios plist cat credentials.plist` Read plist file 1239 | `ios info binary` Inspect binary info 1240 | `ios sslpinning disable --quiet` Disable SSL pinning 1241 | `ios jailbreak simulate` Simulate a jailbroken environment to understand how an application behaves 1242 | `ios jailbreak disable` Jailbreak detection bypass 1243 | `ios nsuserdefaults get` Dump NSUserDefaults 1244 | `ios nsurlcredentialstorage dump` Dump NSURLCredentialStorage 1245 | `ios keychain dump` Dump app keychain 1246 | `ios cookies get` Get secure flags and sensitive data stored in cookies 1247 | `ios monitor crypto monitor` Hooks CommonCrypto to output information about cryptographic operation 1248 | `ios ui dump` Dump UI hierarchy 1249 | `ios ui alert ""` Show alert 1250 | 1251 | ### objection hooking: 1252 | 1253 | `env` Local app paths 1254 | `ios bundles list_bundles` List bundles of the application 1255 | `ios bundles list_frameworks` List external frameworks used by the application 1256 | `ios hooking list classes` List classes of the app 1257 | `ios hooking search classes ` Search a class that contains a string 1258 | `ios hooking list class_methods` List methods of a specific class 1259 | `ios hooking search methods ` Search a method that contains a string 1260 | `ios hooking watch class ` 1261 | Hook all the methods of a class, dump all the initial parameters and returns 1262 | `ios hooking watch method "-[ ]" --dump-args --dump-return --dump-backtrace` 1263 | Hook an specific method of a class dumping the parameters, backtraces and returns 1264 | `ios hooking set return_value "-[ ]" false` 1265 | This will make the selected method return the indicated boolean 1266 | `ios hooking generate simple ` 1267 | Generate hooking template. 1268 | 1269 | ## r2frida 1270 | 1271 | ### **Attach** 1272 | 1273 | `r2 frida://device-id/Snapchat` Attach to a running app using the display name. 1274 | `r2 frida://attach/usb//Gadget` Attach to the Frida Gadget 1275 | 1276 | ### **Spawn** 1277 | 1278 | `r2 frida://device-id//com.snapchat.android` Spawn an app using two `//` and the package name. 1279 | `r2 frida://spawn/usb/device-id/com.android.app` Or explicitly using the word `spawn` 1280 | `r2 frida://spawn/usb//com.android.app` Or without entering the `device-id` 1281 | 1282 | ### Commands 1283 | 1284 | `=!?` Get the list of commands 1285 | 1286 | `=!?~^i`: 1287 | `i` Show target information 1288 | `ii[*]` List imports 1289 | `il` List libraries 1290 | `is[*] ` List symbols of lib (local and global ones) 1291 | `iE[*] ` Same as is, but only for the export global ones 1292 | `iEa[*] () ` Show address of export symbol 1293 | `isa[*] () ` Show address of symbol 1294 | `ic ` List Objective-C classes or methods of \ 1295 | `ip ` List Objective-C protocols or methods of \ 1296 | `=!i` Shows target information 1297 | `=!i*` Shows target information in r2 form 1298 | `.=!i*` Radare2 imports all the dynamic binary data from Frida. E.g: which architecture, endianness, pointer size, etc... 1299 | `.=!iE*` Radare2 imports all the dynamic `export` data from Frida for all the dynamic libraries. 1300 | `.=!iE* ` Radare2 imports all the dynamic `export` data from Frida for only one specific library. 1301 | `.=!ii*` Radare2 imports all the dynamic `import` data from Frida. 1302 | `=!ii ` List imports. Commonly used with the symbol `~`, which is the internal grep of `r2`. 1303 | `=!ii* ` List imports in r2 form. 1304 | `=!il` List libraries. Commonly used with the symbol `~`, which is the internal grep of r2. 1305 | `=!iE ` List exports of library(ies) 1306 | `=!iEa () ` Show address of export symbol 1307 | `=!iEa* () ` Show address of export symbol in r2 format 1308 | `=!isa[*] () ` Show address of symbol 1309 | `=!ic` List classes 1310 | `=!/ keyword` Search hex/string pattern in memory ranges (see search.in=?) 1311 | 1312 | `> =!?~^/`: 1313 | `/[x][j] ` Search hex/string pattern in memory ranges (see search.in=?) 1314 | `/w[j] string` Search wide string 1315 | `/v[1248][j] value` Search for a value honoring `e cfg.bigendian` of given width 1316 | 1317 | `> =!?~^d`: 1318 | `db (|)` List or place breakpoint 1319 | `db- (|)|*` Remove breakpoint(s) 1320 | `dc` Continue breakpoints or resume a spawned process 1321 | `dd[-][fd] ([newfd])` List, dup2 or close filedescriptors 1322 | `dm[.|j|*]` Show memory regions 1323 | `dma ` Allocate bytes on the heap, address is returned 1324 | `dmas ` Allocate a string inited with on the heap 1325 | `dmad ` Allocate bytes on the heap, copy contents from 1326 | `dmal` List live heap allocations created with dma[s] 1327 | `dma- (...)` Kill the allocations at (or all of them without param) 1328 | `dmp ` Change page at
with , protection (rwx) 1329 | `dmm` List all named squashed maps 1330 | `dmh` List all heap allocated chunks 1331 | `dmhj` List all heap allocated chunks in JSON 1332 | `dmh*` Export heap chunks and regions as r2 flags 1333 | `dmhm` Show which maps are used to allocate heap chunks 1334 | `dp` Show current pid 1335 | `dpt` Show threads 1336 | `dr` Show thread registers (see dpt) 1337 | `dl libname` Dlopen a library 1338 | `dl2 libname [main]` Inject library using Frida's >= 8.2 new API 1339 | `dt (|) ...` Trace list of addresses or symbols 1340 | `dth (|) (x y..)` Define function header (z=str,i=int,v=hex barray,s=barray) 1341 | `dt-` Clear all tracing 1342 | `dtr (...)` Trace register values 1343 | `dtf [fmt]` Trace address with format (^ixzO) (see dtf?) 1344 | `dtSf[*j] [sym|addr]` Trace address or symbol using the stalker (Frida >= 10.3.13) 1345 | `dtS[*j] seconds` Trace all threads for given seconds using the stalker 1346 | `di[0,1,-1] [addr]` Intercept and replace return value of address 1347 | `dx [hexpairs]` Inject code and execute it (TODO) 1348 | `dxc [sym|addr] [args..]` Call the target symbol with given args 1349 | 1350 | `e[?] [a[=b]]` List/get/set config evaluable vars 1351 | 1352 | ```bash 1353 | [0x00000000]> =!e 1354 | e patch.code=true 1355 | e search.in=perm:r-- 1356 | e search.quiet=false 1357 | e stalker.event=compile 1358 | e stalker.timeout=300 1359 | e stalker.in=raw 1360 | ``` 1361 | 1362 | `=!. script.js` 1363 | `=!ic` List iOS classes 1364 | 1365 | More info: 1366 | [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06c-reverse-engineering-and-tampering#tampering-and-runtime-instrumentation](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06c-reverse-engineering-and-tampering#tampering-and-runtime-instrumentation) 1367 | 1368 | ## Grapefruit (Passionfruit) 1369 | 1370 | Frida GUI. 1371 | 1372 | ## Dwarf 1373 | 1374 | Frida GUI. 1375 | 1376 | ## Fermion 1377 | 1378 | Frida GUI. [https://github.com/FuzzySecurity/Fermion](https://github.com/FuzzySecurity/Fermion) 1379 | 1380 | More info: 1381 | [https://frida.re/docs/examples/ios/](https://frida.re/docs/examples/ios/) 1382 | [https://frida.re/docs/frida-trace/ ](https://frida.re/docs/frida-trace/) 1383 | https://frida.re/docs/examples/ios/ 1384 | [https://github.com/sensepost/objection/wiki/Using-objection](https://github.com/sensepost/objection/wiki/Using-objection) 1385 | Apple's Entitlements Troubleshooting – [https://developer.apple.com/library/content/technotes/tn2415/_index.html](https://developer.apple.com/library/content/technotes/tn2415/\_index.html) 1386 | Apple's Code Signing – [https://developer.apple.com/support/code-signing/](https://developer.apple.com/support/code-signing/) 1387 | Cycript Manual – [http://www.cycript.org/manual/](http://www.cycript.org/manual/) 1388 | Frida iOS Tutorial – [https://www.frida.re/docs/ios/](https://www.frida.re/docs/ios/) 1389 | Frida iOS Examples – [https://www.frida.re/docs/examples/ios/](https://www.frida.re/docs/examples/ios/) 1390 | r2frida Wiki – [https://github.com/enovella/r2frida-wiki/blob/master/README.md](https://github.com/enovella/r2frida-wiki/blob/master/README.md) 1391 | Charlie Miller, Dino Dai Zovi. The iOS Hacker's Handbook. Wiley, 2012 – [https://www.wiley.com/en-us/iOS+Hacker's+Handbook-p-9781118204122](https://www.wiley.com/en-us/iOS+Hacker%27s+Handbook-p-9781118204122) 1392 | Jonathan Levin. Mac OS X and iOS Internals: To the Apple's Core. Wiley, 2013 – [http://newosxbook.com/MOXiI.pdf](http://newosxbook.com/MOXiI.pdf) 1393 | 1394 | # Analyze application network traffic 1395 | 1396 | ## Disabling SSL pinning 1397 | 1398 | Install SSL Kill Switch 2 from [https://github.com/nabla-c0d3/ssl-kill-switch2/releases/](https://github.com/nabla-c0d3/ssl-kill-switch2/releases/) 1399 | 1400 | Open your settings and enable SSL Kill Switch 2 1401 | 1402 | ## Intercepting with Charles Proxy 1403 | 1404 |
1405 | 1406 | 1. Run Charles on PC. 1407 | 1408 | 2. Install Charles Root Certificate on iOS device: 1409 | 1410 |
1411 | 1412 | Help → SSL Proxing → Install Charles Root Certificate on Mobile Device or Remote Browser. 1413 | 1414 | 1415 | 1416 |
1417 | 1418 | The following window will appear: 1419 | 1420 |
1421 | 1422 | 3. In the network settings of the iOS device specify the IP and port of Charles Proxy: 1423 | 1424 |
1425 | 1426 | Depending on your network architecture the IP address Charles is running on may differ. 1427 | 1428 | 4. Open the browser on the iOS device and follow the link — [http://chls.pro/ssl](http://chls.pro/ssl) 1429 | 1430 |
1431 | 1432 | 5. Install Charles SSL certificate on the device: 1433 | 1434 |
1435 | 1436 | 6. Enable SSL Proxying 1437 | 1438 |
1439 | 1440 | Proxy → SSL Proxying Settings... → Add (Include) → Host: `*` ; Port: `*` 1441 | 1442 | 1443 | 1444 | 1445 | 1446 |
1447 | 1448 | 7. Start SSL Proxying: 1449 | 1450 |
1451 | 1452 | # Get decrypted .ipa file 1453 | 1454 | Since all binary files inside an .ipa are encrypted with AES and being decrypted with a private key by Secure Enclave Processor at the runtime there is a few ways to decrypt it: 1455 | 1456 | ### With Apple mobile device – Dump it with bagbak (with extensions) or frida-ios-dump (can't dump extensions) or any other tool 1457 | 1458 | If you don't have Node.js: 1459 | 1460 | `brew install nvm` 1461 | `nvm install node` 1462 | 1463 | To dump decrypted ipa using bagbak utility install it on desktop: 1464 | 1465 | `sudo npm install -g bagbak` 1466 | 1467 | Then download your application from the App Store and dump: 1468 | 1469 | `bagbak --uuid --output ` 1470 | 1471 | ### With Apple mobile device – Run the hardware AES decryption 1472 | 1473 | There are several ways to run the hardware AES engine: 1474 | 1475 | - Patch [iBoot](https://www.theiphonewiki.com/wiki/IBoot_(Bootloader)) to jump to `aes_crypto_cmd` 1476 | - Use [OpenIBoot](http://github.com/planetbeing/iphonelinux/tree/master) 1477 | - Use [XPwn](https://www.theiphonewiki.com/wiki/XPwn) with a kernel patch 1478 | - Use [Greenpois0n](https://www.theiphonewiki.com/wiki/Greenpois0n_(toolkit)) console: 1479 | 1480 | `ideviceenterrecovery` 1481 | `irecovery --shell` 1482 | `go aes dec ` 1483 | - Use [ipwndfu](http://github.com/Axi0mX/ipwndfu) 1484 | - Use checkra1n 1485 | 1486 | ### We will use latest tools – checkra1n & pongoOS: 1487 | 1488 | Run checkra1n with `-p` to run into pongoOS ([https://github.com/checkra1n/pongoOS](https://github.com/checkra1n/pongoOS)) and use the `aes` command over USB 1489 | 1490 | # Analyze application binaries 1491 | 1492 | If you want to disassemble an application from the App Store, remove the FairPlay DRM first. 1493 | 1494 | After decrypting .ipa file open app binary in disassembler like **IDA Pro**. 1495 | 1496 | In this section the term "app binary" refers to the Macho-O file in the application bundle which contains the compiled code, and should not be confused with the application bundle - the IPA file. 1497 | 1498 | ## Tools 1499 | 1500 | ### Mach-O Binary Analyzers: 1501 | 1502 | - MachOViewer ([Homepage](http://sourceforge.net/projects/machoview/)) 1503 | 1504 | ### Hex Editors: 1505 | 1506 | - Hex Fiend ([Homepage](http://ridiculousfish.com/hexfiend/)) 1507 | - 0xED ([Homepage](http://www.suavetech.com/0xed/)) 1508 | - Synalyze It! ([Homepage](http://www.synalysis.net/)) 1509 | 1510 | ### Disassemblers: 1511 | 1512 | - Hopper ([Homepage](http://www.hopperapp.com/)) 1513 | - IDA ([Homepage](https://www.hex-rays.com/products/ida/index.shtml)) 1514 | - otool ([man page](x-man-page://1/otool)) 1515 | - otx ([Homepage](http://otx.osxninja.com/)) 1516 | 1517 | ### Decompilers: 1518 | 1519 | - Hopper ([Homepage](http://www.hopperapp.com/)) 1520 | - Hex-Rays ([Homepage](https://www.hex-rays.com/products/decompiler/index.shtml)) 1521 | - classdump ([Homepage](http://stevenygard.com/projects/class-dump/)) 1522 | - codedump (i386) ([Source ZIP](https://pewpewthespells.com/re/i386codedump.zip)) 1523 | 1524 | ### Debuggers: 1525 | 1526 | - GDB (Not shipped on OS X anymore) ([Homepage](http://www.sourceware.org/gdb/)) 1527 | - LLDB ([Homepage](http://lldb.llvm.org/) - [man page](x-man-page://1/lldb)) 1528 | - PonyDebugger ([link](https://github.com/square/PonyDebugger)) 1529 | 1530 | ### Memory Editors: 1531 | 1532 | - Bit Slicer ([Homepage](http://zorg.tejat.net/programs/) - [Source](https://bitbucket.org/zorgiepoo/bit-slicer/)) 1533 | 1534 | ### Various Command Line Tools: 1535 | 1536 | - nm ([man page](x-man-page://1/nm)) 1537 | - strings ([man page](x-man-page://1/strings)) 1538 | - dsymutil ([man page](x-man-page://1/dsymutil)) 1539 | - install_name_tool ([man page](x-man-page://1/install_name_tool)) 1540 | - ld ([man page](x-man-page://1/ld)) 1541 | - lipo ([man page](x-man-page://1/lipo)) 1542 | - codesign ([man page](x-man-page://1/codesign)) 1543 | - hexdump ([man page](x-man-page://1/hexdump)) 1544 | - dyld_shared_cache ([link](x-man-page://1/hexdump)) 1545 | - vbindiff ([link](http://www.cjmweb.net/vbindiff/)) 1546 | - binwalk ([link](https://code.google.com/p/binwalk/)) 1547 | - xpwntool ([link](http://theiphonewiki.com/wiki/Xpwntool)) 1548 | - objdump ([link](https://sourceware.org/binutils/docs/binutils/objdump.html)) 1549 | 1550 | ## Disassembling with IDA Pro 1551 | 1552 | If you have a license for IDA Pro, you can analyze the app binary using IDA Pro as well. 1553 | 1554 | To get started, simply open the app binary in IDA Pro. 1555 | 1556 |
1557 | 1558 | Upon opening the file, IDA Pro will perform auto-analysis, which can take a while depending on the size of the binary. Once the auto-analysis is completed you can browse the disassembly in the **IDA View** (Disassembly) window and explore functions in the **Functions** window, both shown in the screenshot below. 1559 | 1560 |
1561 | 1562 | ## IDA Pro plugins for iOS and Mach-O 1563 | 1564 | [https://github.com/ChiChou/IDA-ObjCExplorer/blob/master/ObjCExplore.py](https://github.com/ChiChou/IDA-ObjCExplorer/blob/master/ObjCExplore.py) – Obj-C Classes Explorer for IDA Pro. Just press **Ctrl + Shift + E**. 1565 | 1566 | [https://github.com/avast/retdec-idaplugin](https://github.com/avast/retdec-idaplugin) – RetDec decompiler for IDA Pro. Just press **Ctrl + D**. 1567 | 1568 | [https://github.com/zynamics/objc-helper-plugin-ida](https://github.com/zynamics/objc-helper-plugin-ida) – zynamics Objective-C helper script. 1569 | 1570 | [https://github.com/techbliss/Frida_For_Ida_Pro](https://github.com/techbliss/Frida_For_Ida_Pro) – Connect frida. 1571 | 1572 | ### Kernelcache analysis 1573 | 1574 | [https://github.com/vadimszzz/idapython/blob/master/cortex_m_firmware.py](https://github.com/vadimszzz/idapython/blob/master/cortex_m_firmware.py) – IDA Python module for loading ARM Cortex M firmware. 1575 | 1576 | [https://github.com/saelo/ida_scripts/blob/master/kernelcache.py](https://github.com/saelo/ida_scripts/blob/master/kernelcache.py) – Identify and rename function stubs in an iOS kernelcache. 1577 | 1578 | [https://github.com/luismiras/IDA-iOS-scripts/blob/master/find_iOS_syscalls.py](https://github.com/luismiras/IDA-iOS-scripts/blob/master/find_iOS_syscalls.py) – Find iOS syscalls. 1579 | 1580 | [https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/listAllKEXT.py](https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/listAllKEXT.py) – List all Kexts. 1581 | 1582 | [https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/findSyscallTable.py](https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/findSyscallTable.py) – This script searches the iOS syscall table within the iOS kernelcache. 1583 | 1584 | [https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/fixupSysctlSet.py](https://github.com/stefanesser/IDA-IOS-Toolkit/blob/master/fixupSysctlSet.py) – This script ensures that all sysctl_oid structures referenced by the sysctl_set segment are marked correctly. 1585 | 1586 | [https://github.com/bazad/ida_kernelcache](https://github.com/bazad/ida_kernelcache) – An IDA Toolkit for analyzing iOS kernelcaches. 1587 | 1588 | ### Get information about methods 1589 | 1590 | You can use [class-dump](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x08-Testing-Tools.md#class-dump) to get information about methods in the application's source code. 1591 | 1592 | Note the architectures: `armv7` (which is 32-bit) and `arm64`. This design of a fat binary allows an application to be deployed on all devices. To analyze the application with class-dump, we must create a so-called thin binary, which contains one architecture only: 1593 | 1594 | ``` 1595 | iOS8-jailbreak:~ root# lipo -thin armv7 DamnVulnerableIOSApp -output DVIA32 1596 | ``` 1597 | 1598 | And then we can proceed to performing class-dump: 1599 | 1600 | ```bash 1601 | iOS8-jailbreak:~ root# class-dump DVIA32 1602 | 1603 | @interface FlurryUtil : ./DVIA/DVIA/DamnVulnerableIOSApp/DamnVulnerableIOSApp/YapDatabase/Extensions/Views/Internal/ 1604 | { 1605 | } 1606 | + (BOOL)appIsCracked; 1607 | + (BOOL)deviceIsJailbroken; 1608 | ``` 1609 | 1610 | Note the plus sign, which means that this is a class method that returns a BOOL type. A minus sign would mean that this is an instance method. Refer to later sections to understand the practical difference between these. 1611 | 1612 | ### Retrieving Symbols and Strings 1613 | 1614 | Strings are always a good starting point while analyzing a binary, as they provide context to the associated code. For instance, an error log string such as "Cryptogram generation failed" gives us a hint that the adjoining code might be responsible for the generation of a cryptogram. 1615 | 1616 | In order to extract strings from an iOS binary, you can use GUI tools such as Ghidra or Cutter or rely on CLI-based tools such as the *strings* Unix utility `strings ` or radare2's rabin2 `rabin2 -zz `. When using the CLI-based ones you can take advantage of other tools such as grep (e.g. in conjunction with regular expressions) to further filter and analyze the results. 1617 | 1618 | #### Symbols 1619 | 1620 | **nm** 1621 | 1622 | ``` 1623 | nm libprogressbar.a | less 1624 | ``` 1625 | 1626 | **rabin2** 1627 | 1628 | ``` 1629 | rabin2 -s file 1630 | ``` 1631 | 1632 | **radare2** 1633 | 1634 | ``` 1635 | is~FUNC 1636 | ``` 1637 | 1638 | #### Strings 1639 | 1640 | Check URLs: 1641 | 1642 | ``` 1643 | strings | grep -E 'session|https' 1644 | strings | grep -E 'pinning' 1645 | rabin2 -qz // in Data Section 1646 | rabin2 -qzz // ALL strings in binary 1647 | 1648 | jtool -dA __TEXT.__cstring c_playground 1649 | Dumping C-Strings from address 0x100000f7c (Segment: __TEXT.__cstring).. 1650 | Address : 0x100000f7c = Offset 0xf7c 1651 | 0x100000f7c: and we have a winner @ %ld\r 1652 | 0x100000f98: and that's a wrap folks!\r 1653 | ``` 1654 | 1655 | ### Cross References 1656 | 1657 | IDA Pro can be used for obtaining cross references by right clicking the desired function and selecting **Show xrefs**. 1658 | 1659 | # ARM64 assembly 1660 | 1661 | ### Registers 1662 | 1663 | - General purpose registers 0 through 30 with two addressing modes: 1664 | - `w0` = 32-bit 1665 | - `x0` = 64-bit 1666 | - Zero register `wzr` or `xzr`. Write to = discard, read from = `0`. 1667 | - Stack pointer `sp` - unlike other instruction sets, never modified implicitly (e.g. no `push`/`pop`). 1668 | - Instruction pointer `pc`, not modifiable directly. 1669 | - A lot of float, vector and system registers, look up as needed. 1670 | - First register in assembly is usually destination, rest are source (except for `str`). 1671 | 1672 | ### Register manipulation 1673 | 1674 | - `mov` to copy one register to another, e.g. `mov x0, x1` -> `x0 = x1`. 1675 | - Constant `0` loaded from `wzr`/`xzr`. 1676 | - Small constants usually OR'ed with zero register, e.g. `orr x0, xzr, 5`. 1677 | - Big constants usually loaded with `movz`+`movk`, e.g.: 1678 | ```asm 1679 | movz x0, 0x1234, lsl 32 1680 | movk x0, 0x5678, lsl 16 1681 | movk x0, 0x9abc 1682 | ``` 1683 | -> `x0 = 0x123456789abc`. 1684 | - `movn` for negative values, e.g. `movn x0, 1` -> `x0 = -1`. 1685 | - `lsl` and `lsr` instructions = logic-shift-left and logic-shift-right, e.g. `lsl x0, x0, 8` -> `x0 <<= 8`. 1686 | - `lsl` and `lsr` not only used as instructions, but also as operands to other instructions (see `movz` above). 1687 | - `asl` for arithmetic shift also exists, but less frequently used. 1688 | - Lots of arithmetic, logic and bitwise instructions, look up as needed. 1689 | 1690 | ### Memory 1691 | 1692 | - `ldr` and `str` with multiple variations and addressing modes: 1693 | - `ldr x0, [x1]` -> `x0 = *x1` 1694 | - `str x0, [x1]` -> `*x1 = x0` 1695 | - `ldr x0, [x1, 0x10]` -> `x0 = *(x1 + 0x10)` 1696 | - `ldp`/`stp` to load/store two registers at once behind each other, e.g.: 1697 | `stp x0, x1, [x2]` -> `*x2 = x0; *(x2 + 8) = x1;` 1698 | - Multiple variations for load/store size: 1699 | - Register names `xN` for 64-bit, `wN` for 32-bit 1700 | - `ldrh`/`srth` for 16-bit 1701 | - `ldrb`/`strb` for 8-bit 1702 | - Multiple variations for sign-extending registers smaller than 64-bit: 1703 | - `ldrsw x0, [x1]` -> load 32-bit int, sign extend to 64-bit 1704 | - `ldrsh x0, [x1]` -> load 16-bit int, sign extend to 64-bit 1705 | - `ldrsb x0, [x1]` -> load 8-bit int, sign extend to 64-bit 1706 | - (No equivalent `str` instructions) 1707 | - Three register addressing modes: 1708 | - Normal: `ldr x0, [x1, 0x10]` 1709 | - Pre-indexing: `ldr x0, [x1, 0x10]!` (notice the `!`) -> `x1 += 0x10; x0 = *x1;` 1710 | - Post-indexing: `ldr x0, [x1], 0x10` -> `x0 = *x1; x1 += 0x10;` 1711 | - Memory addresses usually computed by PC-relative instructions: 1712 | - `adr x0, 0x12345` (only works for small offset from PC) 1713 | - Bigger ranges use `adrp`+`add`: 1714 | ```asm 1715 | adrp x0, 0xffffff8012345000 ; "address of page", last 12 bits are always zero 1716 | add x0, x0, 0x678 1717 | ``` 1718 | - Even bigger ranges usually stored as pointers in data segment, offset by linker and loaded with `ldr`. 1719 | 1720 | ### Calling convention 1721 | 1722 | _Note: Only dealing with integral types here. The rules change when floating-point is involved._ 1723 | 1724 | - `x0`-`x7` first 8 arguments, rest on the stack (low address to high) with natural alignment (as if they were members of a struct) 1725 | - `x8` pointer to where to write the return value if >128 bits, otherwise scratch register 1726 | - `x9`-`x17` scratch registers 1727 | - `x18` platform register (reserved, periodically zeroed by XNU) 1728 | - `x19`-`x28` callee-saved 1729 | - `x29` frame pointer (basically also just callee-saved) 1730 | - `x30` return address 1731 | - Functions that save anything in `x19`-`x28` usually start like this: 1732 | ```asm 1733 | stp x24, x23, [sp, -0x40]! 1734 | stp x22, x21, [sp, 0x10] 1735 | stp x20, x19, [sp, 0x20] 1736 | stp x29, x30, [sp, 0x30] 1737 | add x29, sp, 0x30 1738 | ``` 1739 | and end like this: 1740 | ```asm 1741 | ldp x29, x30, [sp, 0x30] 1742 | ldp x20, x19, [sp, 0x20] 1743 | ldp x22, x21, [sp, 0x10] 1744 | ldp x24, x23, [sp], 0x40 1745 | ret 1746 | ``` 1747 | The stack for local variables is usually managed separately though, with `add sp, sp, 0x...` and `sub sp, sp, 0x...`. 1748 | - Variadic arguments are passed on the stack (low address to high), each promoted to 8 bytes. Structs that don't fit into 8 bytes have a pointer passed instead. 1749 | Fixed arguments that don't fit into `x0`-`x7` come before variadic arguments on the stack, naturally aligned. 1750 | - The return value is passed as follows: 1751 | - If it fits into 64 bits, in `x0`. 1752 | - If it fits into 128 bits, the first/lower half in `x0`, the second/upper half in `x1`. 1753 | - If it is larger than 128 bits, the caller passes a pointer in `x8` to where the result is written. 1754 | 1755 | ### Conditions 1756 | 1757 | - System register `nzcv` holds condition flags (Negative, Zero, Carry, oVerflow). 1758 | Set by one instruction and acted upon by a subsequent one, the latter using condition codes. 1759 | (Could be accessed as normal system register, but usually isn't.) 1760 | - Some instructions use condition codes as suffixes (`instr.cond`), others as source operands (`instr ..., cond`). List of condition codes: 1761 | - `eq`/`ne` = equal/not equal 1762 | - `lt`/`le`/`gt`/`ge` = less than/less or equal/greater than/greater or equal (signed) 1763 | - `lo`/`ls`/`hi`/`hs` = lower/lower or same/higher/higher or same (unsigned) 1764 | - A few more weird flags, seldom used. 1765 | - Unlike many other instruction sets, arm64 sets carry on no-borrow rather than borrow. 1766 | Thus, `cs`/`cc` = carry set/carry clear are aliases of `hs`/`lo`. 1767 | - `cmp` = most common/basic compare instruction, sets condition flags. Examples: 1768 | ```asm 1769 | cmp x0, x1 1770 | cmp x0, 3 1771 | ``` 1772 | - Other instructions that set condition flags: 1773 | - `cmn` = compare negative 1774 | - `tst` = bitwise test 1775 | - `adds`/`adcs` = add/add with carry 1776 | - `subs`/`sbcs` = subtract/subtract with carry 1777 | - `negs`/`ngcs` = negate/negate with carry 1778 | - Some more bitwise and float instructions. 1779 | - Some instructions that act on condition flags: 1780 | - `cset` = conditional set, e.g.: 1781 | ```asm 1782 | cmp x0, 3 1783 | cset x0, lo 1784 | ``` 1785 | -> `x0 = (x0 < 3)` 1786 | - `csel` = conditional select, e.g.: 1787 | ```asm 1788 | cmp x0, 3 1789 | csel x0, x1, x2, lo 1790 | ``` 1791 | -> `x0 = (x0 < 3) ? x1 : x2` 1792 | (Translates nicely to ternary conditional.) 1793 | - `ccmp` = conditional compare, e.g.: 1794 | ```asm 1795 | cmp x0, 3 1796 | ccmp x0, 7, 2, hs 1797 | b.hi 0xffffff8012345678 1798 | ``` 1799 | -> `hi` condition will be true if `x0 < 3 || x0 > 7` (third `ccmp` operand is raw `nzcv` data). 1800 | Often generated by compiler for logical and/or of two conditions. 1801 | - Many, many more. 1802 | 1803 | ### Branches 1804 | 1805 | - `b` = simple branch, jump to PC-relative address. 1806 | Can be unconditional: 1807 | ```asm 1808 | b 0xffffff8012345678 1809 | ``` 1810 | or conditional: 1811 | ```asm 1812 | cmp x0, 3 1813 | b.lo 0xffffff8012345678 ; jump to 0xffffff8012345678 if x < 3 1814 | ``` 1815 | Used primarily within function for flow control. 1816 | - Shortcuts `cbz`/`cbnz` = compare-branch-zero and compare-branch-non-zero. 1817 | Just shorter ways to write 1818 | ```asm 1819 | cmp xN, 0 1820 | b.eq 0x... 1821 | ``` 1822 | or 1823 | ```asm 1824 | cmp xN, 0 1825 | b.ne 0x... 1826 | ``` 1827 | (Translate nicely to C `if(x)` or `if(!x)`.) 1828 | - Shortcuts `tbz`/`tbnz` = test single bit and branch if zero/non-zero. 1829 | E.g. `tbz x0, 3, ...` translates to `if((x0 & (1 << 3)) == 0) goto ...`. 1830 | - `bl` = branch-and-link (e.g. `bl 0xffffff8012345678`) 1831 | Store return address to `x30` and jump to PC-relative address. Used for static function calls. 1832 | - `blr` = branch-and-link to register (e.g. `blr x8`) 1833 | Store return address to `x30` and jump to address in `x8`. Used for calls with function pointers or C++ virtual methods. 1834 | - `br` = branch to register (e.g. `br x8`) 1835 | Jump to address in `x8`. Used for tail calls. 1836 | - `ret` = return to address in register, default: `x30` 1837 | Can in theory use registers other than `x30` (e.g. `ret x8`), but compiler doesn't usually generate that. 1838 | ### Miscellaneous 1839 | 1840 | - `nop` = do nothing 1841 | - `svc` = make a system call using an immediate value (e.g. `svc 0x80`). Note that the immediate value is separate from the syscall number. XNU ignores the immediate and expects the syscall number in `x16`. 1842 | - `.` = special symbol that refers to the address of the instruction it is used in (e.g. `adr x0, .`) 1843 | 1844 | # iOS tweak development 1845 | 1846 | ## Theos 1847 | 1848 | ### Installation instructions for macOS 1849 | 1850 | 1. Install the following prerequisites: 1851 | 1852 | - [Homebrew](https://brew.sh/) 1853 | - [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12) is mandatory. The Command Line Tools package isn’t sufficient for Theos to work. Xcode includes toolchains for all Apple platforms. 1854 | 1855 | ``` 1856 | brew install ldid xz 1857 | ``` 1858 | 1859 | 2. Set up the `THEOS` environment variable: 1860 | 1861 | ``` 1862 | echo "export THEOS=~/theos" >> ~/.zshrc 1863 | source ~/.zshrc 1864 | ``` 1865 | 1866 | 3. Clone Theos: 1867 | 1868 | ``` 1869 | git clone --recursive https://github.com/theos/theos.git $THEOS 1870 | ``` 1871 | 1872 | 4. Get the toolchain: 1873 | 1874 | Xcode contains the toolchain. 1875 | 1876 | 5. Get an iOS SDK: 1877 | 1878 | Xcode always provides the latest iOS SDK, but as of Xcode 7.3, it no longer includes private frameworks you can link against. This may be an issue when developing tweaks. You can get patched SDKs from [our SDKs repo](https://github.com/theos/sdks). 1879 | 1880 | ``` 1881 | curl -LO https://github.com/theos/sdks/archive/master.zip 1882 | TMP=$(mktemp -d) 1883 | unzip master.zip -d $TMP 1884 | mv $TMP/sdks-master/*.sdk $THEOS/sdks 1885 | rm -r master.zip $TMP 1886 | ``` 1887 | 1888 | ## Logos 1889 | 1890 | Logos is a Perl regex-based preprocessor that simplifies the boilerplate code needed to create hooks for Objective-C methods and C functions with an elegant Objective-C-like syntax. It’s most commonly used along with the Theos build system, which was originally developed to create jailbreak tweaks. Logos was once integrated in the same Git repo as Theos, but now has been decoupled from Theos to its own repo. 1891 | 1892 | Logos aims to provide an interface for [Cydia Substrate](https://cydiasubstrate.com/) by default, but can be configured to directly use the Objective-C runtime. 1893 | 1894 | Logos is a component of the [Theos](https://theos.dev/) development suite. 1895 | 1896 | ``` 1897 | %hookf(return type, functionName, arguments list...) { 1898 | /* body */ 1899 | } 1900 | ``` 1901 | 1902 | Generate a function hook for the function named `functionName`. Set `functionName` in `%init` to an expression if the symbol should be dynamically looked up. 1903 | 1904 | Example: 1905 | 1906 | ``` 1907 | // Given the function prototype (only add it yourself if it's not declared in an included/imported header) 1908 | 1909 | FILE *fopen(const char *path, const char *mode); 1910 | 1911 | // The hook is thus made 1912 | %hookf(FILE *, fopen, const char *path, const char *mode) { 1913 | puts("Hey, we're hooking fopen to deny relative paths!"); 1914 | if (path[0] != '/') { 1915 | return NULL; 1916 | } 1917 | return %orig; // Call the original implementation of this function 1918 | } 1919 | 1920 | // functions can also be looked up at runtime, if, for example, the function is in a private framework 1921 | %hookf(BOOL, MGGetBoolAnswer, CFStringRef string) { 1922 | if (CFEqual(string, CFSTR("StarkCapability"))) { 1923 | return YES; 1924 | } 1925 | return %orig; 1926 | } 1927 | %ctor() { 1928 | %init(MGGetBoolAnswer = MSFindSymbol(NULL, "_MGGetBoolAnswer")); 1929 | } 1930 | ``` 1931 | 1932 | ### %ctor 1933 | 1934 | ``` 1935 | %ctor { 1936 | /* body */ 1937 | } 1938 | ``` 1939 | 1940 | Generate an anonymous constructor (of default priority). This function is executed after the binary is loaded into memory. `argc`, `argv`, and `envp` are implicit arguments so they can be used as they would be in a `main` function. 1941 | 1942 | ### %dtor 1943 | 1944 | ``` 1945 | %dtor { 1946 | /* body */ 1947 | } 1948 | ``` 1949 | 1950 | Generate an anonymous deconstructor (of default priority). This function is executed before the binary is unloaded from memory.`argc`, `argv`, and `envp` are implicit arguments so they can be used as they would be in a `main` function. 1951 | 1952 | ## Block level 1953 | 1954 | The directives in this category open a block of code which must be closed by an [%end](https://theos.dev/docs/logos-syntax#end) directive (shown below). These should not exist within functions or methods. 1955 | 1956 | ### %group 1957 | 1958 | ``` 1959 | %group GroupName 1960 | /* %hooks */ 1961 | %end 1962 | ``` 1963 | 1964 | Generate a hook group with the name `GroupName`. Groups can be used for conditional initialization or code organization. All ungrouped hooks are in the default group, initializable via [%init](https://theos.dev/docs/logos-syntax#init) without arguments. 1965 | 1966 | Cannot be inside another [%group](https://theos.dev/docs/logos-syntax#group) block. 1967 | 1968 | Grouping can be used to manage backwards compatibility with older code. 1969 | 1970 | Example: 1971 | 1972 | ``` 1973 | %group iOS8 1974 | %hook IOS8_SPECIFIC_CLASS 1975 | // your code here 1976 | %end // end hook 1977 | %end // end group ios8 1978 | 1979 | %group iOS9 1980 | %hook IOS9_SPECIFIC_CLASS 1981 | // your code here 1982 | %end // end hook 1983 | %end // end group ios9 1984 | 1985 | %ctor { 1986 | if (kCFCoreFoundationVersionNumber > 1200) { 1987 | %init(iOS9); 1988 | } else { 1989 | %init(iOS8); 1990 | } 1991 | } 1992 | ``` 1993 | 1994 | ### %hook 1995 | 1996 | ``` 1997 | %hook ClassName 1998 | /* objc methods */ 1999 | %end 2000 | ``` 2001 | 2002 | Open a hook block for the class named `ClassName`. 2003 | 2004 | Can be inside a [%group](https://theos.dev/docs/logos-syntax#group) block. 2005 | 2006 | Example: 2007 | 2008 | ``` 2009 | %hook SBApplicationController 2010 | - (void)uninstallApplication:(SBApplication *)application { 2011 | NSLog(@"Hey, we're hooking uninstallApplication:!"); 2012 | %orig; // Call the original implementation of this method 2013 | } 2014 | %end 2015 | ``` 2016 | 2017 | ### %new 2018 | 2019 | ``` 2020 | %new 2021 | /* objc method */ 2022 | %new(signature) 2023 | /* objc method */ 2024 | ``` 2025 | 2026 | Add a new method to a hooked class or subclass by adding this directive above the method definition. signature is the Objective-C type encoding for the new method; if it is omitted, one will be generated. 2027 | 2028 | Must be inside a [%hook](https://theos.dev/docs/logos-syntax#hook) or [%subclass](https://theos.dev/docs/logos-syntax#subclass) block. 2029 | 2030 | Example: 2031 | 2032 | ``` 2033 | %new 2034 | - (void)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { 2035 | NSLog(@"Recieved tap: %@", gestureRecognizer); 2036 | } 2037 | ``` 2038 | 2039 | ### %subclass 2040 | 2041 | ``` 2042 | %subclass ClassName: Superclass 2043 | /* %properties and methods */ 2044 | %end 2045 | ``` 2046 | 2047 | Generate a subclass at runtime. Like @property in normal Objective-C classes, you can use [%property](https://theos.dev/docs/logos-syntax#property) to add properties to the subclass. The [%new](https://theos.dev/docs/logos-syntax#new) specifier is needed for a method that doesn’t exist in the superclass. To instantiate an object of the new class, you can use the [%c](https://theos.dev/docs/logos-syntax#c) operator. 2048 | 2049 | Can be inside a [%group](https://theos.dev/docs/logos-syntax#group) block. 2050 | 2051 | Example: 2052 | 2053 | ``` 2054 | // An interface is required to be able to call methods of the runtime subclass using block syntax. 2055 | @interface MyObject : NSObject 2056 | @property (nonatomic, retain) NSString * someValue; 2057 | @end 2058 | 2059 | %subclass MyObject : NSObject 2060 | 2061 | %property (nonatomic, retain) NSString * someValue; 2062 | 2063 | - (instancetype)init { 2064 | if ((self = %orig)) { 2065 | [self setSomeValue:@"value"]; 2066 | } 2067 | return self; 2068 | } 2069 | 2070 | %end 2071 | 2072 | %ctor { 2073 | // The runtime subclass cannot be linked at compile time so you have to use %c(). 2074 | MyObject *myObject = [[%c(MyObject) alloc] init]; 2075 | NSLog(@"myObject: %@", [myObject someValue]); 2076 | } 2077 | ``` 2078 | 2079 | ### %property 2080 | 2081 | ``` 2082 | %property (nonatomic|assign|retain|copy|weak|strong|getter=...|setter=...) Type name; 2083 | ``` 2084 | 2085 | Add a property to a [%subclass](https://theos.dev/docs/logos-syntax#subclass) just like you would with @property to a normal Objective-C subclass as well as adding new properties to existing classes within [%hook](https://theos.dev/docs/logos-syntax#hook). 2086 | 2087 | Must be inside a [%hook](https://theos.dev/docs/logos-syntax#hook) or [%subclass](https://theos.dev/docs/logos-syntax#subclass) block. 2088 | 2089 | ### %end 2090 | 2091 | ``` 2092 | %end 2093 | ``` 2094 | 2095 | Close a [%group](https://theos.dev/docs/logos-syntax#group), [%hook](https://theos.dev/docs/logos-syntax#hook) or [%subclass](https://theos.dev/docs/logos-syntax#subclass) block. 2096 | 2097 | ## Function level 2098 | 2099 | The directives in this category should only exist within a function or method body. 2100 | 2101 | ### %init 2102 | 2103 | ``` 2104 | %init; 2105 | %init([=, …]); 2106 | %init(GroupName[, [+|-]=, …]); 2107 | ``` 2108 | 2109 | Initialize a group’s method and function hooks. Passing no group name will initialize the default group. Passing `ClassName=expr`arguments will substitute the given expressions for those classes at initialization time. The `+` sigil (as in class methods in Objective-C) can be prepended to the classname to substitute an expression for the metaclass. If not specified, the sigil defaults to `-`, to substitute the class itself. If not specified, the metaclass is derived from the class. 2110 | 2111 | The class name replacement is specially useful for classes that contain characters that can’t be used as the class name token for the [%hook](https://theos.dev/docs/logos-syntax#hook) directive, such as spaces and dots. 2112 | 2113 | Example: 2114 | 2115 | ``` 2116 | %hook ClassName 2117 | - (id)init { 2118 | return %orig; 2119 | } 2120 | %end 2121 | 2122 | %ctor { 2123 | %init(ClassName=objc_getClass("SwiftApp.ClassName")); 2124 | } 2125 | ``` 2126 | 2127 | ### %c 2128 | 2129 | ``` 2130 | %c([+|-]ClassName) 2131 | ``` 2132 | 2133 | Evaluates to `ClassName` at runtime. If the `+` sigil is specified, it evaluates to MetaClass instead of Class. If not specified, the sigil defaults to `-`, evaluating to Class. 2134 | 2135 | ### %orig 2136 | 2137 | ``` 2138 | %orig 2139 | %orig(args, …) 2140 | ``` 2141 | 2142 | Call the original hooked function or method. Doesn’t work in a [%new](https://theos.dev/docs/logos-syntax#new)‘d method. Works in subclasses, strangely enough, because MobileSubstrate will generate a super-call closure at hook time. (If the hooked method doesn’t exist in the class we’re hooking, it creates a stub that just calls the superclass implementation.) `args` is passed to the original function - don’t include `self` and `_cmd`, Logos does this for you. 2143 | 2144 | Example: 2145 | 2146 | ``` 2147 | %hook ClassName 2148 | - (int)add:(int)a to:(int)b { 2149 | if (a != 0) { 2150 | // Return original result if `a` is not 0 2151 | return %orig; 2152 | } 2153 | // Otherwise, use 1 as `a` 2154 | return %orig(1, b); 2155 | } 2156 | %end 2157 | ``` 2158 | 2159 | #### &%orig 2160 | 2161 | ``` 2162 | &%orig 2163 | ``` 2164 | 2165 | Get a pointer to the original function or method. Return type is `void (*)(id, SEL[, arg types])` 2166 | 2167 | Example: 2168 | 2169 | ``` 2170 | // Call from outside hooked method: 2171 | void (*orig_ClassName_start)(id, SEL) = nil; 2172 | 2173 | void doStuff(id self, SEL _cmd) { 2174 | if (self && orig_ClassName_start) { 2175 | orig_ClassName_start(self, _cmd); 2176 | } 2177 | } 2178 | 2179 | %hook ClassName 2180 | - (void)start { 2181 | %orig; 2182 | orig_ClassName_start = &%orig; 2183 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), 2184 | dispatch_get_main_queue(), ^{ 2185 | doStuff(self, _cmd); 2186 | }); 2187 | } 2188 | %end 2189 | 2190 | // Call with another object: 2191 | %hook ClassName 2192 | - (int)add:(int)a to:(int)b { 2193 | int (*_orig)(id, SEL, int, int) = &%orig; 2194 | ClassName * myObject = [ClassName new]; 2195 | int r = _orig(myObject, _cmd, 1, 2); 2196 | [myObject release]; 2197 | return r; 2198 | } 2199 | %end 2200 | ``` 2201 | 2202 | Real world example at [PreferenceLoader](https://github.com/DHowett/preferenceloader/blob/master/prefs.xm#L237-L263) 2203 | 2204 | ### %log 2205 | 2206 | ``` 2207 | %log; 2208 | %log([(), …]); 2209 | ``` 2210 | 2211 | Dump the method arguments to syslog. Typed arguments included in `%log` will be logged as well. 2212 | 2213 | ## logify.pl 2214 | 2215 | You can use logify.pl to create a Logos source file from a header file that will log all of the functions of that header file. Here is an example of a very simple Logos tweak generated by logify.pl. 2216 | 2217 | Given a header file named `SSDownloadAsset.h`: 2218 | 2219 | ``` 2220 | @interface SSDownloadAsset : NSObject 2221 | - (NSString *)finalizedPath; 2222 | - (NSString *)downloadPath; 2223 | - (NSString *)downloadFileName; 2224 | + (id)assetWithURL:(id)url type:(int)type; 2225 | - (id)initWithURLRequest:(id)urlrequest type:(int)type; 2226 | - (id)initWithURLRequest:(id)urlrequest; 2227 | - (id)_initWithDownloadMetadata:(id)downloadMetadata type:(id)type; 2228 | @end 2229 | ``` 2230 | 2231 | You can find logify.pl at $THEOS/bin/logify.pl and you would use it as so: 2232 | 2233 | ``` 2234 | $THEOS/bin/logify.pl ./SSDownloadAsset.h 2235 | ``` 2236 | 2237 | The resulting output should be: 2238 | 2239 | ``` 2240 | %hook SSDownloadAsset 2241 | - (NSString *)finalizedPath { %log; NSString * r = %orig; NSLog(@" = %@", r); return r; } 2242 | - (NSString *)downloadPath { %log; NSString * r = %orig; NSLog(@" = %@", r); return r; } 2243 | - (NSString *)downloadFileName { %log; NSString * r = %orig; NSLog(@" = %@", r); return r; } 2244 | + (id)assetWithURL:(id)url type:(int)type { %log; id r = %orig; NSLog(@" = %@", r); return r; } 2245 | - (id)initWithURLRequest:(id)urlrequest type:(int)type { %log; id r = %orig; NSLog(@" = %@", r); return r; } 2246 | - (id)initWithURLRequest:(id)urlrequest { %log; id r = %orig; NSLog(@" = %@", r); return r; } 2247 | - (id)_initWithDownloadMetadata:(id)downloadMetadata type:(id)type { %log; id r = %orig; NSLog(@" = %@", r); return r; } 2248 | %end 2249 | ``` 2250 | 2251 | ## Logos File Extensions 2252 | 2253 | | Extension | Process order | 2254 | | --------- | ------------------------------------------------------------ | 2255 | | x | will be processed by Logos, then preprocessed and compiled as Objective-C. | 2256 | | xm | will be processed by Logos, then preprocessed and compiled as Objective-C++. | 2257 | | xi | will be preprocessed first, then Logos will process the result, and then it will be compiled as Objective-C. | 2258 | | xmi | will be preprocessed first, then Logos will process the result, and then it will be compiled as Objective-C++. | 2259 | 2260 | xi or xmi files enable Logos directives to be used in preprocessor macros, such as `#define`. You can also import other Logos source files with the `#include` statement. However, this is discouraged, since this leads to longer build times recompiling code that hasn’t changed. Separating into x and xm files, sharing variables and functions via `extern` declarations, is recommended. 2261 | 2262 | These file extensions control how a build system such as Theos should build a Logos file. Logos itself does not take the file extension into account and works regardless of whether a file is Objective-C or Objective-C++. 2263 | 2264 | 2265 | ### Links 2266 | 2267 | [https://theos.dev/docs/](https://theos.dev/docs/) 2268 | [https://cydia.saurik.com/faq/developing.html](https://cydia.saurik.com/faq/developing.html) 2269 | [http://www.cydiasubstrate.com/id/7cee77bc-c4a5-4b8b-b6ef-36e7dd039692/](http://www.cydiasubstrate.com/id/7cee77bc-c4a5-4b8b-b6ef-36e7dd039692/) 2270 | [http://www.cydiasubstrate.com/inject/](http://www.cydiasubstrate.com/inject/) 2271 | [https://iphonedev.wiki/index.php/Cydia_Substrate](https://iphonedev.wiki/index.php/Cydia_Substrate) 2272 | [https://cwcaude.github.io/project/tutorial/2020/07/02/iOS-tweak-dev-1.html](https://cwcaude.github.io/project/tutorial/2020/07/02/iOS-tweak-dev-1.html) 2273 | [https://cwcaude.github.io/project/tutorial/2020/07/04/iOS-tweak-dev-2.html](https://cwcaude.github.io/project/tutorial/2020/07/04/iOS-tweak-dev-2.html) 2274 | [https://cwcaude.github.io/project/tutorial/2020/07/12/iOS-tweak-dev-3.html](https://cwcaude.github.io/project/tutorial/2020/07/12/iOS-tweak-dev-3.html) 2275 | [https://cwcaude.github.io/project/tutorial/2020/07/16/iOS-tweak-dev-4.html](https://cwcaude.github.io/project/tutorial/2020/07/16/iOS-tweak-dev-4.html) 2276 | --------------------------------------------------------------------------------