聯系我們
掃二維碼

熱烈慶祝鑫聯華集團網站改版成功!股票代碼:835164

服務熱線:0451-82283322

行業新聞

您當前位置:首頁 > 新聞中心 > 行業新聞

微信5.0 Android版飛機大戰破解無敵模式手記
發布時間:2016年4月26日 瀏覽次數:1838次
最近微信出了5.0,新增了游戲中心,并內置了一個經典游戲《飛機大戰》。游戲其實很簡單,但由于可以和好友一起競爭排名,一時間受到大家的追捧,小伙伴們進入“全民打飛機”時代。

ios 版出來不久就被破解出了無敵模式。Android版出后好像一直風平浪靜。周末無事,加之看雪zmworm版主邀請,于是花了一天的工夫研究了下。也出了個Android版的無敵模式增強版。具體來說就是無敵、雙排子彈加無限炸彈。當然,這個不是重點,我們的重點當然是技術細節啦!

微信的游戲繼承了Android版手機QQ游戲中心的思想,也采用插件動態加載方式。具體來說,就是插件及游戲以jar包形式存在,jar包中有classes.dex及其他資源文件,在運行時動態加載資源及classes.dex代碼。這樣的好處是靈活管理,易于擴展。以后更多的游戲只要上架到微信的服務器,用戶就能在微信應用內部下載、安裝、運行。具體原理可以參考我2011年的一篇文章《Android類動態加載技術》 。

當然,那篇文章講的只是基本原理,而微信在代碼動態加載方面則走得更遠。針對插件的管理及安全,它有一套完整的框架,并自稱為sandbox。由于代碼有做混淆,加之代碼量挺大,所以我僅算管中窺豹,看到的也只是冰山一角。與實際情況有所出入,還請見諒!

一、微信游戲插件的安全校驗

其實說實話,微信在游戲插件的安全架構方面花了不少功夫。我能破解并不是利用微信在安全方面的漏洞,而是Android系統本身的安全漏洞。這個漏洞也就是我前段時間發的以為是bluebox上報google的漏洞,后來被證實不是。詳情請看《Bluebox Security最新提報Android漏洞的初步探討》 。

那微信是如何對游戲插件進行加載及安全校驗的呢?

飛機大戰的游戲插件以jar包的形式,放在微信apk的assets/preload文件夾下:

1.jpg
   
jar包中包括classex.dex、so本地庫及drawable圖片資源或者還有xml資源。微信處理插件加載的代碼在com.tencent.mm.compatible.loader包中。加載插件資源的類叫做PluginResourceLoader,它是android.content.res.Resources的子類。


而最核心的加載類應該是PluginClassLoader。上面說的PluginResourceLoader也是它的成員變量。它似乎負責整個插件加載的各個環節調度。

Android動態加載類有一個弊端,就是dex文件必須釋放為本地文件。這是dalvik虛擬機機制決定的。一直以為google或者dalvik會改,不過似乎到現在還沒見改進。釋放到本地緩存的dex是很容易受到攻擊的,不過微信在這些細節上處理得還挺好,沒有明顯漏洞。這個后面再說。

PluginClassLoader會在微信安裝后第一次啟動時,掃描插件的情況,并將插件拷貝到自己應用data下面的app_dex文件夾下。接下來會對插件進行處理。將so庫釋放到app_lib文件夾下,將jar包中的classes.dex重命名釋放到app_cache文件夾下。

在拷貝插件jar包的過程中,會對插件進行第一次校驗——簽名校驗。關于簽名校驗的原理,可以參看我2011年的另一篇文章《Android APK 簽名比對》 。微信的簽名校驗就是微信APK的簽名需要和插件jar包的簽名一致。這里我考慮過用bluebox上報的ANDROID-8219321漏洞繞過插件jar包的簽名檢測。經過一段時間的研究發現了它還有第二次校驗。。。

由于是在拷貝之前進行簽名校驗,所以我考慮過拷貝完成后,直接替換app_dex和app_lib下的文件的方法。發現均不可行。繼續分析發現了第二次校驗——MD5校驗。一開始看到jar包命名就很疑惑,文件名后面一串數字是干嘛的。想過是MD5碼,沒做驗證。直到碰壁之后,才發現了這里的奧秘。后面這一串數字就是jar包的MD5值。插件加載的時候會去解析這個MD5值,并存起來。在加載運行的時候會對這個MD5值進行校驗,如果緩存中的文件MD5值不同,會用重新釋放apk中的插件覆蓋。緩存中的dex應該也有類似的機制。這部分代碼分析得不是很透徹,大概原理如此,有感興趣的朋友可以繼續深入。

