破解《Reveal》

Reveal简介

Reveal能查看iOS App的视图布局,而且能在App运行时进行视图调试。

破解过程(本教程使用的Reveal版本为21)

下载下来打开后,出现一个Welcome窗口挡在上面

Welcome

想看看这个Welcome窗口属于哪个类,考虑用Xcode的View UI Hierarchy
打开XcodeFile -> New -> Project...,选择 macOS -> Cocoa Framework
工程创建好后,Debug -> Attach to Process,选择Reveal
Could not attach

Attach失败,应该是开启了反调试。

hopper打开Reveal.app/Contents/MacOS/Reveal,搜索ptrace

                     imp___stubs__ptrace:
0000000100442380         jmp        qword [_ptrace_ptr]                         ; _ptrace, CODE XREF=EntryPoint+23

x查找引用,跳到调用的地方:

                     EntryPoint:
00000001003df9bb         push       rbp
00000001003df9bc         mov        rbp, rsp
00000001003df9bf         push       r14
00000001003df9c1         push       rbx
00000001003df9c2         mov        r14, rsi
00000001003df9c5         mov        ebx, edi
00000001003df9c7         mov        edi, 0x1f                                   ; argument "request" for method imp___stubs__ptrace
00000001003df9cc         xor        esi, esi                                    ; argument "pid" for method imp___stubs__ptrace
00000001003df9ce         xor        edx, edx                                    ; argument "addr" for method imp___stubs__ptrace
00000001003df9d0         xor        ecx, ecx                                    ; argument "data" for method imp___stubs__ptrace
00000001003df9d2         call       imp___stubs__ptrace
00000001003df9d7         mov        edi, ebx                                    ; argument "argc" for method imp___stubs__NSApplicationMain
00000001003df9d9         mov        rsi, r14                                    ; argument "argv" for method imp___stubs__NSApplicationMain
00000001003df9dc         pop        rbx
00000001003df9dd         pop        r14
00000001003df9df         pop        rbp
00000001003df9e0         jmp        imp___stubs__NSApplicationMain

这里明显就是main函数,直接jmp到NSApplicationMain即可:
选中函数的第一条指令,Modify -> Assemble Instruction...,输入jmp imp___stubs__NSApplicationMain

                     EntryPoint:
00000001003df9bb         jmp        imp___stubs__NSApplicationMain

修改完成后command+shift+e -> Remove Signature -> Save -> Replace,重新打开Reveal,此时Xcode Debug -> Attach to Process 已经能连接上了,但是报损坏:

damaged

应该是验证签名了,hopper搜索SecStaticCodeCheckValidity,没有搜索到,可能是隐藏了符号。Xcode添加Symbolic Breakpoint...试试,果然没有失望:

(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x00007fff3e0681aa Security`SecStaticCodeCheckValidity
    frame #1: 0x000000010cb02191 Reveal`___lldb_unnamed_symbol16110$$Reveal + 136
(lldb) image lookup --address 0x000000010cb02191
      Address: Reveal[0x0000000100418191] (Reveal.__TEXT.__text + 4281425)
      Summary: Reveal`___lldb_unnamed_symbol16110$$Reveal + 136

通过堆栈,找到验证签名的地方为0x0000000100418191 。回到hopperg -> 0x0000000100418191 -> Go,查看伪代码:

int sub_100418109() {
    r14 = [*0x100609aa0 retain];
    *var_30 = 0x0;
    r15 = (*0x100609a00)(0x0, var_30);
    if (r15 == 0x0) {
            *var_28 = 0x0;
            r15 = (*0x100609a08)(var_30, 0x0, var_28);
            if (r15 == 0x0) {
                    *var_20 = 0x0;
                    r15 = (*0x100609a10)(r14, 0x0, var_20);
                    if (r15 == 0x0) {
                            r15 = (*0x100609a18)(var_28, 0x1, var_20);
                    }
                    rdi = var_20;
                    if (rdi != 0x0) {
                            CFRelease(rdi);
                    }
            }
            rdi = var_28;
            if (rdi != 0x0) {
                    CFRelease(rdi);
            }
    }
    rdi = var_30;
    if (rdi != 0x0) {
            CFRelease(rdi);
    }
    [r14 release];
    rax = r15 == 0x0 ? 0x1 : 0x0;
    return rax;
}

这里出现了几个地址:0x100609aa0、0x100609a00、0x100609a08、0x100609a10、0x100609a18

(lldb) image list
[  0] D63C46A4-4A6C-3559-BF02-9A41B3AAF2CB 0x000000010c6ea000 /var/folders/nn/xpy1hqrn6s19d6dp4r69m4hr0000gn/T/AppTranslocation/FCEBF1A4-C20B-4140-AFAB-B357ACCCA528/d/Reveal.app/Contents/MacOS/Reveal
(lldb) memory read --size 8 --format x ’0x100609aa0+0xc6ea000‘
0x10ccf3aa0: 0x00007ffa52002a90 0x0000000000000000
(lldb) po 0x7ffa52002a90
anchor apple generic and identifier = "com.ittybittyapps.Reveal2" and certificate 1[field.1.2.840.113635.100.6.2.6] exists and (certificate leaf[field.1.2.840.113635.100.6.1.13] exists or certificate leaf[field.1.2.840.113635.100.6.1.14] exists) and certificate leaf[subject.OU] = "KBY3G4JPGC"

(lldb) memory read --size 8 --format x ’0x100609a00+0xc6ea000‘
0x10ccf3a00: 0x00007fff3e0608db 0x00007fff3e060df6
0x10ccf3a10: 0x00007fff3e06596a 0x00007fff3e0681aa
(lldb) image lookup --address 0x00007fff3e0608db
      Address: Security[0x000000000015c8db] (Security.__TEXT.__text + 1421739)
      Summary: Security`SecCodeCopySelf
(lldb) image lookup --address 0x00007fff3e060df6
      Address: Security[0x000000000015cdf6] (Security.__TEXT.__text + 1423046)
      Summary: Security`SecCodeCopyStaticCode
(lldb) image lookup --address 0x00007fff3e06596a
      Address: Security[0x000000000016196a] (Security.__TEXT.__text + 1442362)
      Summary: Security`SecRequirementCreateWithString
(lldb) image lookup --address 0x00007fff3e0681aa
      Address: Security[0x00000000001641aa] (Security.__TEXT.__text + 1452666)
      Summary: Security`SecStaticCodeCheckValidity

找到了对应关系,简单整理就可以得出源码为:

bool sub_100418109() {
    CFStringRef text = (__bridge CFStringRef)@"anchor apple generic and identifier = \"com.ittybittyapps.Reveal2\" and certificate 1[field.1.2.840.113635.100.6.2.6] exists and (certificate leaf[field.1.2.840.113635.100.6.1.13] exists or certificate leaf[field.1.2.840.113635.100.6.1.14] exists) and certificate leaf[subject.OU] = \"KBY3G4JPGC\"";
    SecCodeRef code;
    OSStatus status = SecCodeCopySelf(kSecCSDefaultFlags, &code);
    if (status == errSecSuccess) {
            SecStaticCodeRef staticCode;
            status = SecCodeCopyStaticCode(code, kSecCSDefaultFlags, &staticCode);
            if (status == errSecSuccess) {
                    SecRequirementRef requirement;
                    status = SecRequirementCreateWithString(text, kSecCSDefaultFlags, &requirement);
                    if (status == errSecSuccess) {
                            status = SecStaticCodeCheckValidity(staticCode, kSecCSDefaultFlags, requirement);
                    }
                    if (requirement != NULL) {
                            CFRelease(requirement);
                    }
            }
            if (staticCode != NULL) {
                    CFRelease(staticCode);
            }
    }
    if (code != NULL) {
            CFRelease(code);
    }
    return status == errSecSuccess ? true : false;
}

这个函数就是校验签名,没干别的,整个函数直接return true吧:

                     sub_100418109:
0000000100418109         mov        rax, 0x1
0000000100418110         ret

重现打开reveal,又能看到Welcome界面了


DMActivationController

看到类名DMActivationController,在Reveal.app/Contents/Frameworks/DevMateKit.framework/Versions/A/DevMateKit里面找到它的定义。
GitHub搜索DevMateKit,发现是一个第三方库:
https://github.com/DevMate/DevMateKit
(以后看到这种Welcome界面,第一时间要想到是这个第三方库了。)

hopper打开DevMateKit
找到下面的函数,直接ret完事:

                     -[DMActivationController runActivationWindowInMode:initialActivationInfo:withCompletionHandler:]:
000000000002564d         ret

重新打开,基本功能都能用了,唯独点击help弹出的菜单项有些还是灰的:

validateMenuItem:

搜索validateMenuItem:,将下面函数直接return YES试试:

                     -[IBAAppDelegate validateMenuItem:]:
000000010029bad0         mov        rax, 0x1
000000010029bad7         ret

重新打开,完美破解!

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

推荐阅读更多精彩内容