經過安卓手機獲取微信小程序包進行反編譯方法

偶然有需求瞭解別人的小程序實現方法,網上相關資料不少,順便了解了一下,作個總結,沒啥技術含量,分享出來。

要求

  • 安裝Nodejs
  • 一臺root後的安卓手機或者裝有能夠打開微信小程序的安卓模擬器
  • 一個勇於折騰的耐心
看起來很簡單的樣子

準備

安裝反編譯工具

【推薦】方法一:你能夠經過git clone將它存在本地javascript

git clone https://github.com/qwerty472123/wxappUnpacker.git

將工具放在須要的目錄內(例如wxappUnpacker)。css

方法二:也能夠直接下載這個工具包,點擊下載,並解壓出來。html

接着在該項目內執行:java

npm install esprima css-tree cssbeautify vm2 uglify-es js-beautify escodegen

安裝完項目依賴後開始進行最複雜的操做,提取小程序包。node

提取微信小程序文件包

此時你有兩個選擇:經過安卓虛擬機獲取,用你已經root的安卓機操做。git

安卓虛擬機

  • 若是你是Windows,這就好說了。

    【推薦】選擇夜神模擬器下載並安裝。github

    【彷佛不太好用】我已經實踐過了,這裏有破解版的模擬器:Genymotion v2.12.2破解版。可是你要註冊一個帳號來添加虛擬設備,進行安裝。安裝完成後就能夠啓動了。web

    【失敗】網易的Mumu也是安卓模擬器,可是通過實踐,竟然不支持微信小程序。npm

  • 若是你是MacOS

    上面提到的Genymotion也是支持MacOS的,不過仍是很麻煩。小程序

    Mumu彷佛不錯,結果上面提到了,MacOS下也是打不開微信小程序的。

    結論:請自行嘗試Genymotion模擬,或者找其餘我還沒發現的模擬器。

已Root安卓手機

你用有一臺牛逼閃閃的安卓手機,可是大部分手機不容許root的,或者說root也是很是複雜的,因此若是你不懂得如何root,請考慮使用安卓虛擬機!

若是你優秀的root過了,這裏又有兩個方案:

  1. 【風險極高】粗暴的下載一個root explorer破解版,並受權root權限!
  2. 【推薦】從谷歌商店或者可靠的應用市場下載Root Explorer,土豪請付款購買,好像不到6美圓,我這裏嘗試了一下ES文件瀏覽器也能夠,因此接下來下載它並安裝好。

看到這裏,我當你已經擁有了一臺能夠登陸微信、安裝了文件管理工具、並給它授予最高權限的安卓手機了!

提取文件

  • 打開微信,登陸微信帳號。
  • 打開一個小程序,讓他正確加載顯示後就能夠關閉了(這個時候小程序的包已經報留在你的手機某個位置了)。
  • 打開文件管理工具(模擬器終會提示root,真機請手動受權root權限),訪問這個路徑根目錄(非存儲) > data > data > com.tencent.mm > MicroMsg > 9f69************ad8d(相似這樣的標識你所登陸的帳號的目錄) > appBrand > pkg,能夠看到相似下面這樣的文件:

    • _46541548_7.wxapkg
    • _-529198367_190.wxapkg
    • *.wxapkg
  • 若是很少的話將他們打包成zip,發送給微信朋友或者其餘方法上傳到網絡硬盤。
  • 再到電腦上把剛接收的或者上傳的zip下載到電腦上,解壓出來。

此時,文件就拿到了。

反編譯

進入工具目錄wxappUnpacker,建一個文件夾,好比pkg,將剛纔拿到的文件放在這裏。

假設,我要嘗試反編譯這個文件_46541548_7.wxapkg,執行命令:

node wuWxapkg.js ./pkg/_46541548_7.wxapkg

順利的話會生成一個同名的目錄。打開這個目錄就能看到了。

異常

