通过逆向工程破解书籍APP中的乱序算法

作者: 秦砖 | 来源:发表于2016-12-04 20:28 被阅读225次

背景

在AppStore中有一款网络小说类的APP,这里就不提App名称了,毕竟是破解别人的应用。现将该小说的txt文件通过抓包、爬虫等途径搞定后,才发现该txt文件是不可读的,它里面的内容顺序是经过程序按照特定算法打乱了,这里给出一个样本文件。那么就要通过逆向工程得出正确的文本内容了。

LLDB

使用lldb与debugserver对应用可执行文件进行动态分析,具体的使用步骤这里就不在详细说明了,这里给出一个参考链接,文章说的很详细。
还要提的一点是,xcode8中的lldb是有BUG的,它会导致断点后显示出来的汇编代码与ida显示的代码不一致,具体参考下图:


xcode8中lldb触发断点显示的汇编
同样地址下ida显示的汇编

如果你也碰到了类似的BUG,请换用xcode5带的lldb即可。

乱序算法

通过逆向分析,我们能够定位到算法的具体位置-[PageViewController analysisChapterContent]。这里给出几段关键的汇编代码:

//这段代码主要是定位txt文件最后一部分正常顺序文件的起始点,并将其保存到var_84内存中
loc_43DCE                               ; CODE XREF: -[PageViewController analysisChapterContent]+162�j
__text:00043DCE                 MOV R0,     #(selRef_length - 0x43DDA)
__text:00043DD6                 ADD             R0, PC ; selRef_length
__text:00043DD8                 LDR             R1, [R0] ; "length"
__text:00043DDA                 MOV             R0, R4
__text:00043DDC                 STR             R1, [SP,#0xE0+var_78]
__text:00043DDE                 BLX.W           _objc_msgSend
__text:00043DE2                 MOV             R8, R0
__text:00043DE4                 MOV             R0, #0xBA2E8BA3
__text:00043DEC                 UMULL.W         R0, R2, R8, R0
__text:00043DF0                 MOV             R0, #(selRef_substringFromIndex_ - 0x43DFC)
__text:00043DF8                 ADD             R0, PC ; selRef_substringFromIndex_
__text:00043DFA                 LDR             R1, [R0] ; "substringFromIndex:"
__text:00043DFC                 LSRS            R0, R2, #3
__text:00043DFE                 STR             R1, [SP,#0xE0+var_CC]
__text:00043E00                 ADD.W           R0, R0, R0,LSL#2
__text:00043E04                 LSLS            R2, R0, #1
__text:00043E06                 MOV             R0, R4
__text:00043E08                 STR             R2, [SP,#0xE0+var_84]
__text:00043E0A                 BLX.W           _objc_msgSend

从这段代码里大致能分析出定位起始点的算法:

(文本长度)* 0xBA2E8BA3 = AB;//这里A表示64位结果的前32位
 起始点 = (A >> 3) * 5 * 2

但至于这种算法的原理是什么,为什么为这样,0xBA2E8BA3是什么东西,我就搞不明白了,哪位大牛能给我细说下吗?转换成下面的OC代码:

-(NSUInteger)calculateEnd:(NSUInteger)length
{
    uint32_t strand = 0xba2e8ba3;
    uint64_t mul = (uint64_t)strand * (uint64_t)length;
    uint64_t and = 0xffffffff00000000;
    uint64_t one = mul & and;
    uint32_t result = (uint32_t)(one >> 32);
    uint32_t point = (result >> 3) * 10;
    return point;
}

另外一段关键汇编代码,主要用于从txt文件起点开始分10段文本各自拼接内容,每一段有各自的拼接算法,进而形成可读的内容。

__text:00043ED2 loc_43ED2                               ; CODE XREF: -[PageViewController analysisChapterContent]+372�j
__text:00043ED2                 MOV             R0, R4
__text:00043ED4                 MOV             R1, R8
__text:00043ED6                 MOV             R2, R10
__text:00043ED8                 MOVS            R3, #1
__text:00043EDA                 BLX.W           _objc_msgSend
__text:00043EDE                 MOV             R2, R0
__text:00043EE0                 LDR             R0, [SP,#0xE0+var_74]
__text:00043EE2                 MOV             R1, R6
__text:00043EE4                 BLX.W           _objc_msgSend
__text:00043EE8                 ADD.W           R2, R10, #1
__text:00043EEC                 MOV             R0, R4
__text:00043EEE                 MOV             R1, R8
__text:00043EF0                 MOVS            R3, #1
__text:00043EF2                 BLX.W           _objc_msgSend
__text:00043EF6                 MOV             R2, R0
__text:00043EF8                 LDR             R0, [SP,#0xE0+var_5C]
__text:00043EFA                 MOV             R1, R6
__text:00043EFC                 BLX.W           _objc_msgSend
__text:00043F00                 ADD.W           R2, R10, #2
__text:00043F04                 MOV             R0, R4
__text:00043F06                 MOV             R1, R8
__text:00043F08                 MOVS            R3, #1
__text:00043F0A                 BLX.W           _objc_msgSend
__text:00043F0E                 MOV             R2, R0
__text:00043F10                 LDR             R0, [SP,#0xE0+var_68]
__text:00043F12                 MOV             R1, R5
__text:00043F14                 MOVS            R3, #0
__text:00043F16                 BLX.W           _objc_msgSend
__text:00043F1A                 ADD.W           R2, R10, #3
__text:00043F1E                 MOV             R0, R4
__text:00043F20                 MOV             R1, R8
__text:00043F22                 MOVS            R3, #1
__text:00043F24                 BLX.W           _objc_msgSend
__text:00043F28                 MOV             R2, R0
__text:00043F2A                 LDR             R0, [SP,#0xE0+var_60]
__text:00043F2C                 MOV             R1, R5
__text:00043F2E                 MOVS            R3, #0
__text:00043F30                 BLX.W           _objc_msgSend
__text:00043F34                 ADD.W           R2, R10, #4
__text:00043F38                 MOV             R0, R4
__text:00043F3A                 MOV             R1, R8
__text:00043F3C                 MOVS            R3, #1
__text:00043F3E                 BLX.W           _objc_msgSend
__text:00043F42                 MOV             R2, R0
__text:00043F44                 LDR             R0, [SP,#0xE0+var_7C]
__text:00043F46                 MOV             R1, R5
__text:00043F48                 MOVS            R3, #0
__text:00043F4A                 BLX.W           _objc_msgSend
__text:00043F4E                 ADD.W           R2, R10, #5
__text:00043F52                 MOV             R0, R4
__text:00043F54                 MOV             R1, R8
__text:00043F56                 MOVS            R3, #1
__text:00043F58                 BLX.W           _objc_msgSend
__text:00043F5C                 MOV             R2, R0
__text:00043F5E                 MOV             R0, R11
__text:00043F60                 MOV             R1, R5
__text:00043F62                 MOVS            R3, #0
__text:00043F64                 BLX.W           _objc_msgSend
__text:00043F68                 ADD.W           R2, R10, #6
__text:00043F6C                 MOV             R0, R4
__text:00043F6E                 MOV             R1, R8
__text:00043F70                 MOVS            R3, #1
__text:00043F72                 BLX.W           _objc_msgSend
__text:00043F76                 MOV             R2, R0
__text:00043F78                 LDR             R0, [SP,#0xE0+var_80]
__text:00043F7A                 MOV             R1, R6
__text:00043F7C                 BLX.W           _objc_msgSend
__text:00043F80                 ADD.W           R2, R10, #7
__text:00043F84                 MOV             R0, R4
__text:00043F86                 MOV             R1, R8
__text:00043F88                 MOVS            R3, #1
__text:00043F8A                 BLX.W           _objc_msgSend
__text:00043F8E                 MOV             R2, R0
__text:00043F90                 LDR             R0, [SP,#0xE0+var_70]
__text:00043F92                 MOV             R1, R5
__text:00043F94                 MOVS            R3, #0
__text:00043F96                 BLX.W           _objc_msgSend
__text:00043F9A                 ADD.W           R2, R10, #8
__text:00043F9E                 MOV             R0, R4
__text:00043FA0                 MOV             R1, R8
__text:00043FA2                 MOVS            R3, #1
__text:00043FA4                 BLX.W           _objc_msgSend
__text:00043FA8                 MOV             R2, R0
__text:00043FAA                 LDR             R0, [SP,#0xE0+var_6C]
__text:00043FAC                 MOV             R1, R6
__text:00043FAE                 BLX.W           _objc_msgSend
__text:00043FB2                 ADD.W           R2, R10, #9
__text:00043FB6                 MOV             R0, R4
__text:00043FB8                 MOV             R1, R8
__text:00043FBA                 MOVS            R3, #1
__text:00043FBC                 BLX.W           _objc_msgSend
__text:00043FC0                 MOV             R2, R0
__text:00043FC2                 LDR             R0, [SP,#0xE0+var_64]
__text:00043FC4                 MOV             R1, R6
__text:00043FC6                 BLX.W           _objc_msgSend
__text:00043FCA                 ADD.W           R10, R10, #0xA
__text:00043FCE                 LDR             R0, [SP,#0xE0+var_84]
__text:00043FD0                 CMP             R10, R0
__text:00043FD2                 BLT.W           loc_43ED2
__text:00043FD6
__text:00043FD6 loc_43FD6

这段代码可以等价为下面的OC代码:

//end表示的是上段代码中获取到的正常顺序起始点
int max = end / 10;
for (int time = 0; time < max; time++) {
  for (int index = 0; index < 10; index++) {
    NSUInteger len = 1;
    NSUInteger location = index + time * 10;
    NSRange range = NSMakeRange(location, len);
    NSString* character = [content substringWithRange:range];
            
    if (index == 0 || index == 1 || index == 6 || index == 8 || index == 9) {
        NSMutableString* line = [lineArray objectAtIndex:index];
        [line appendString:character];
    }else if (index == 2 || index == 3 || index == 4 || index == 5 || index == 7){
        NSMutableString* line = [lineArray objectAtIndex:index];
        [line insertString:character atIndex:0];
    }
  }
}

最终将获取到的所有正常顺序的字符串拼接到一起,便能够正确的解析整个txt文本,产生可读的小说内容,打印LOG如下:


解析成功的小说文本

最后的话

代码虽然不多,但汇编代码看起来有点头大,花了两天时间,脑子很混乱,进而文章写的也有点乱了。如果有同学对这方面感兴趣,可以私下聊聊。

相关文章

网友评论

    本文标题:通过逆向工程破解书籍APP中的乱序算法

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