微信小程式“反編譯”實戰(一):解包

知識小集發表於2018-05-08

本實踐教程將一步步告訴你如何“反編譯”獲得其它小程式的原始碼,包括“解包”和“原始碼還原”兩篇,主要參考了看雪論壇、V2EX、GitHub 等網站上的帖子、教程、工具,在此不勝感激,參考連結詳見文章底部,以及加上了我自己的一些理解和總結。

知識小集是一個團隊公眾號,每週都會有原創文章分享,我們的文章都會在公眾號首發。歡迎關注檢視更多內容。

微信小程式“反編譯”實戰(一):解包

我們知道,在微信開發者工具中開發完小程式後,我們點選“上傳”按鈕,微信開發者工具會進行“編譯”,對 JS 程式碼進行壓縮混淆以及對 wxmlwxss 和資原始檔等進行整合打包成一個 .wxapkg 檔案上傳給微信伺服器。

所以要“反編譯”小程式,首先我們要獲取到小程式對應的 .wxapkg 包。

之前在 V2EX 上有一篇文章 https://www.v2ex.com/t/419056 介紹瞭如何通過某 URL 直接下載每個小程式的 .wxapkg,但很快被微信封了。

因此,我們只能從手機端入手,在手機上找到微信客戶端下載儲存在本地的小程式包。

獲取小程式的 .wxapkg 檔案

工具:一臺已越獄的 iPhone 手機或者已 RootAndroid 手機

本文以 iPhone 4S, iOS 8.4.1 為例,微信版本 v6.6.6

在已越獄的 iPhone 上開啟 Cydia,搜尋並安裝 iFile 或者 Filza 等檔案瀏覽 App,開啟 iFile 或者 Filza,跳轉到本地 App 安裝目錄:/var/mobile/Containers/Data/Application/,此時,你可以看到當前 iPhone 上已安裝的 App 列表,如下圖所示:

微信小程式“反編譯”實戰(一):解包

找到“微信”的目錄(我手機上對應的是:297286CE-9055-400A-99FA-D2D7C0735DCF 資料夾),點選進入,即為微信在此 iPhone 上的“沙盒”(Sandbox),相信 iOS 開發者對此目錄已經非常熟悉了,該目錄下主要有 DocumentsLibrarytmp 等資料夾,通常用於存放不同的資料和檔案,這裡不再贅述。我們在當前微信“沙盒”目錄中搜尋 wxapkg 關鍵字,即可找到當前 iPhone 中微信已下載的小程式包,如下圖:

微信小程式“反編譯”實戰(一):解包

我們發現搜尋到的 .wxapkg 檔名都是以數字命名的,如圖中的 2.wxapkg25.wxapkg,它們的命名有什麼規則呢?又放在哪呢?我們接著往下看。

經過簡單分析我們發現,微信下載的小程式包存放在以下目錄:

/path/to/WeiChat SandBox/Library/WechatPrivate/{UserId}/WeApp/LocalCache/release/
複製程式碼

其中,{UserId} 為當前登入的微信賬號 IdMD5 值(32 位字串),例如我手機上小程式包存放的完整目錄為:

/var/mobile/Containers/Data/Application/297286CE-9055-400A-99FA-D2D7C0735DCF/Library/WechatPrivate/c15d9cced65acecd30d2d6522df2f973/WeApp/LocalCache/release/
複製程式碼

該目錄的內容如下圖所示:

微信小程式“反編譯”實戰(一):解包

目錄中有一系列以 wx... 開頭的資料夾,這些 wx... 的 18 位字串即為每個小程式對應的 AppId,在每個 wx... 資料夾中都放著當前小程式對應的 .wxapkg 包,它以數字命名,數字代表著當前包為開發者第幾次釋出的(它與開發者在釋出小程式時指定的版本號是不同的),例如我們的“知識小集”小程式一共釋出了兩個版本,所以 wx48...85db 檔案中存放有 2.wxapkg 檔案:

微信小程式“反編譯”實戰(一):解包

另外,我們發現,在 iOS 上,微信也為每個小程式分配了一個 Sandbox 資料夾用於管理小程式在本地儲存的資料和檔案,如圖:

微信小程式“反編譯”實戰(一):解包

其路徑為:

/path/to/WeiChat SandBox/Library/WechatPrivate/{UserId}/WeApp/Sandbox/wx...(小程式 AppId)
複製程式碼

By The Way,Android 手機上小程式包的存放目錄為(需 Root 許可權才能訪問):

/data/data/com.tencent.mm/MicroMsg/{UserId}/appbrand/pkg/
複製程式碼

拷貝 .wxapkg 檔案到電腦上

通過上述分析,我們可以知道到小程式的壓縮包 .wxapkg 存放在哪,接下來我們需要將手機上的 .wxapkg 檔案拷貝到電腦上。

在 iPhone 上開啟 Cydia 搜尋並安裝 OpenSSH 後,在 iPhone > 設定 > 無線區域網中檢視你當前手機連線的 WiFi,並記錄 IP 地址,例如我的為:192.168.1.17,然後在你的 Mac 電腦上開啟終端(與 iPhone 連線同一 WiFi),就可以通過 SSH 登入到你的手機上了(具體的細節詳見 CydiaOpenSSH 下載頁面的使用說明):

ssh root@192.168.1.17
複製程式碼

接下來我們就可以通過 scp 命令從 iPhone 上拷貝檔案到我們的電腦上了,例如,在我的 Mac 上的命令列裡執行(不需要 ssh 登入到 iPhone 上,直接在 Mac 的終端上執行):

scp root@192.168.1.17:/var/mobile/Containers/Data/Application/297286CE-9055-400A-99FA-D2D7C0735DCF/Library/WechatPrivate/c15d9cced65acecd30d2d6522df2f973/WeApp/LocalCache/release/wx48...85db/2.wxapkg /Users/Zubin/Desktop/WeApp/
複製程式碼

就可以把“知識小集”小程式的包 2.wxapkg 拷貝到我 Mac 桌面上的 WeApp 資料夾中了。

當然,如果你的電腦有安裝 iTool 或者 PP助手 之類的工具,當連線已越獄的 iPhone 好像可以直接訪問手機上的目錄和檔案,可能就不用這麼麻煩了(未驗證)。

.wxapkg 解包

上述費了很大週摺我們終於拿到每個小程式的 .wxapkg 包,接下來我們可以對它進行分析了。首先 .wxapkg 檔案到底是什麼呢?你可能會認為它就是類似 Android 的 .apk 或者 iOS 的 .ipa 安裝包,本質上是一個 .zip 壓縮包?其實不是的!,它是一個二進位制檔案,實際的檔案結構如下圖:

微信小程式“反編譯”實戰(一):解包

圖片取自文章 微信小程式原始碼閱讀筆記,同時此文章的作者也提供瞭解包的指令碼(各種語言的)放在了 GitHub 上:

微信小程式“反編譯”實戰(一):解包

我下載了 Python 2 的解包指令碼,與 .wxapkg 檔案放在一個目錄,然後在命令列裡執行如下命名即可得到解包後的檔案:

python unwxapkg.py 2.wxapkg
複製程式碼

以“知識小集”小程式為例,解包後得到的檔案目錄如下(已經基本與我開發“知識小集”小程式的工程目錄一致了):

微信小程式“反編譯”實戰(一):解包

每個小程式解包後的檔案都大同小異,主要包含如下檔案:

  • app-service.js: 小程式工程中所有 JS 檔案的彙總,已被混淆;
  • app-config.json: 小程式工程 app.json 以及各個頁面的 JSON 配置檔案彙總,可直接檢視;
  • page-frame.html: 所有頁面的 .wxmlapp.wxss 樣式檔案的彙總,可讀性差,需要還原;
  • *.html: 包含每個頁面對應的 .wxss 資訊,可讀性較好;
  • 資原始檔: 各類圖片、音訊等資原始檔

總結

本文主要介紹瞭如何獲取小程式的 .wxapkg 包檔案,以及如何解包獲得小程式“編譯”混淆後的程式碼和資原始檔。在下一篇文章《微信小程式“反編譯”實戰(二):原始碼還原》將介紹如何將 .wxapkg 包內內容還原為"編譯"前的內容。

參考連結

相關文章