一起来探索下小程序包的魔数
时间:2022-07-26
本文章向大家介绍一起来探索下小程序包的魔数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本篇文章源于一名同学对近期一篇文章聊一聊微信小程序包内容 的疑问--如何获取文件的 firstMark 之类的数据,借此来展开探究一下。
# 前言
# 了解下魔数
什么是魔数
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!"错误。
# 参考资料
- No.014 Longest Common Prefix
- Java实现解析IP地址的方法,给出一串数字,生成正确的IP地址
- 图解“管道过滤器模式”应用实例:SOD框架的命令执行管道
- No.013 Roman to Integer
- OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client
- Java实现的手工做乘法方法,给出二个字符串数字,返回相乘结果
- No.012 Integer to Roman
- 黑帽SEO剖析之手法篇
- IOS学习1——IOS应用程序的生命周期及基本架构
- 浅议“全局变量”、“多线程”和“编译器陷阱”
- Java实现的图片合并方法,支持水平和垂直合并
- OC学习15——文件I/O体系
- 用惯了ORM,居然不会写分页SQL了
- OC学习14——谓词
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 3分钟短文 | Laravel 查询结果检查是不是空,5个方法你别用错!
- 使用XtraBackup备份MySQL 8.0 Part 7 对增量备份进行恢复
- 3分钟短文 | Laravel 日志全程记录 SQL 查询语句,要改写底层?
- MySQL InnoDB表空间加密
- 微信小程序自动化测试最佳实践(附 Python 源码)
- 3分钟短文 | MySQL在分组时,把多列合并为一个字段!
- Redis Linux系统参数最佳配置
- 实现Promise其它API
- 使用sysbench进行压测 Part1 sysbench安装
- Java并发编程(07):Fork/Join框架机制详解
- PostgreSQL Pgbouncer 到底怎么使用,疗效有多大
- 微信练手小程序源码 - 日历(含各种功能组件)
- Redis 5.0.8安装
- Redis 主从搭建
- Redis 5.0.8 主从+哨兵的搭建