程序出問題,工具出問題,代碼有BUG,再常見不過了。如下幾個異常,你也許也發生過,可能不明白,我把我遇到的異常理解分享一下:

  • 未安裝成功工具依賴的模塊

    Error: Cannot find module 'uglify-es'
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
        at Function.Module._load (internal/modules/cjs/loader.js:507:25)
        at Module.require (internal/modules/cjs/loader.js:637:17)
        at require (internal/modules/cjs/helpers.js:22:18)
        at Object.<anonymous> (/Users/whidy/webs/wxappUnpacker/wuJs.js:3:16)
        at Module._compile (internal/modules/cjs/loader.js:689:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
        at Module.load (internal/modules/cjs/loader.js:599:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
        at Function.Module._load (internal/modules/cjs/loader.js:530:3)

    那就是你沒裝好依賴,再執行一次npm run uglify-es

  • 未識別的包

    ...
    Saving files...
    Unpack done.
    /Users/whidy/webs/wxappUnpacker/wuWxapkg.js:104
            }else throw Error("This package is unrecognizable.\nMay be this package is a subPackage which should be unpacked with -s=<MainDir>.\nOtherwise, please decrypted every type of file by hand.")
                  ^
    
    Error: This package is unrecognizable.
    May be this package is a subPackage which should be unpacked with -s=<MainDir>.
    Otherwise, please decrypted every type of file by hand.
        at Array.packDone (/Users/whidy/webs/wxappUnpacker/wuWxapkg.js:104:14)
        at CntEvent.decount (/Users/whidy/webs/wxappUnpacker/wuLib.js:17:43)
        at ioLimit.runWithCb.err (/Users/whidy/webs/wxappUnpacker/wuLib.js:73:11)
        at agent (/Users/whidy/webs/wxappUnpacker/wuLib.js:54:14)
        at FSReqWrap.oncomplete (fs.js:141:20)

    好像挺順利,東西也出來了,但是最後仍是報錯了,推斷是包內有包,子包解壓失敗。有關更多能夠閱讀:https://github.com/qwerty4721...

  • 未定義的$gwx

    Saving files...
    Unpack done.
    /Users/whidy/webs/wxappUnpacker/wuWxapkg.js:104
            }else throw Error("This package is unrecognizable.\nMay be this package is a subPackage which should be unpacked with -s=<MainDir>.\nOtherwise, please decrypted every type of file by hand.")
                  ^
    
    Error: This package is unrecognizable.
    May be this package is a subPackage which should be unpacked with -s=<MainDir>.
    Otherwise, please decrypted every type of file by hand.
        at Array.packDone (/Users/whidy/webs/wxappUnpacker/wuWxapkg.js:104:14)
        at CntEvent.decount (/Users/whidy/webs/wxappUnpacker/wuLib.js:17:43)
        at ioLimit.runWithCb.err (/Users/whidy/webs/wxappUnpacker/wuLib.js:73:11)
        at agent (/Users/whidy/webs/wxappUnpacker/wuLib.js:54:14)
        at FSReqWrap.oncomplete (fs.js:141:20)

    這個就要修改一下工具源碼了,打開wuWxss.js文件,修改內容以下:

    // 原始
    function runVM(name,code){
        let wxAppCode={},handle={cssFile:name};
        let vm=new VM({sandbox:Object.assign(new GwxCfg(),{__wxAppCode__:wxAppCode,setCssToHead:cssRebuild.bind(handle)})});
        vm.run(code);
        for(let name in wxAppCode)if(name.endsWith(".wxss")){
            handle.cssFile=path.resolve(frameName,"..",name);
            wxAppCode[name]();
        }
    }

    改爲新的:

    function runVM(name,code){
        let wxAppCode={},handle={cssFile:name};
        let gg = new GwxCfg();
        let tsandbox ={$gwx:GwxCfg.prototype["$gwx"],__mainPageFrameReady__:GwxCfg.prototype["$gwx"],__wxAppCode__:wxAppCode,setCssToHead:cssRebuild.bind(handle)};
        let vm = new VM({sandbox:tsandbox});
        vm.run(code);
        for(let name in wxAppCode)if(name.endsWith(".wxss")){
            handle.cssFile=path.resolve(frameName,"..",name);
            wxAppCode[name]();
        }
    }

    再從新跑一次,Bingo!萬事大吉。

總結

總的來講,這個操做仍是比較容易的,最大的難點就是想辦法提出文件了。工具別人寫好了,有問題,Issue上面的解決方案不少,很快就能解決。

想要實現更多,也能夠參考工具的說明文檔經過不一樣的命令操做。

固然,小程序緩存到本地是無可奈何的,爲了提升加載速度嘛。這個東西,微信官方大概已經知道了,我想可能也會封堵吧。這個微信官方或許也只是單純打包了一下,因此就比較容易破解,若是他加殼,加密的話,或許之後就難了。

這也讓我想起不少年前,我也搞過相似的事情,大約8年前玩安卓手機的時候,解鎖Bootload,開啓Root來自個性化手機幾乎滿天都是,大把一鍵root,一鍵解鎖工具,所以那時候安卓手機安全性很低,小白用戶不懂,一不當心就中毒羣發小廣告。

那時候也流行Wifi萬能鑰匙,流量很貴的啦,我常常蹭了網,再去系統目錄找到那個存放wifi的配置文件來查看別人家的Wifi密碼。而後再用這個密碼嘗試admin/密碼,看看路由啥的,不過我沒搞過破壞的。

好了,你們若是還有不明白的,能夠留言,我有空再分析一下這個工具的實現方式,也順便嘗試一下其餘小程序(SWAN,頭條,支付寶等),是否也是相似的,等有告終論再來一篇了~

相關文章
相關標籤/搜索