When dyld_decache fails on dyld_shared_cache_arm64, dsc_extractor saves our days

As you may have already known, dyld_decache by kennyTM fails on arm64 caches. Since arm64 devices are more popular these days, what’s the alternative of dyld_decache on dyld_shared_cache_arm64? Luckily, there is an answer: dsc_extractor, an open-sourced tool from Apple.
Now follow me on patching and compiling dsc_extractor so that it can decache dyld_shared_cache_arm64 as dyld_decache used to do.
P.S. You may need to manually install wget with homebrew.
###Download and extract dsc_extractor

192:~ snakeninny$ cd ~
192:~ snakeninny$ mkdir dsc_extractor
192:~ snakeninny$ cd dsc_extractor
192:dsc_extractor snakeninny$ wget http://opensource.apple.com/tarballs/dyld/dyld-210.2.3.tar.gz
--2015-10-17 12:14:44--  http://opensource.apple.com/tarballs/dyld/dyld-210.2.3.tar.gz
Resolving opensource.apple.com... 17.251.224.146
Connecting to opensource.apple.com|17.251.224.146|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 470411 (459K) [application/x-gzip]
Saving to: 'dyld-210.2.3.tar.gz'

dyld-210.2.3.tar.gz                 100%[==================================================================>] 459.39K   230KB/s   in 2.0s   

2015-10-17 12:14:46 (230 KB/s) - 'dyld-210.2.3.tar.gz' saved [470411/470411]

192:dsc_extractor snakeninny$ tar xvf dyld-210.2.3.tar.gz
x dyld-210.2.3/
x dyld-210.2.3/bin/
...

###Patch

192:dsc_extractor snakeninny$ cd dyld-210.2.3/launch-cache/
192:launch-cache snakeninny$ touch dsc_extractor.patch

The above command creates an empty file named dsc_extractor.patch under ~/dsc_extractor/dyld-210.2.3/launch-cache. Next copy the contents from here into dsc_extractor.patch and save the file (Note that if you wget or curl the patch file, there’d be an extra newline character at the end of the file, you’d have to remove it manually). Let’s continue:

192:launch-cache snakeninny$ patch < dsc_extractor.patch
patching file dsc_extractor.cpp
Hunk #4 succeeded at 485 with fuzz 2.

P.S. MD5 of dsc_extractor.patch should be b54a2e2c9556003a91b04009e9986dba. If you don’t get it correct, download this copy dsc_extractor.patch (1.1 KB)

###Compile

192:launch-cache snakeninny$ clang++ -o dsc_extractor dsc_extractor.cpp dsc_iterator.cpp
In file included from dsc_extractor.cpp:51:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ext/hash_map:212:5: warning: Use of
      the header <ext/hash_map> is deprecated. Migrate to <unordered_map> [-W#warnings]
#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
    ^
1 warning generated.

###Decache
Now there’s a binary dsc_extractor under ~/dsc_extractor/dyld-210.2.3/launch-cache. Let’s test if it works.

  1. Copy /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64 from iOS to OSX using iFunBox.
  2. Run /path/to/dsc_extractor /path/to/dyld_shared_cache_arm64 /path/to/decached/binaries/ on OSX, the output is shown below:
0/969
1/969
2/969
3/969
4/969
5/969
6/969
...

Done. Happy hacking iOS 9 :stuck_out_tongue_winking_eye:


References:

  1. http://lightbulbone.tumblr.com/post/56546834100/ios-shared-cache-extraction
  2. http://ant4g0nist.blogspot.com/2015/04/ios-shared-cache-extraction-to-solve.html
  3. dyld_shared_cache - iPhone Development Wiki
9 个赞

不是啊,是这个链接:https://gist.githubusercontent.com/lightbulbone/6092321/raw/305c9cc67a2379cdf852903de2d4b102c8e7bf4a/dsc_extractor.patch

1 个赞

麻烦您看下这个错误。非常感谢

求一个dyld_shared_cache_arm64 ios9.1的文件,谢谢。这个需要越狱的手机才能拿到。

Using the latest source code from Apple instead of the 210.2.3 here.
Only need to comment two lines instead of all those bullshit.
Thanks

2 个赞

patch<dsc_extractor.patch
patching file dsc_extractor.cpp
patch unexpectedly ends in middle of line
patch: **** unexpected end of file in patch
大神,咋弄啊~

编辑了一下帖子,上传了我这边没问题的dsc_extractor.patch,你可以下载了再试试

This is wonderful. Thank you very much.

Ethans-MacBook-Air:launch-cache Ethan$ patch < dsc_extractor.patch
patching file dsc_extractor.cpp
patch unexpectedly ends in middle of line
patch: **** unexpected end of file in patch
Ethans-MacBook-Air:launch-cache Ethan$

大神,帖子中的下载地址现在还能用吗?试了多次都运行失败,求帮助:sweat_smile:

直接从Apple官方下,把if 0改成if 1即可

2 个赞

解决了,谢谢:thumbsup::thumbsup::thumbsup:

Nice solution! You saved my hours.

Has anyone tried this Link Removed?

Unrelated to this post.

And don’t post ad here pls

这句话的表述有个问题:
原作者的是一共34行,应该是回车再另加一行,而不是删掉末尾多余的一行,再执行命令
patch < dsc_extractor.patch
才会正确输出。
如果删掉末尾执行patch < dsc_extractor.patch此命令,会出现

patch unexpectedly ends in middle of line
patch: **** unexpected end of file in patch

如上错误。

patch < dsc_extractor.patch
patching file dsc_extractor.cpp
Reversed (or previously applied) patch detected! Assume -R? [n] n
Apply anyway? [n] n
Skipping patch.
4 out of 4 hunks ignored – saving rejects to file dsc_extractor.cpp.rej

what does this mean? how can I slove this?

@snakeninny 我按照你的步骤操作的,dsc_extractor可执行文件也生成了,为什么报了这个错误
Error: dyld_shared_cache_iterate_segments_with_slide failed.
dyld_shared_cache_extract_dylibs_progress() => -1

自己看看assert是代码里的哪里挂的。这个东西一共也没多少行代码

https://opensource.apple.com/source/dyld/dyld-421.2/launch-cache/dsc_extractor.cpp.auto.html

// 这里改下
#if 1
// test program
#include <stdio.h>
#include <stddef.h>
#include <dlfcn.h>


typedef int (*extractor_proc)(const char* shared_cache_file_path, const char* extraction_root_path,
													void (^progress)(unsigned current, unsigned total));

int main(int argc, const char* argv[])
{
	if ( argc != 3 ) {
		fprintf(stderr, "usage: dsc_extractor <path-to-cache-file> <path-to-device-dir>\n");
		return 1;
	}
	
	//void* handle = dlopen("/Volumes/my/src/dyld/build/Debug/dsc_extractor.bundle", RTLD_LAZY);
	void* handle = dlopen("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/lib/dsc_extractor.bundle", RTLD_LAZY);
	if ( handle == NULL ) {
		fprintf(stderr, "dsc_extractor.bundle could not be loaded\n");
		return 1;
	}
	
	extractor_proc proc = (extractor_proc)dlsym(handle, "dyld_shared_cache_extract_dylibs_progress");
	if ( proc == NULL ) {
		fprintf(stderr, "dsc_extractor.bundle did not have dyld_shared_cache_extract_dylibs_progress symbol\n");
		return 1;
	}

	//这里需要修改否则用的是系统的, 不是你自己编译的
	int result = dyld_shared_cache_extract_dylibs_progress(argv[1], argv[2], ^(unsigned c, unsigned total) { printf("%d/%d\n", c, total); } );
	fprintf(stderr, "dyld_shared_cache_extract_dylibs_progress() => %d\n", result);
	return 0;
}


#endif

请问现在最新的应该下载哪一个包解压。解决iOS10.2的缓存文件