破解《Reveal》

Reveal簡(jiǎn)介

Reveal能查看iOS App的視圖布局,而且能在App運(yùn)行時(shí)進(jìn)行視圖調(diào)試。

破解過(guò)程(本教程使用的Reveal版本為21)

下載下來(lái)打開(kāi)后,出現(xiàn)一個(gè)Welcome窗口擋在上面

Welcome

想看看這個(gè)Welcome窗口屬于哪個(gè)類,考慮用Xcode的View UI Hierarchy
打開(kāi)XcodeFile -> New -> Project...,選擇 macOS -> Cocoa Framework
工程創(chuàng)建好后,Debug -> Attach to Process,選擇Reveal
Could not attach

Attach失敗,應(yīng)該是開(kāi)啟了反調(diào)試。

hopper打開(kāi)Reveal.app/Contents/MacOS/Reveal,搜索ptrace

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

x查找引用,跳到調(diào)用的地方:

                     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函數(shù),直接jmp到NSApplicationMain即可:
選中函數(shù)的第一條指令,Modify -> Assemble Instruction...,輸入jmp imp___stubs__NSApplicationMain

                     EntryPoint:
00000001003df9bb         jmp        imp___stubs__NSApplicationMain

修改完成后command+shift+e -> Remove Signature -> Save -> Replace,重新打開(kāi)Reveal,此時(shí)Xcode Debug -> Attach to Process 已經(jīng)能連接上了,但是報(bào)損壞:

damaged

應(yīng)該是驗(yàn)證簽名了,hopper搜索SecStaticCodeCheckValidity,沒(méi)有搜索到,可能是隱藏了符號(hào)。Xcode添加Symbolic Breakpoint...試試,果然沒(méi)有失望:

(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

通過(guò)堆棧,找到驗(yàn)證簽名的地方為0x0000000100418191 。回到hopper,g -> 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;
}

這里出現(xiàn)了幾個(gè)地址: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

找到了對(duì)應(yīng)關(guān)系,簡(jiǎn)單整理就可以得出源碼為:

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;
}

這個(gè)函數(shù)就是校驗(yàn)簽名,沒(méi)干別的,整個(gè)函數(shù)直接return true吧:

                     sub_100418109:
0000000100418109         mov        rax, 0x1
0000000100418110         ret

重現(xiàn)打開(kāi)reveal,又能看到Welcome界面了


DMActivationController

看到類名DMActivationController,在Reveal.app/Contents/Frameworks/DevMateKit.framework/Versions/A/DevMateKit里面找到它的定義。
GitHub搜索DevMateKit,發(fā)現(xiàn)是一個(gè)第三方庫(kù):
https://github.com/DevMate/DevMateKit
(以后看到這種Welcome界面,第一時(shí)間要想到是這個(gè)第三方庫(kù)了。)

hopper打開(kāi)DevMateKit
找到下面的函數(shù),直接ret完事:

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

重新打開(kāi),基本功能都能用了,唯獨(dú)點(diǎn)擊help彈出的菜單項(xiàng)有些還是灰的:

validateMenuItem:

搜索validateMenuItem:,將下面函數(shù)直接return YES試試:

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

重新打開(kāi),完美破解!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容