iOS 逆向编程(二十三)dsc_extractor 动态库提取器

2,740 阅读2分钟

一、简介

  • 既然我们是通过 dyld 加载进来的,并生成了 dyld_shared_cache_armX 这的资源包,那么它也自然支持解包了。

二、生成提取器指令

  • 我们将下在的 dyld 项目打开,找到里面的 dsc_extractor.cpp,这个是一个 c++ 编写的文件,从单词就能看出来是提取器的意思。

  • 打开命令行,cd 到这个 dsc_extractor.cpp 文件夹,然后我们需要通过 clang++dsc_extractor.cpp 生成可执行指令。

    dengzemiaodeMacBook-Pro:~ dengzemiao$ cd /Users/dengzemiao/Downloads/dyld-832.7.1/dyld3/shared-cache/
    

    然后直接通过 clang++ 进行编译,结果报错,因为里面包含可一些不可编译进来的文件,我们需要删除。

    dengzemiaodeMacBook-Pro:shared-cache dengzemiao$ clang++ dsc_extractor.cpp
    dsc_extractor.cpp:40:10: fatal error: 'CodeSigningTypes.h' file not found
    #include "CodeSigningTypes.h"
             ^~~~~~~~~~~~~~~~~~~~
    1 error generated.
    

    我们只需要红色框内的代码即可其他代码全部删掉,只有这一段代码是用来提取的,这段代码在文件最底部,直接滚到底部就能找到。

    删除之后,只要留这个就够了

    但是我这边删掉上面的代码之后 fprintfstderr 报错,我干脆就注释了,它只是输出。

    dsc_extractor.cpp 提取代码:

    // 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 = (*proc)(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;
    }
    

    然后执行命令,获得 dsc_extractor 提取器指令。

    // dsc_extractor 是生成文件名称
    $ clang++ -o dsc_extractor dsc_extractor.cpp
    

三、dsc_extractor 取器指令使用

  • dsc_extractor 指令怎么使用

    $ dsc_extractor 动态库文件路径 提取出来之后存放路径
    
  • 将这个指令文件与之前获取到的 dyld_shared_cache_armX 文件放到一起,方便使用。

  • 执行指令,然后就提取出来了动态库包

    $ ./dsc_extractor dyld_shared_cache_arm64 arm64
    

  • 然后就可以拖到 Hopper Disassmbler 里面进行分析了。