前言

整個逆向的過程花了我快十二個小時,其中可能有很多地方有講錯或是描述不完全的,請各位見諒,這是我第一次嘗試逆向,整個過程都參考了很多前輩的教學,希望這篇文章可以幫助到跟我一樣入門的新手 XD

聲明:本文的內容僅做學習用途,不會提供任何破解檔案

這篇文章要破解的軟體是 Things 3,版本為 3.14.2

尋找破解的切入點

打開 Things,可以看到關於授權的部分只有右上角的剩餘試用天數,那我們就從這邊出發吧! Pasted-image-20210823065434

切換 App 語系

我們先把 App 換成英文的,好讓我們等等可以直接在 Hopper 找字串 這部分可以參考 jkg 大大的文章 如何單獨修改某個 iOS / iPadOS / macOS App 預設的語言?

Pasted-image-20210823064812 完成啦🎉 那我們等等就從 days left 下手吧!

利用 Hopper 來找到關鍵 Function

從上圖我們可以看到剩餘天數已經變成 days left,這時我們就可以打開 Hopper 來找出關鍵的驗證授權 Function

定位到特定的 Function

我們打開 Hopper 並且加載 Things 後,因為我們要找字串,所以先點左邊的 str 後輸入 days left

Pasted-image-20210823072010 從圖片中我們可以感覺到 %ld days left [DATEFORMATTER] 最可疑,所以我們雙擊它後,再按下鍵盤上的 x ,會跳出下圖的視窗,我們點兩下或是選中後按 Go就可以跳過去了

Pasted-image-20210823073049

進入後我們點上面的按鈕,看看能不能從偽代碼中看出驗證的Function

Pasted-image-20210823073506

看來很快就找到我們要的東西了 XD

Pasted-image-20210823073638

Frida Hook Function

接下來用 Frida 來 Hook 相關的 Function,我們的思路是找到這個驗證授權的 Function 後,將它 return True,是不是就等於有授權呢,接下來我們用 Frida 來實測看看

frida-trace -m "-[* *isProductLicensed*]" "Things"

我們可以看到 Frida 幫我們找到了 Function,並且產生了一隻 isProductLicensed.js

Pasted-image-20210823091824

用編輯器打開 isProductLicensed.js,並將下方的 return 改為 1 後存檔

Pasted-image-20210823075346

Frida hook function

接下來就是要 Hook function 啦,我們把剛剛的 js 存檔,再把 Things 重新打開,但這次重開的瞬間,我們要趕快再執行一次 frida-trace 的指令,因為他的驗證是做在剛執行的時候,如果我們錯過了那個時機,就算已經成功 Hook 也會顯示試用

Pasted-image-20210823092238

成功啦 🎉🎉🎉

Frida 注入成功了…. 然後呢?

對耶,看起來是破解成功了,但我總不能每次打開,每次都要開一次 frida 吧?

dylib 代碼注入

找了很多文章,看起來可以用 dylib 來做到 Hook Function,那我們就來做一個 dylib 吧!

利用 Xcode 來建立 dylib

點擊 Create a new Xcode project Pasted-image-20210823081455

點下 macOS 分頁,選擇 Library

Pasted-image-20210823081612

把該填的填一填後就可以建立專案啦~

Pasted-image-20210823081901

接下來我們寫上 Hook 的程式碼

Pasted-image-20210823085319

按下左上的三角形來 Build 如果沒問題,那就是注入 dylib 的時候啦!

insert_dylib

接著我們要用的是 insert_dylib ,利用它來注入我們的 Patch Build 好 insert_dylib 後,我們把剛剛建好的 libThingsPatch.dylib 也移過來

執行 insert_dylib <dylib_path> <binary_path> 這邊要注意一下第二個參數是 Binary的路徑Pasted-image-20210823090516

完成後我們進到 Binary 的所在處,可以看到多了 Things3_patched,這個就是 insert_dylib 幫我們 Patch 好的檔案,我們把原本的移除,替換成剛剛打包好的檔案

Pasted-image-20210823091108

再次執行一次打完 Patch 的 Things

Pasted-image-20210823092528

成功啦 🎉🎉🎉

9/2 更新

有天使用 CleanMyMac X 之後,突然 Things 就打不開了

截圖 2021-09-02 下午10.25.34

因為找不到問題,所以陷入了思考,後來想到可以打開「系統監視程式」來看 log,我們就來看看能不能找出問題吧

截圖 2021-09-02 下午10.28.45

看起來是缺少了什麼東西吧?!

一開始以為是 CleanMyMac X 清掉一些 dependency 導致 dylib 無法正常開啟

將 Build 模式從 debug 改為 Release 後,用 CleanMyMac X 清掃完也還是一樣會掛掉

後來才發現是 CleanMyMac X 把 dylib 砍掉了

赫然發現,insert_dylib 是幫你把要注入的 dylib 路徑寫死在裡面,

然後應用程式啟動的時候從那個路徑去注入 dylib,如果那個路徑沒有東西,那當然沒東西注入啊!

所以我們要改一下寫法,為了避免 dylib 的位置會變動,我們要把 dylib 放在 binary 旁邊,這樣可以跟 App 一起帶著走

截圖 2021-09-02 下午11.24.49

接下來是重點!!!

這次將 dylib_path 設定成 @executable_path/libThingPatch.dylib 然後再跑一次 insert_dylib 的流程

~/insert_dylib @executable_path/libThingsPatch.dylib Things3

截圖 2021-09-02 下午11.31.59

剩下的就跟之前一樣,把 Things3_patched 換成 Things3

然後就完成啦~

Reference

一行代码走天下,Frida+Hopper v4.5.19 Demo,调试Ummy Video Downloader的注册验证算法

逆向

insert_dylib

用 insert_dylib 來注入 macOS 的執行檔

如何單獨修改某個 iOS / iPadOS / macOS App 預設的語言?

iOS安全:iOS APP注入动态库重打包(非越狱)