美文网首页iOS程序猿程序员iOS学习笔记
OC 字符匹配小技巧 (模板构造)

OC 字符匹配小技巧 (模板构造)

作者: CoderHG | 来源:发表于2018-10-25 23:40 被阅读146次

    遇到一个小需求: 给一个从 App Store 下载的 ipa 文件重签名。 这个需求有点荒谬,但是今天为了做一个实验,于是就下载了一个线上的 ipa 文件,然后使用自己的证书重新签名。

    接下来就简单的介绍一下,在什么也不操作的情况下如何使用自己的证书重新签名。具体分成一下4个步骤:

      1. 砸壳。
      1. 给除可执行文件之外的 MachO文件的签名。
      1. 给.app 文件夹签名。
      1. 重新压成 zip 文件。

    关于以上的4个步骤,都不是当前简书所要介绍的重点,具体的如何操作,请看我的另一篇简书:【重组 IPA (打包再签名) - 窥打包签名流程】。当前简书的重点是第二步:如何快速的找到 除可执行文件之外的 MachO文件?先直观的看一下这些文件在什么地方:

    image.png

    如果是正向开发的话,打包的时候回自动的将使用到的这个动态库放到这个 Frameworks 文件夹中。

    这里可以手动的一个一个的将某个动态库的 MachO 文件路径拖到终端,然后执行签名命令, 这当然是最笨的方法。用一个高大上的方式就是代码实现。具体的规律是:所有的文件都在 Frameworks 中,某个动态库对应的 MachO 文件名等于动态库名称。核心代码如下:

    /**
     查找所有动态库的 MachO 文件路径
    
     @param frameworksPath Frameworks的路径
     @return 返回结果
     */
    - (NSArray*)signPathsWithFrameworksPath:(NSString*)frameworksPath {
        // 所有的子文件路径
        NSArray* subPaths = [[NSFileManager defaultManager] subpathsAtPath:frameworksPath];
        // 定义一个模板
        NSString* const templateString = @"#content#.framework/#content#";
        // 所有的匹配的路径
        NSMutableArray* signPaths = [NSMutableArray array];
        for (NSString* subPath in subPaths) {
            // 子路径的后段
            NSString* lastPathComponent = subPath.lastPathComponent;
            // 按照模本匹配出的字符串
            NSString* matchString = [templateString stringByReplacingOccurrencesOfString:@"#content#" withString:lastPathComponent];
            // 如果匹配出来的与当前的 subPath 相等, 那就是我们所要的
            if ([matchString isEqualToString:subPath]) {
                // 加上签名前缀
                NSString* signStrig = [NSString stringWithFormat:@"codesign -fs 283(证书的唯一编号)3C15E ./%@", matchString];
                [signPaths addObject:signStrig];
            }
        }
        // 这里的结果就可以直接放到一个 sh 文件中,直接执行就可以了
        return signPaths.copy;
    }
    

    以上的代码,看起来还是很直观的。比较关键的一句是:

    // 定义一个模板
    NSString* const templateString = @"#content#.framework/#content#";
    

    这只是一个简单的例子,如果使用其它的方法,代码量也相差不大,但是在有的场合使用这样的模板还是挺方便的。比如前不久做了一个代码混淆的功能,其中有一个添加垃圾代码的功能。添加垃圾代码有两个核心的功能是:方法实现体与调用方法体。
    可以先思考一下,如果不使用模板的话,那代码会很复杂,各种的字符串拼接。如果使用了模板,我们可以直接在模板中做替换即可。比如我的其中的一个方法调用模板是这样定义的:

    // 调用模板
    #define CodeODictionaryStringArrayCall @"[self #paramString#:#paramStringValue# #paramArray#:#paramArrayValue#];";
    

    这是一个字符串的宏定义,当然也可以写成字符串常量。我简单的介绍一下这个方法调用模板结构:都是 self 调用,第一个参数是一个字符串,但是 SEL 段是随机生成的,传的参数也是随机生成的数组,第二个参数不用解释应该就懂。
    如果不用模板,那就会使用各种的拼接,代码看起来还特别的凌乱,尤其的随机生成方法实现体。在这里也说明一个问题,所谓的垃圾代码的随机生成,也并非完全的随机,再怎么随机,都应该是有一定的套路的,至少要保证随机生成的代码运行不报错吧。

    到这里,当前简书想要介绍的核心内容就结束了。上面的内容有点乱了,copy 一下标题吧:OC 字符匹配小技巧 (模板构造)

    推荐两篇文章:

    1、我的简书 重组 IPA (打包再签名) - 窥打包签名流程
    2、 You should blog even if you have no readers

    添加于 2018-11-07

    今天在看 喵神VVDocumenter 发现,他在文档字符处理的时候,使用了另一种思路,感觉挺棒的,所以想借助这篇简书,直接分享一下。
    这个工具的功能是自动生成注释模板:或枚举、或结构体、或方法。默认由 /// 触发,核心代码在 -[VVDocumenterManager textStorageDidChange:] 中:

    image.png

    在喵神的这段代码中,借助 NSPasteboard 做文本的替换,可谓 绝配

    相关文章

      网友评论

      • CoderHG:文中主要是使用 OC 的方式读取所有的文件,然后在签名,这个方案的步骤很繁琐。建议看看我的这篇简书,实现方式更高大上。 没有源码的签名与打包(Python+command):https://www.jianshu.com/p/b87ca19091cc

      本文标题:OC 字符匹配小技巧 (模板构造)

      本文链接:https://www.haomeiwen.com/subject/xvcrnftx.html