word 破解曆程
破解工具:hopper
破解目标:mac 微軟word文檔
搜尋isactiv
通過交叉引用查找,找到了sub_1002a6121,在這個方法裡調用了 isActive, 反編譯的結果:
重反編譯的結果可知,關鍵點在 NSApp 類的 isActive這個方法。
oc裡面 它實際上是通過 objc_msgsend("NSapp","isActive") 這樣的方式調用的,
那麼如何靜态分析找到這個isActive方法呢?
冷靜分析:
既然是通過字元串調用,必然有通過這個字元串注冊回調的地方,順着這個思路去找,肯定能找到isActive方法。
可以看到有2個方法使用了這個字元串:
sub_1002a6121 【這個方法是剛才使用的地方,排除】
sub_10043c7e6 【這個方法是剛才使用的地方,排除】
通過交叉引用查找的兩處都是僅僅對他讀取并調用, 并沒有看到注冊方法的地方。
沒有直接找到注冊的地方,猜測他可能是通過指針偏移注冊的,于是重新查找:
可以看到有一個 method_list. 這個清單裡 有isactive. 在這個清單中的第三個位置。 索引的第2個位置。 程式中索引是從0開始的
那麼就查找這個 __objc_proto_OUIOfficeSpaceControl_opt_inst_methods:
交叉引用查找,隻有一個地方使用到它了,位置如下:
這個list被一個結構體引用, 那麼繼續查找這個結構體:__objc_proto_OUIOfficeSpaceControl_protocol。
在目前可執行檔案中未到找到相應的函數,可能有2種可能:
1,要找的函數加殼了
2,或者不在目前的二進制檔案了,可能在 動态加載庫裡。
============
下面重新審視這個問題:
使用xcode,建立cocoa工程,附加目前word程序,檢視目前激活按鈕資訊:
可以檢視到:激活按鈕的事件回調: [FileUIViewController activateClicked]
然後重新加載mso99 二進制檔案,查找這個函數可以得到:
從這裡可以看到:回調裡調用了 [[DocsUIBridge licensing] showActivationUI],輕按兩下showActivationUI,得到兩個相關方法:
清單中2兩個,到底用的哪個呢?
調用的哪個方法取決于:[DocsUIBridge licensing] 這個是什麼類型。這裡猜測是第二個方法吧。
因為如果是第一個,隻有DocsUIBridge licensing是一個單利引用自身類型,但是按照程式猿的正常做法,一般單利用getInstance或者Instance來表示。
是以暫且排除,剛好licensing字眼和清單中的第二個比較符合。
結論:點選清單中的第二個函數:DocsUILicensing showActivationUI
從途中顯示激活面闆核心函數就是:_SetupUI_IsActivityAllowed,繼續跟蹤一次得到以下方法:
圖中大量調用了:CFUUIDGetConstantUUIDWithBytes
關于這個方法的說明:https://developer.apple.com/documentation/corefoundation/1542189-cfuuidgetconstantuuidwithbytes
該方法跟據raw bytes 傳回一個CFUUID對象。先忽略這個方法。
我注意到有一個方法吸引了我:setShouldQuitAppIfNotActivated
這個方法的意思是:設定要不要退出app,如果沒有激活。 很顯然如果參數傳入true,則app可能會推出。
這裡的參數的值是arg3. 反向跟蹤,得知:
有一點小小的失望,arg3傳入的固定值0,也就是word本身設定了永遠不會退出app。
從實際效果看,也可以知道即使沒有激活它不會退出app,僅僅限制裡面的很多功能,比如不能編輯和儲存。
這裡就要猜測了,setShouldQuitAppIfNotActivated 方法的arg3參數存的是否激活的資訊。
很可惜arg3傳入的也是一個固定值0x46. 通過方法參數值,追蹤激活資訊的關鍵函數的希望再次破裂。
========================
接下來繼續分析激活資訊,猜測如果激活了, 激活按鈕應該不會再顯示,這個從使用者資訊入手,profile字段入手,跟蹤激活關鍵點。
通過查找找到了,設定左邊面闆的關鍵函數。 果然有設定激活按鈕的是否可見資訊,離成功又近了一步。
關鍵變量 canActivate。 使用者激活資訊類:DocsUILicensing
rax+0x8 對應的函數是:sub_fe20
找到了破解方法:隻要 MbuInAutomatedQTestMode()這個方法的傳回值不為0,那麼就可以破解這個軟體了。
因為rbx=1, goto之後直接傳回這個 rax=rbx=1, 也就是1. 通過跟蹤找到Mbuinstrument庫 的MbuInAutomatedQTestMode()
修改MbuInAutomatedQTestMode函數裡面的某個指令就OK了。【具體的哪個指令我就不說了】
附一張破解圖,可以編輯和儲存: