?
前言
了解下魔數(shù)
什么是魔數(shù)
magic number 一般是指硬寫(xiě)到代碼或文件中的整型常量,數(shù)值是編程者自己指定的,其他人不知道數(shù)值有什么具體意義。
小程序包也有自己的魔數(shù),這是區(qū)別其它文件的標(biāo)識(shí)。
了解下大小端序
-
大端序(Big-endian):高字節(jié)保存在內(nèi)存的低地址--正序排列
-
小端序(Little-endian):高字節(jié)保存在內(nèi)存的高地址--逆序排列
注意
-
主機(jī)字節(jié)順序,X86一般多為小端(little-endian),網(wǎng)絡(luò)字節(jié)順序,一般為大端(big-endian)
-
小程序包是以大端序方式存儲(chǔ)的
實(shí)驗(yàn)環(huán)境
-
macOS Catalina:v10.15.5
-
node:v10.17.0
-
測(cè)試小程序包:開(kāi)源中國(guó)小程序
測(cè)試用node腳本
readfile.js
執(zhí)行腳本結(jié)果
命令行執(zhí)行 node readfile.js 得到如下結(jié)果
-
Header info:
-
Magic number first: 190
-
firstMark: 0xbe
-
unknownInfo: 0
-
infoListLength: 2978
-
dataLength: 923206
-
Magic number last: 237
-
lastMark: 0xed
相關(guān)腳本若干關(guān)鍵方法解讀
此段測(cè)試腳本摘錄自原工具并做了小修改
buf.readUInt8(0)
作用:從第0個(gè)字節(jié)開(kāi)始讀取一個(gè)無(wú)符號(hào)的8比特位整數(shù)值(即:從0讀一個(gè)字節(jié))。
這里是讀取一個(gè)字節(jié)的數(shù)據(jù)作為 firstMark ,也就是魔數(shù)了。如上面執(zhí)行結(jié)果所示,值是一個(gè)10進(jìn)制數(shù)字為 190。
buf.readUInt8(13)
作用:從第13個(gè)字節(jié)開(kāi)始讀取一個(gè)無(wú)符號(hào)的8比特位整數(shù)值。
這里是從第13個(gè)字節(jié)讀取一個(gè)字節(jié)的數(shù)據(jù)作為 lastMark ,是另一個(gè)魔數(shù)。值為 237。
firstMark.toString(16)
作用:把數(shù)字轉(zhuǎn)換為字符串(以十六進(jìn)制值顯示)
這里數(shù)字190的十六進(jìn)制轉(zhuǎn)換結(jié)果為 be ,因?yàn)槭M(jìn)制有前綴 0x ,所以前面需要帶前綴以表示十六進(jìn)制值-> 0xbe。
buf.readUInt32BE(5)
作用:以大端字節(jié)序從 buf 中第 5 個(gè)字節(jié)讀取一個(gè)無(wú)符號(hào)的 32 位整數(shù)值。
這里代表微信文件信息列表長(zhǎng)度值。
結(jié)論
微信小程序包文件的魔數(shù)為兩個(gè)十六進(jìn)制值 0xbe 和 0xed,使用其它文件跑腳本會(huì)報(bào)"Magic number is not correct!"錯(cuò)誤。
參考資料
-
JavaScript toString()方法:https://www.runoob.com/jsref/jsref-tostring-number.html
-
buf.readUInt8([offset]):http://nodejs.cn/latest-api/buffer/buf_readuint8_offset.html
-
buf.readUInt32LE([offset]):http://nodejs.cn/latest-api/buffer/buf_readuint32le_offset.html
本文摘自 :https://blog.51cto.com/x