2017-09-05 博客遷移 實習(xí)之競品分析
在實習(xí)的時候,項目里是要做一個類似競品的習(xí)題集需求,但是組里沒有習(xí)題資源环壤,按照競品的題目一個個拼也不現(xiàn)實,所以便有了扒取競品Apk數(shù)據(jù)的想法钞诡。
競品效果見下圖逆向一開始還是老套路郑现,ApkTool湃崩、JD-GUI走起,先大致瀏覽一遍逆出來的AndroidManifest接箫,對Activity界面的名稱有個大致的了解攒读。然后再用JD-GUI大致瀏覽一遍各個文件包名。
因為要扒的是棋盤數(shù)據(jù)辛友,在確定數(shù)據(jù)是存在本地的情況下薄扁,本能的看看databases有啥,結(jié)果發(fā)現(xiàn)有個叫book.db的東西瞎领。其中horse泌辫、kill、polgar九默、tactical是我們想要的習(xí)題集數(shù)據(jù)震放。
看看polgar存的數(shù)據(jù)好了,結(jié)果發(fā)現(xiàn)數(shù)據(jù)一堆亂碼一開始以為是編碼問題驼修,所以把book.db放到另外一個apk殿遂,試著用UTF-16,UTF-8, ASCII等各種編碼試了下,發(fā)現(xiàn)沒什么用乙各,導(dǎo)出的依舊是亂碼墨礁,所以猜測數(shù)據(jù)里應(yīng)該是做了加密。
隨后開始看代碼耳峦,先通過JD-GUI找到對應(yīng)讀取DB的代碼地方恩静,具體定位方法最快的方法是直接搜字符串“_fen”或“_pgn”。
以獲取fen為例蹲坷,在拿到fen的BLOB數(shù)據(jù)后驶乾,傳到了localj對象的b方法,b方法最終會調(diào)用如下a方法循签,a方法會轉(zhuǎn)化成一個v對象级乐。
代碼各種位運算實在讓人頭疼,一開始是打算在smali代碼注入日志县匠,然后重新打包风科,但是
1.這個v對象有很多參數(shù),到底哪個參數(shù)有用以及怎么用還不確定 乞旦,雖然看代碼能看出個大概贼穆,但不好把握。
2.競品對重新打包做了處理杆查,一直都打包失敗扮惦。
3.通過閱讀代碼可以看出棋盤界面是刷出來的時候才讀db對應(yīng)的數(shù)據(jù),1w多道題如果通過日志刷出的話亲桦,還要把每一頁都滑動一下才能走到讀對應(yīng)db的邏輯崖蜜,不太現(xiàn)實浊仆。
隨后想試試調(diào)試看看有沒有什么新發(fā)現(xiàn)。
關(guān)于調(diào)試豫领,我用的是AndroidStudio調(diào)試smali代碼的方法抡柿。
具體環(huán)境搭建可參照Smalidea+IntelliJ IDEA/Android Studio動態(tài)調(diào)試安卓app教程
手機打開到6個棋盤展示的界面,然后通過 adb shell dumpsys activity | grep "mFocusedActivity"
獲取當前界面對應(yīng)的Activity名等恐,然后找到對應(yīng)代碼洲劣,跟蹤相應(yīng)的邏輯(此處略)在棋盤初始化的時候加個斷點,然后調(diào)試课蔬,意外的發(fā)現(xiàn)了一個fen字符串囱稽。
仿佛看到了曙光,對比了下二跋,這個j就是對應(yīng)的之前說的v類的對象战惊,打開j發(fā)現(xiàn)有個長度64的數(shù)組。
很容易想到棋盤就是64個扎即,很有可能跟這有關(guān)系吞获,經(jīng)過逐一比對,發(fā)現(xiàn)數(shù)據(jù)是以棋盤左下角為原點建立的數(shù)組谚鄙,0代表無棋各拷,1代表白王,2代表白后闷营。烤黍。然后7代表黑王,8代表黑后傻盟,因為國象一共就6種棋型蚊荣,所以這種就是x白、x+6黑的編碼方式莫杈,以此內(nèi)推可以推出馬、象奢入、車筝闹、兵的id。
之后把BLOB數(shù)據(jù)轉(zhuǎn)換成16進制排布腥光,發(fā)現(xiàn)數(shù)據(jù)其實就是利用棋子id和奇偶對調(diào)的方式處理的关顷,比如如果有數(shù)據(jù)0201,其實它的在棋盤的排布是2010武福,也就是第1個格子是白后议双,第3個格子是白王∽狡考慮到版權(quán)問題平痰,這部分細節(jié)就不公開了汞舱。
上述說的是獲取棋盤信息fen的過程,還有一個就是獲取答案pgn的過程宗雇。pgn在代碼里的使用是通過坐標轉(zhuǎn)換的昂芜,BLOB的數(shù)據(jù)轉(zhuǎn)化規(guī)律定位到了如下函數(shù):
l的構(gòu)造函數(shù)有三個形參a,b,c(從左至右),分別代表原坐標赔蒲、目標坐標泌神、兵升變參數(shù)。
整體逆向的感受還是挺麻煩的舞虱,這個過程會遇到很多坑欢际,比如長期看混淆的代碼會被一些函數(shù)調(diào)用繞的暈頭轉(zhuǎn)向,不過之后也懂得放棄這種死磕代碼的做法矾兜,換一種角度看問題损趋,嘗試調(diào)試看看能看出什么東西來,不然可能這個項目的習(xí)題獲取就一直做不成了焕刮。還有學(xué)過的東西肯定會有用的舶沿,雖然工作用的都是unity和c#,跟原生Android已經(jīng)相去甚遠配并,但學(xué)過的以后肯定會有用武之地括荡,所以學(xué)東西不能一味的太功利化,提升自己能力才是關(guān)鍵溉旋。