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

背景

在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如下:


解析成功的小说文本

最后的话

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,077评论 4 62
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,922评论 25 707
  • 當愛情還在黑暗精神中糾纏不休的時候 軀體卻早已擦肩而過⋯ 如果愛情不能撕扯著找回各自的肉體 人生終究是一場色加一場...
    宗源如是说阅读 277评论 0 0
  • 1、牵扯重大的事要请示领导,不要自以为简单,擅自做决定! 2、不谋全局者,不足以谋一域;不谋万世者,不足以谋一时。...
    woniu阅读 226评论 2 0
  • 我家最近的邻居,是对面的细板屋。除了“禾咀”每天来我家坐外,还有一个每天围着我叫“爱大大”的奇奇。 奇奇的爸爸大留...
    小鸟笑笑阅读 485评论 -1 4