MD5值作文件名+簽名校驗,以為著利用ANDROID-8219321漏洞的企圖落空了。因為ANDROID-8219321漏洞的前提是apk中文件的文件名需要保持不變,這樣才能通過重名文件繞過簽名校驗。然而只要我們改了插件jar包,MD5值就必須得變,從而導致文件名改變。因此此路不通了。(也許可以通過修改MD5校驗和簽名校驗的smali繞過校驗,無奈我暫時沒找到具體MD5校驗的代碼,只能作罷)。

MD5值作文件名+插件簽名校驗,再加上安裝APK本身的簽名校驗。三重校驗保證了微信游戲的安全性。

因此我只能采用《Bluebox Security最新提報Android漏洞的初步探討》 一文中所述的安全漏洞。此漏洞針對system/app和vendor/app下的apk只會校驗manifest.xml文件簽名。因此我可以任意修改插件jar包,在重新生成新包之后計算出新包的MD5值,并對新包進行重命名。對于插件的簽名校驗,則直接通過修改smali代碼,屏蔽掉微信簽名校驗的函數功能,直接返回true:

2.jpg

file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/8274359.png
這就是我們修改插件之后得以正常運行的理論基礎及可行性保證。有了上面的理論,我們就可以開始修改游戲了!


二、飛機大戰游戲破解

飛機大戰這個游戲據說是騰訊一個程序員一周時間開發完成的作品。其實考慮到這個游戲的規模,除GUI和交互設計外,程序員一周時間應該也差不多了。沒有太大出入。

此游戲采用的游戲引擎是libgdx。相信做過Android游戲的朋友對此款引擎不會陌生。如果在Android平臺開源游戲引擎里,cocos2d當仁不讓地排第一的話,那么libgdx也可以當仁不讓地排第二了。cocos2d主要采用C++開發,而libgdx則主要采用java方式開發。學習成本低,開發周期短,是它的優勢。當然它也是跨多平臺的游戲引擎,運行效率方面稍有欠缺但也不錯。因此廣大的Android單機小游戲都是采用libgdx作為游戲引擎。

微信飛機大戰的代碼量不大,有興趣的朋友可以研究下,移植成為一款獨立的單機游戲應該也不難。下面我詳細介紹下飛機大戰游戲破解的技術細節。

第一步就是將飛機大戰游戲的插件包從apk中釋放出來。我們可以采用反編譯APK的方式反編譯這個插件包。修改smali代碼之后,再打包回jar包文件。如果還有朋友對APK破解流程不熟悉的話,可以參考我以前的一篇文章《APK Crack》 。這里我們主要介紹游戲的架構及破解思路。

解壓之后,smali部分其實可以分為兩個包:com.badlogic.gdx和com.tencent.mm.plugin.shoot。前面一個是libgdx導入的jar包,這個不是我們關心的內容。我們的重點就在com.tencent.mm.plugin.shoot這個包中。

游戲主要有兩個Activity:ShootMainUI和ShootFlashUI。它們都繼承自com.badlogic.gdx.backends.android.AndroidApplication,這個類事實上繼承自Android系統的Activity。它們一個是主加載界面,一個是我們停留時間最長的游戲界面。當然需要了解,但都不是重點,重點是我們游戲中的各種角色:

file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/4059890.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/4075140.jpg
3.jpg
4.jpg

這些角色構成了整個游戲的演員,他們都繼承自同一個類:GameSprite。相當于游戲引擎中精靈的概念。它們都有生命值、寬高、速度、類型、狀態等屬性。這些類的定義都在actor子包內。在游戲過程中會對每個精靈做碰撞檢測,當你發現你的飛機爆炸時,就是碰撞檢測在起作用。順便說一下,libgdx引擎采用的物理引擎是C++版的box2d,性能非常不錯。

好了,我們具體的破解特性,我會以任務的形式一個一個娓娓道來。下面我們接到的第一個任務就是“永久雙子彈”!

任務1、永久雙子彈!

在玩飛機大戰時,雙子彈意味著更大的威力??梢韵麥绺嗟臄硻C,化險為夷。然而在實際游戲中我們只有吃到PROPS_DOUBLE之后才能擁有一段有限時間的雙子彈狀態。

雙子彈屬性屬于HERO的,對應的類是Player和PlayerActor。Player繼承自GameSprite,而PlayerActor則是libgdx中的actor類的概念。兩個前者注重狀態和屬性,后者注重邏輯和動作。

Player在構造函數初始化時就會設置子彈類型:

5.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/5541906.png

我們只需要把BulletType從NORMAL改為DOUBLE就可以了。

