這些反破解盲區,你踩了幾個

最近破解了不少軟件練手,發現了一些憨到可愛的反破解,於是就決定寫這篇文章


0x0 驗證挺嚴密,就是可以繞過

典例:某手勢app,驗證序列號使用了native層lib,通過調用下面的方法完成驗證

.method public static native validateActivateCode(Ljava/lang/String;Ljava/lang/String;)Z
.end method

驗證邏輯位於libnative-lib.so

眾所周知,native文件要反編譯非常困難,要各種動態分析,一般破解者沒這功夫。但是這個app被我秒破了

原因很簡單:注意這個方法,返回的是整數Z

在dex裡搜索調用這個驗證方法的地方,我們可以發現下面一處

invoke-static {v0, v1}, L***保護開發者***Util;->validateActivateCode(Ljava/lang/String;Ljava/lang/String;)Z
move-result v0
if-eqz v0, :cond_76
const-string v0, "已激活,感謝您的支持~"
invoke-virtual {p0, v0}, L***保護開發者***ActivateActivity;->setTitle(Ljava/lang/CharSequence;)V

我們可以分析出,這個native層的驗證邏輯就是輸入序列號,如果可用則返回1,不可用則返回0

知道這個邏輯,就好辦了。我們找到每個調用這個驗證的地方,手動給返回值賦值1就好了,在if-eqz上方添加const/4 v0,0x1,破解完成!

這個app被輕鬆破解的關鍵在於驗證太容易被分析出邏輯從而繞過,返回的整數Z很容易讓破解者順藤摸瓜下去,如果自定義一個Object就會難很多了。另外既然都用上native層了,不如把部分關鍵代碼全部native化,增加反編譯難度。同時缺少混淆導致方法的用途能被一眼望到底也是被快速破解的原因之一。


0x1 技能樹完全點歪

典例:2.x版本的tx加固

最初的tx加固非常好dump,直接drizzleDumper就完事了,後來tx不斷加強各種反調試手段和防dump手段,但是還是一直被秒脫

因為過了幾個版本之後,大家根本就沒有用調試和dump來脫...

tx一直沒有換過加密算法,以至於過了幾個版本,靜態脫殼機就出來了...

這些反破解盲區,你踩了幾個

部分脫殼機源碼

大家都在靜態脫殼,把dex丟進去處理就完事了,加強的反調試和防dump根本用不上...

對於開發者,發現自己的作品被破解後,第一時間是要定位被破解的地方,dir的開發者曾召集破解者有獎破解,收集破解方法,這點就做的很好,知道怎麼被破解的,才能有針對的加強防護,而不是按照自己的想法點歪技能樹


0x2 如果免費用戶的權限和付費用戶一樣大...

典例:某內存盤工具

該工具免費用戶只能創建1023m的內存盤,需要更大空間則需要購買付費版本。

因為官網只有一個版本可以下載,且有驗證序列號(聯網)模塊,判定免費版和付費版的主程序一致,為內部邏輯限制

因為是C井,直接dnspy拖入最大的dll(dnspy會自動加載其他必須的dll),搜索license,沒有找到可以下腳的地方。截止到這裡,這個工具反破解還做的挺好的

但是...無意間發現了一條變量...MaxMegabytes...初始賦值1023

直接1023改成999999,回編譯,破解完成!

這個工具最大的問題在於忽視了破解並不一定要完全偽裝到付費用戶,只要我能用到付費用戶的功能,破解就成功了。雖然我沒有在許可證上偽裝成付費用戶,但是我把免費用戶的權限解鎖到了和付費用戶一樣,這樣就不用解決序列號驗證了,畢竟序列號驗證還要聯網比較難以破解。

要避免這類破解,也不難。對於不同級別用戶權限不等的變量,不要上來就按照免費用戶的權限賦值,初始賦值都設為0,依靠license manager類來統一按權限賦值。同時為了增加分析難度,混淆非常有必要。對於大型項目,還可以在不同的dll裡添加互相驗證文件完整性的邏輯,以避免被破解


就先聊聊這三個典例,以後遇到更多精彩的案例再寫


分享到:


相關文章: