使用 lldb 對應(yīng)用砸殼

進(jìn)行 iOS 越獄開發(fā)的第一步,通常就是對從 AppStore 上下載安裝的應(yīng)用進(jìn)行砸殼。我們常用的工具就是 dumpdecrypted 或者 Clutch,關(guān)于這兩個(gè)工具的使用,在之前的文章 已經(jīng)進(jìn)行過介紹了。

事實(shí)上,除了使用工具幫助我們進(jìn)行砸殼,我們還可以直接使用 lldb 進(jìn)行手動(dòng)砸殼。

原理

手動(dòng)砸殼的原理其實(shí)很簡單,在應(yīng)用被加載完成后,對應(yīng)的解密工作就已經(jīng)完成了。

這個(gè)時(shí)候,我們就可以通過 loadCommand 中的 LC_ENCRYPTION_INFOLC_ENCRYPTION_INFO_64 信息,找到對應(yīng)的偏移,然后將解密后的數(shù)據(jù)從內(nèi)存中 dump 出來,再使用這份數(shù)據(jù)對原來的可執(zhí)行文件進(jìn)行補(bǔ)丁,這樣我們就得到了一個(gè)砸過殼的可執(zhí)行文件了。

了解過原理后,下面就可以直接動(dòng)手了。

準(zhǔn)備工作

在開始真正進(jìn)行砸殼之前,要先將 iphone 設(shè)備上的可執(zhí)行文件拷貝到本地。

由于從 AppStore 安裝的應(yīng)用都是在 Application 目錄下的,因此我們可以使用 ps 配合 grep 命令來找到我們的目標(biāo)應(yīng)用。

iphone$ ps -e | grep Application

  2815 ??         0:02.32 /var/mobile/Containers/Bundle/Application/577995FB-298A-40DC-88BE-FC9C7804D1E8/LuoJiFM-IOS.app/LuoJiFM-IOS

接著就可以使用 scp 命令將可執(zhí)行文件拷貝到本機(jī)上。

# 拷貝到 Mac 的桌面上
osx$ scp root@<device_ip>:/var/mobile/Containers/Bundle/Application/577995FB-298A-40DC-88BE-FC9C7804D1E8/LuoJiFM-IOS.app/LuoJiFM-IOS ~/Desktop

查看可執(zhí)行文件信息

將可執(zhí)行文件拷貝到本地之后,我們就可以使用 otool 來查看它的信息了。

osx$ otool -fh LuoJiFM-IOS

Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 12
    cpusubtype 9
    capabilities 0x0
    offset 16384
    size 21302352
    align 2^14 (16384)
architecture 1
    cputype 16777228
    cpusubtype 0
    capabilities 0x0
    offset 21331968
    size 25417728
    align 2^14 (16384)
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface      12          9  0x00           2    63       6280 0x00218085
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    63       7008 0x00218085

可以看到這個(gè)可執(zhí)行文件是一個(gè)多架構(gòu)的文件,它包含 32 位與 64 位的架構(gòu)。選擇想要砸殼的架構(gòu)查看它的加密信息,我這里選擇的是 64 位架構(gòu)。

osx$ cd ~/Desktop
osx$ otool -arch arm64 -l LuoJiFM-IOS | grep crypt

     cryptoff 16384
    cryptsize 19972096
      cryptid 1

其中,cryptoff 是加密信息的偏移,cryptsize 是加密信息的大小,而 cryptid 為 1 證明這個(gè)可執(zhí)行文件是加密的。

有了這些信息后,我們就可以開始進(jìn)行砸殼了。

使用 lldb 砸殼

配合 debugserver 并祭出 lldb 神器,附加到進(jìn)程上。

iphone$ debugserver *:1234 -a LuoJiFM-IOS
# debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-320.2.89 for arm64.
# Attaching to process LuoJiFM-IOS...
# Listening to port 1234 for a connection from *...

osx$ lldb
(lldb) process connect connect://<device_ip>:1234

Process 2815 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x0000000196d24e0c libsystem_kernel.dylib` mach_msg_trap  + 8
libsystem_kernel.dylib`mach_msg_trap:->  0x196d24e0c <+8>: ret
libsystem_kernel.dylib'mach_msg_overwrite_trap:    0x196d24e10 <+0>: mov    x16, #-0x20
    0x196d24e14 <+4>: svc    #0x80
    0x196d24e18 <+8>: ret
libsystem_kernel.dylib'semaphore_signal_trap:    0x196d24e1c <+0>: mov    x16, #-0x21
    0x196d24e20 <+4>: svc    #0x80
    0x196d24e24 <+8>: ret
libsystem_kernel.dylib'semaphore_signal_all_trap:    0x196d24e28 <+0>: mov    x16, #-0x22

接著,找出可執(zhí)行文件的偏移地址:

(lldb) image list LuoJiFM-IOS
[  0] 426D3B7D-5433-3EA3-9E8C-384830B6A104 0x0000000100010000 /private/var/mobile/Containers/Bundle/Application/577995FB-298A-40DC-88BE-FC9C7804D1E8/LuoJiFM-IOS.app/LuoJiFM-IOS (0x0000000100010000)

在此例中,偏移地址為 0x0000000100010000。

然后,dump 出可執(zhí)行文件被加密部分的二進(jìn)制信息。命令如下:

(lldb) memory read --force --outfile ./decrypted.bin --binary --count <cryptsize> <image offset>+<cryptoff>

將以上命令的 cryptsize、image offset 以及 cryptoff 都替換為你自己的數(shù)據(jù)。對于這個(gè)例子而言,實(shí)際的命令如下:

(lldb) memory read --force --outfile ./decrypted.bin --binary --count 19972096 0x0000000100010000+16384

# 19972096 bytes written to './decrypted.bin'

有了這個(gè)補(bǔ)丁文件,就可以對原來的可執(zhí)行文件打補(bǔ)丁了。開始之前,先備份下原來的可執(zhí)行文件。

# 先退出 lldb 并回到桌面
(lldb) exit
osx$ cd ~/Desktop
osx$ cp LuoJiFM-IOS LuoJiFM-IOS-bak

decrypted.bin 文件的內(nèi)容寫入到可執(zhí)行文件中:

osx$ dd seek=21348352 bs=1 conv=notrunc if=./decrypted.bin of=./LuoJiFM-IOS

# 19972096+0 records in
# 19972096+0 records out
# 19972096 bytes transferred in 25.058427 secs (797021 bytes/sec)

上面命令中的 21348352=21331968+16384,其中 21331968 是架構(gòu)的偏移(即上面 otool -fh 打印出的信息中對應(yīng)架構(gòu)的 offset 字段),而 16384 是 cryptoff 的值。

至此,我們就使用 lldb 完成對應(yīng)用的手動(dòng)砸殼。

最后,為了讓可執(zhí)行文件適用于某些應(yīng)用(如 class-dump-z),我們需要將 cryptid 字段手動(dòng)置為 0。這一步可以通過 MachOView 來完成。

將上面的 Cyrpt ID 改成 0,并保存即可。

驗(yàn)證

為了驗(yàn)證我們的砸殼過程是否成功,可以使用 class-dump 來測試導(dǎo)出頭文件。如果頭文件導(dǎo)出成功,則說明我們已經(jīng)成功砸殼了。

osx$ class-dump --arch arm64 -H LuoJiFM-IOS -o Headers
osx$ cd Headers
osx$ ls -l | wc -l
#    2989

可以看到,我們導(dǎo)出了 2989 個(gè)頭文件,說明整個(gè)砸殼過程是正確的。

小結(jié)

大概瞄了下 dumpdecrypted 的源碼,貌似它的原理就是本篇文章中使用的方法。而對于 Clutch,由于還沒有看過它的源碼,因此目前還不知道它的實(shí)現(xiàn)方法,之后有時(shí)間來學(xué)習(xí)學(xué)習(xí)。

參考資料

關(guān)注

如果你喜歡這篇文章,可以關(guān)注我的公眾號,隨時(shí)獲取我最新的博客文章。

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

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

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