https://iphonedev.wiki/api.php?action=feedcontributions&user=Przemub&feedformat=atomiPhone Development Wiki - User contributions [en]2024-03-28T10:10:14ZUser contributionsMediaWiki 1.39.6https://iphonedev.wiki/index.php?title=Dyld_shared_cache&diff=5710Dyld shared cache2021-06-14T01:10:47Z<p>Przemub: update_dyld_shared_cache deprecated with macOS 11</p>
<hr />
<div>{{DISPLAYTITLE:dyld_shared_cache}}<br />
<br />
Since iPhone OS 3.1, all system (private and public) libraries have been combined into a big cache file to improve performance. The original files are redundant and thus eliminated from the system.<br />
<br />
If you're looking for binaries or libraries inside of <tt>[http://theiphonewiki.com/wiki//System/Library/Frameworks /System/Library/Frameworks]</tt> or <tt>/System/Library/PrivateFrameworks</tt> (or other directories) and can't, this is why.<br />
<br />
As of iOS 13.5 application code is now in frameworks in the shared cache. The binaries you see in <tt>/Applications</tt> or <tt>/private/var/staged_system_apps</tt> are now just shims, so if you attempt to class-dump them it will error out as no ObjC section will be found.<br />
<br />
OS X, along with any other *OS released by apple also uses a shared cache. Unlike iOS, macOS before 11 Big Sur used to ship with the source binaries still on-disk, particularly so it can be updated with [https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/update_dyld_shared_cache.1.html update_dyld_shared_cache]. Starting with macOS 11, update_dyld_shared_cache is deprecated and, as in iOS, the only copy of the libraries is in the "cache". The cache is only vaguely documented in dyld man pages.<br />
<br />
== Obtaining a shared cache ==<br />
<br />
The easiest method for getting a dyld_shared_cache is as such:<br />
<br />
# Download or locate an ipsw for the target version and device <br />
# Rename it to a .zip, extract, and locate the largest .dmg <br />
# Mount the dmg and navigate to /System/Library/Caches/com.apple.dyld/ <br />
# Copy the dyld_shared_cache to your machine. <br />
<br />
<br />
== Extracting Frameworks and Libraries. ==<br />
<br />
Since iOS 8, the SDK no longer includes extracted frameworks. The only way to obtain the libraries running on your device is via extraction.<br />
<br />
Extracting the shared cache is useful in a few situations:<br />
<br />
* Linking against a framework or library not available in the public SDK<br />
* Using class-dump or similar tools to analyze Private Frameworks.<br />
* Reverse engineering the code in private or public frameworks within iOS.<br />
<br />
[https://github.com/arandomdev/DyldExtractor DyldExtractor] is currently (as of iOS 14) capable of extracting nearly perfect frameworks from the shared cache. However, these cannot yet be loaded by dyld, as more work needs done.<br />
<br />
== Shared cache static analysis == <br />
<br />
=== Simulator Runtime Frameworks ===<br />
<br />
''Can someone with an M1 mac comment on this?''<br />
<br />
The simulator runtime generated by Xcode includes fully symbolicated, perfect x64 binaries for Private and Public frameworks. For most shared_cache analysis, unless you own IDA 7.5 or the frameworks you are looking for are not available in simulators, you are fine with these. They're located under <code>/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot</code> (Xcode 11 and higher) or <code>/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot</code> (Xcode 10 and lower).<br />
<br />
=== Disassemblers capable of extraction ===<br />
<br />
Using [https://github.com/arandomdev/DyldExtractor DyldExtractor] is recommended for extraction. The only tool capable of extracting on its own is IDA Pro 7.5, and using an extractor can still be easier.<br />
<br />
==== IDA Pro ====<br />
<br />
IDA 7.5 includes a plethora of tools that make working with the dsc much more tolerable. It entirely eliminates the need for extraction or third-party scripts to fix output.<br />
<br />
Details and instructions on using the integrated tools can be found on the [[IDA Pro]] page. If you own a copy, check the IDA page on this wiki for a guide on using it.<br />
<br />
==== Hopper ====<br />
<br />
Hopper is capable of loading singular modules from the shared cache. It does not fix references and as such produces mostly useless output.<br />
<br />
It also allows loading the entire shared cache, but tends to crash when loading it. It's not worth your time.<br />
<br />
==== Ghidra ====<br />
<br />
Ghidra is capable of loading the shared cache<br />
<br />
''More information is needed here''<br />
<br />
There are [https://github.com/NationalSecurityAgency/ghidra/issues/682 known issues] with loading a shared cache. <br />
<br />
=== Standalone tools ===<br />
<br />
Working on current iOS versions:<br />
<br />
* [https://github.com/arandomdev/DyldExtractor DyldExtractor]. Python project capable of extracting and heavily fixing up frameworks from the shared cache. This tool produces nearly perfect output on current iOS versions. <br />
<br />
"Working":<br />
<br />
* [http://opensource.apple.com/source/dyld/ dsc_extractor (source code)]. More info [https://gist.github.com/NSExceptional/85527151eeec4b0640187a0a165da1cd here]. It produces the best results among all tools, but without branch islands workaround. Do note this is the exact same output provided by XCode automatically.<br />
<br />
Tools for previous iOS versions:<br />
<br />
* [https://github.com/kennytm/Miscellaneous/downloads dyld_decache] by KennyTM~ to extract these dylibs.<br />
* [https://gist.github.com/455086/ DySlim] by comex to mount the whole cache file on Mac OS X.<br />
* [https://github.com/phoenix3200/decache decache] by phoenixdev to nearly perfectly extract dylibs from iOS <= 6 cache file.<br />
* [http://www.newosxbook.com/index.php?page=downloads jtool] is another option starting from iOS 8. <br />
* [https://github.com/comex/imaon2 yasce] by comex is/was the best option for iOS 8 (and above), but you will need a nightly build version of rust; something like "rustc 1.9.0-nightly (339a409bf 2016-03-01)".<br />
* [https://github.com/macmade/dyld_cache_extract dyld_cache_extract] by macmade that works on macOS and provides a complete GUI. Clone repo and do 'git submodule update --remote' before buidling. It was reported to be not working on iOS 10.2's dyld_shared_cache_armv7s; gave a 561.1MB executable file.<br />
<br />
== Cache location ==<br />
<br />
The cache is located in <tt>/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX</tt>, where X can be:<br />
<br />
{| class="wikitable"<br />
|-<br />
! X<br />
! Device ARM Architecture<br />
|-<br />
| v6<br />
| ARMv6<br />
|-<br />
| v7<br />
| rowspan="3" | ARMv7<br />
|-<br />
| v7s<br />
|-<br />
| v7k<br />
|-<br />
| 64<br />
| ARMv8<br />
|-<br />
| 64e<br />
| ARMv8.3<br />
|}<br />
<br />
== "Development" vs "Release" caches ==<br />
<br />
=== Creation/background ===<br />
<br />
The source code for the tool used at apple is here:<br />
<br />
https://opensource.apple.com/source/dyld/dyld-733.6/dyld3/shared-cache/CacheBuilder.cpp.auto.html<br />
<br />
Specifically linked is the file responsible for determining if a development build is being created, and if so to avoid removing stubs. This is likely done to make debugging issues in frameworks much less painful.<br />
<br />
Evidence of these builds is present in dyld source (''link to a github mirror here please''), and they're likely used in internal iOS builds.<br />
<br />
<br />
=== Other Disassemblers ===<br />
<br />
''Information on how other disassemblers interact with these caches is needed.''<br />
<br />
<br />
=== Example usage for jtool ===<br />
<br />
To extract a specific binary from the cache ("UIKit" can be replaced with a different framework or library):<br />
<br />
<source lang=bash>jtool -extract UIKit path/to/dyld_shared_cache</source><br />
<br />
An example of one way to dump all the binaries at once (be careful with this, it creates huge files):<br />
<br />
<source lang=bash><br />
cache=dyld_shared_cache_arm64<br />
mkdir -p extracted && jtool -lv $cache | cut -c 24- | tail +5 | while read line; do mkdir -p extracted/"$(dirname "$line")"; jtool -extract $line $cache; mv $cache."$(basename "$line")" extracted/$line; done<br />
</source><br />
<br />
==== Problems with jtool ====<br />
<br />
Please be aware that decache produces currently (16.04.15) better and more usable results then jtool, as jtool fails to resolve and fix the "uniqued" objectiv c selectors correctly.<br />
<br />
Apple "uniques" objectiv c selectors, such as "alloc" (alloc is used almost everywhere), which are used in more then one place, into a single one. When extracting an image from the cache, the address of such a shared selector will most likely not be in the extracted image anymore, so this needs to fixed, which jtool apparently fails to do. (For more information: http://opensource.apple.com/source/dyld/dyld-132.13/launch-cache/update_dyld_shared_cache.cpp, look at the class ObjCSelectorUniquer)<br />
<br />
==== Not working since iOS 11 ====<br />
<br />
jtool2 is the newer version this user reports it not working on the iOS 11 shared cache - shows a warning "File is likely truncated (or header corrupt?)" and then doesn't get past "LC_DYLD_INFO..." http://newosxbook.com/forum/viewtopic.php?f=3&t=19577&start=50#p24183 Still same error exists on the cache from iOS 13.<br />
<br />
<source lang=bash><br />
$ ./jtool2 -e Stocks ./dyld_shared_cache_arm64 <br />
Warning: File is likely truncated (or header corrupt?) Binding opcodes falls outside file<br />
Warning: File is likely truncated (or header corrupt?) Binding opcodes falls outside file<br />
Warning: File is likely truncated (or header corrupt?) LC_FUNCTION_STARTS falls outside file<br />
0x176d9000-0x17731000 __TEXT (360448 bytes)<br />
0x2ccc2070-0x2ccd54a8 __DATA_CONST (78904 bytes)<br />
0x30571f60-0x30575f60 __DATA (16384 bytes)<br />
0x314c9a28-0x314ca000 __DATA_DIRTY (1496 bytes)<br />
0x316b3000-0x37064000 __LINKEDIT (94048256 bytes)<br />
0x31e3c4d0-0x31e3eaf8 Exports (9768 bytes)<br />
0x34689f18-0x346912f8 Symbol Table (29664 bytes)<br />
0x35a46500-0x35a46b90 Function Starts (1680 bytes)<br />
0x35bb1930-0x35bb1960 Data In Code (48 bytes)<br />
0x35d66710-0x37029aba String Table (19674026 bytes)<br />
LC_DYLD_INFO...<br />
</source><br />
<br />
== Class dumping ==<br />
<br />
See [[Reverse_Engineering_Tools#class-dump.2C_class_dump_z.2C_classdump-dyld|this section of Reverse Engineering Tools]].<br />
<br />
== External Links ==<br />
<br />
* [http://blog.howett.net/?p=75 Cache or Check?] — an analysis of the dyld_shared_cache system by D. Howett.<br />
* [https://github.com/deepinstinct/dsc_fix dsc_fix] — an IDA script that aids in reverse engineering dyld_shared_cache libraries</div>Przemub