CMM 試用版使用限制破除的研究(非完美方案)

老文重發(fā)。

使用工具: class-dump, Hopper Disassembler。

CMM試用版的限制是:只能清理最多500MB的垃圾。這里要做的是在試用版下也能突破這個(gè)限制。

首先用class-dump導(dǎo)出所有頭文件備參考,用Hopper打開(kāi)可執(zhí)行文件,應(yīng)該就是CMM:

image

當(dāng)超過(guò)500MB以后,每次點(diǎn)清理按鈕會(huì)彈出下面的窗口:

image

在Hopper中搜索窗口中字符串"I already have a license":

image

得到變量名cfstring_I_already_have_a_licens,然后繼續(xù)搜索該變量:

image

可以看到[CMPurchaseViewController loadView]中引用到了它,從名字判斷這個(gè)controller應(yīng)該對(duì)應(yīng)了彈出來(lái)的窗口。應(yīng)該是點(diǎn)了按鈕后什么東西初始化了這個(gè)controller,之前的探索方向可能有點(diǎn)問(wèn)題,應(yīng)該去找button的處理函數(shù)。于是在Hopper搜索框里猜測(cè)buttonHandler,buttonTapped,buttonClick等等之類,最后發(fā)現(xiàn)有個(gè)叫ubiquitousButtonPurchaseClicked的函數(shù)很可疑:

image
image

在0x1006dec58的位置引用到了它,于是順藤摸瓜到這個(gè)地址:

image

是被這個(gè)函數(shù)給引用了:-[CMUbiquitousButtonView performActionOnDelegate]

打開(kāi)它的頭文件,發(fā)現(xiàn)里面有個(gè)mouseDown: 函數(shù),應(yīng)該就是按鈕處理函數(shù),但是是不是清理按鈕現(xiàn)在還不知道,總之先來(lái)看看mouseDown:的實(shí)現(xiàn)。 用Hopper找到它,查看偽代碼:

image

可以看到最后還是調(diào)用了performActionOnDelegate,看來(lái)是在這個(gè)函數(shù)里決定怎么處理接下來(lái)的邏輯,那么就繼續(xù)看看performActionOnDelegate的實(shí)現(xiàn):

image

哈哈,在這個(gè)函數(shù)里很驚喜的看到了疑似開(kāi)始清理過(guò)程的ubiquitousButtonStartCleanProcess:函數(shù),迫不及待的打開(kāi)看看:

image

有兩個(gè)類有這個(gè)函數(shù),這里可以通過(guò)打斷點(diǎn)判斷得出是CMModuleViewController調(diào)用了??吹綄?shí)現(xiàn):

image

于是痛苦開(kāi)始了,關(guān)鍵部分做了代碼混淆, 函數(shù)名變成了:JwUMdSW7rENEEIgVEGUtnns7cx3JNc9UTOuabo1ThwTJyDSydBKrFyvIIyTL6IgTvp9KwMqg1pF1VqvBEF8tC8YjbebfGbCBzIiRHQiX1wgasjtB0yneXyLo8vUGJhOmWNxu6FDurz8vOBkOSCpGfyGpMC8S1eJS8VWY9JRKfv7dahJuH0MAth7SwKv48LilHi63doAFcf1WDN2c7aJErpPKXKh3n08CPwiOcQxI888pDSR6K4XcjiWsYV3zHreX

姑且稱為加密函數(shù)A,是屬于CMMainWindowController的某個(gè)敏感函數(shù),看看它的實(shí)現(xiàn)如下:

image

忍不住吐血,里面又調(diào)了一個(gè)加密函數(shù)B。不管了,繼續(xù)看B的實(shí)現(xiàn),由于太長(zhǎng)了就不貼出來(lái)了,總之里面又調(diào)了一堆加密函數(shù)。這段時(shí)間比較痛苦,一度想放棄,嘗試著去理清程序執(zhí)行的順序,但又沒(méi)有g(shù)et到Hopper其實(shí)可以單步調(diào)試的技能,一度都是用下面的手段讓程序掛掉來(lái)得知程序的執(zhí)行流程:

MOV AX, 4C00H

INT 21H

注意到偽代碼里經(jīng)常出現(xiàn)一個(gè)類似下面的代碼片段:

image

猜測(cè)是block調(diào)用,于是寫(xiě)了段代碼用Hopper反匯編一下驗(yàn)證了果然是。

對(duì)于加密函數(shù)B,通過(guò)修改匯編的判斷條件,讓程序避過(guò)了彈出警告框的邏輯,最后發(fā)現(xiàn)這個(gè)函數(shù)其實(shí)沒(méi)做什么實(shí)質(zhì)的清理工作,只不過(guò)是在各種判斷用戶有沒(méi)有權(quán)限進(jìn)行清理。最實(shí)質(zhì)性的調(diào)用是這一句:

image

這其實(shí)是一句block調(diào)用,參數(shù)是1,block是外面?zhèn)鬟M(jìn)來(lái)的。接下來(lái)就在函數(shù)開(kāi)始合適的地方加上它的匯編代碼,匯編代碼如下:

mov qword [ss:rbp + var_D8], r15

mov esi, 0x1

mov rdi, qword [ss:rbp + var_D8]

call qword [ds:rdi+0x10]

jmp 0x100207266

這里有個(gè)插曲,直接加上如上的代碼會(huì)讓Hopper掛掉。查了下原因是Hopper這個(gè)版本還不支持編輯的時(shí)候引用var_開(kāi)頭的變量,嘗試換了種辦法,D8==十進(jìn)制的216,所以上面的匯編代碼等價(jià)于:

mov qword [ss:rbp - 216], r15

mov esi, 0x1

mov rdi, qword [ss:rbp - 216]

call qword [ds:rdi+0x10]

jmp 0x100207266

這里又要看到之前的ubiquitousButtonStartCleanProcess:函數(shù),然后結(jié)合加密函數(shù)A和B可以知道,ubiquitousButtonStartCleanProcess里有個(gè)block,然后把block丟給加密函數(shù)A,加密函數(shù)A又把block丟給加密函數(shù)B,由B執(zhí)行到最后再調(diào)用了這個(gè)block。這種執(zhí)行流程很像是這個(gè)block就叫onAuthorizeSuccess,兩個(gè)加密函數(shù)做了點(diǎn)能否執(zhí)行清理的判斷,如果成功的話執(zhí)行onAuthorizeSuccess block。 那么這里就應(yīng)該看到ubiquitousButtonStartCleanProcess: 里的block執(zhí)行體,也就是sub_1000dd914函數(shù):

image

接下來(lái)一路順藤摸瓜,從-[CMModuleViewController startClean]:到-[CMGroupScanner startClean]:到sub_100090e3a到-[CMGroupScanner cleanWithSession]: 到 -[CMScanner cleanWithSession]到 -[CMScanner cleanThreadWithSession] 到 -[CMScanner recursivelyCleanNode:parentNode:session:]: 都比較順利,最后在-[CMScanner recursivelyCleanNode:parentNode:session:]: 里發(fā)現(xiàn)有很多-[shouldScanner:pauseCleaningWithNextNodeToClean:]: 函數(shù),這個(gè)函數(shù)有好幾個(gè)類里都有,一一把它們直接返回false。

以為大功告成了,跑一下程序,發(fā)現(xiàn)掛了。幸好Hopper的debugger給出了exception的位置,發(fā)現(xiàn)是加密函數(shù)B中由于改變了程序執(zhí)行流程,導(dǎo)致最后某個(gè)不需要release的變量被release了,于是把這局操作置空就行。

以為接下來(lái)肯定大功告成了,結(jié)果發(fā)現(xiàn)清理系統(tǒng)垃圾的時(shí)候需要管理員權(quán)限,而被patch過(guò)的程序始終無(wú)法成功。這里牽涉到了SMJobBless和privileged helper tool等mac上的獲取系統(tǒng)權(quán)限接口,搞了兩天沒(méi)搞定。 最后只能簡(jiǎn)單粗暴的讓-[CMAgentController install] 返回false來(lái)跳過(guò)所有需要系統(tǒng)權(quán)限的垃圾的清理。

有大神知道怎么搞定SMJobBless的歡迎補(bǔ)充。

最后編輯于
?著作權(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ù)。

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