PlayerActor會對子彈類型進行定時地檢測,檢測是會將雙子彈還原為單子彈。應該是為了處理吃到PROPS_DOUBLE后,一段時間子彈還原的問題。所以我們一并改掉:

6.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/5882812.png

OK,雙子彈破解任務完成!


任務2、炸彈無限!

炸彈是個好東西,威力無窮。關鍵時候全靠它清屏,消滅所有敵機!而且它還是刷分利器。當然,只有在它變為無限的時候,我們才能用它來刷分。

這里我試圖修改Player的getBombNumber和setBombNumber方法,發現均不行。后來轉變思路,只要在使用炸彈后炸彈數量不減少,就能實現無限炸彈的功能。經過代碼追蹤,最后定位到一處混淆代碼處。將-0x1改為了0x0。

7.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/6488578.png

修改的結果,在吃到兩個炸彈后使用炸彈不會減少炸彈數量。吃一個炸彈時,使用炸彈后炸彈按鈕消失,因此無法做到無限。請記住一定要存到兩個炸彈之后才能無限炸彈。無限炸彈破解任務完成!


任務3、開啟無敵模式!

長生不死一直是我們人類的終極夢想,在游戲中也不例外。iphone版微信也是因為有了飛機大戰無敵模式而被各大新聞站點競相轉載。讓我們Android版也無敵一下吧~

前面提到了GameSprite是所有角色的父類,在游戲用物理引擎做碰撞檢測后,會調用GameSprite類的hit方法。hit方法中將GameSprite的liftCount減一,如果減到0則將狀態設置為DEAD。

GameSprite的狀態有如下一些:

DEAD
EXPLODING
FLIGTHING
HITING
INVINCIBLE

在飛機正常的死亡過程中,是先HITING,再EXPLODING,再DEAD。FLIGTHING我不清楚干嘛的,INVINCIBLE應該是無敵模式。但是在我的破解里,并沒有使用這個模式,而是強制在碰撞檢測結果中,把它列在了生死薄之外。至于INVINCIBLE的方式,大家可以試試能不能很好的維護這個狀態。

具體來說就是hit方法不管GameSprite是hero也好,enemy也罷,均一視同仁,生命值減一,或者死掉。然而我們可以通過修改smali代碼,將hero列在生死薄之外:

8.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/211932724.png

其中goto_1標簽跳轉到return-void。這樣我們的hero將永遠不會被hit,因此也就無敵啦!


任務4、獨孤求敗。。。

本以為完成任務3就大功告成了,誰知我們缺遇到了無敵的尷尬——死不了。。。死不了,意味著永遠無法結束游戲,永遠不會有機會上傳自己的得分進入排行榜。哎,現在終于明白為什么獨孤求敗了。。。

基于此,我們得想個辦法觸發飛機非自然死亡。想來想去,我還是覺得讓飛機自己決定自己的生死最合理。具體就是當飛機飛到屏幕最上方時觸發死亡。因為一般情況,我們不會把飛機飛到屏幕最上方,所以誤操作概率極低。

通過前面我們知道hero飛機的類就是Player。而Player中有一個函數更新飛機的坐標位置:updatePosition。所以我們可以在這個函數中進行我們想要的操作:

9.jpg
file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/Wiz/c8a9eb41-9985-4ac8-9d56-792efe286bef_128_files/213169937.png

其中0x64就是我指定的y坐標下限100。當飛機坐標y在100以內時,我會把飛機的LiftCount設置為0,然后再將狀態設置為EXPLODING。飛機就會爆炸死亡了~
OK,任務完成,打完收工!


三、一些掃尾工作

插件包修改完成后,我們通過apktool,將其打包回jar包。res資源包需要手動添加會jar包中。然后按照第一節所說的,生成jar報的MD5碼,重命名jar包。
微信APK也需要按第一節的方法,將插件的簽名校驗屏蔽掉。編譯出classes.dex,替換微信原始包中的classes.dex。
再將APK包中的飛機大戰插件換為我們編譯出來重命名的這個jar包。

OK,APK準備好了。

由于我利用的是《Bluebox Security最新提報Android漏洞的初步探討》 一文中所述的安全漏洞,所以安裝此APK的過程并不是菜鳥能玩的。。。簡單來說,你需要root權限,并能將system分區mount為可寫。

然后卸載你原本的微信。將這個apk放到/system/app/文件夾下。稍等片刻,你就是打飛機的高手了!

如需技術交流,請與我聯系。新浪微博: @囧虎張建偉

轉載請注明出處: http://www.blogjava.net/zh-weir/archive/2013/08/14/402821.html
      【 】   【 返回
日本av在线观看片_日本av在线一区二区三区_日本a级毛片无卡免费视频