前言
了解下魔数
什么是魔数
magic number 一般是指硬写到代码或文件中的整型常量,数值是编程者自己指定的,其他人不知道数值有什么具体意义。
小程序包也有自己的魔数,这是区别其它文件的标识。
了解下大小端序
-
大端序(Big-endian):高字节保存在内存的低地址--正序排列
-
小端序(Little-endian):高字节保存在内存的高地址--逆序排列
注意
-
主机字节顺序,X86一般多为小端(little-endian),网络字节顺序,一般为大端(big-endian)
-
小程序包是以大端序方式存储的
实验环境
-
macOS Catalina:v10.15.5
-
node:v10.17.0
-
测试小程序包:开源中国小程序
测试用node脚本
readfile.js
执行脚本结果
命令行执行 node readfile.js 得到如下结果
-
Header info:
-
Magic number first: 190
-
firstMark: 0xbe
-
unknownInfo: 0
-
infoListLength: 2978
-
dataLength: 923206
-
Magic number last: 237
-
lastMark: 0xed
相关脚本若干关键方法解读
此段测试脚本摘录自原工具并做了小修改
buf.readUInt8(0)
作用:从第0个字节开始读取一个无符号的8比特位整数值(即:从0读一个字节)。
这里是读取一个字节的数据作为 firstMark ,也就是魔数了。如上面执行结果所示,值是一个10进制数字为 190。
buf.readUInt8(13)
作用:从第13个字节开始读取一个无符号的8比特位整数值。
这里是从第13个字节读取一个字节的数据作为 lastMark ,是另一个魔数。值为 237。
firstMark.toString(16)
作用:把数字转换为字符串(以十六进制值显示)
这里数字190的十六进制转换结果为 be ,因为十六进制有前缀 0x ,所以前面需要带前缀以表示十六进制值-> 0xbe。
buf.readUInt32BE(5)
作用:以大端字节序从 buf 中第 5 个字节读取一个无符号的 32 位整数值。
这里代表微信文件信息列表长度值。
结论
微信小程序包文件的魔数为两个十六进制值 0xbe 和 0xed,使用其它文件跑脚本会报"Magic number is not correct!"错误。
参考资料
-
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