找回密码
 立即注册

小程序不让用 JS 解释器?那我再肛一次鹅厂

匿名  发表于 2022-7-15 21:42:33 阅读模式 打印 上一主题 下一主题
前言

6月23号的时辰,微信团队发了以下告诉将制止小法式利用 JavaScript 诠释来静态更新代码。消息一出,小法式开辟者们哀嚎哀嚎遍野,更有人宣称要起头加班改代码了。
为进一步提升小法式的平安性和用户体验,今朝平台对提审的小法式均需停止平安检测,在检测进程中,发现有小法式采用内置 JavaScript 诠释器(如eval5、estime、evil-eval等)的方式,静态履行JS代码、对小法式wxml代码停止热更新。对于利用诠释器的小法式,平台将自2022年7月6日起头在代码考核环节停止采纳,请列位开辟者于7月6日前完成自查、修复。
—— 摘自 关于制止小法式JavaScript诠释器利用标准要求 | 微信开放社区
自 2018年1月,我写下《brambles:微信小法式也要强行热更代码,鹅厂不服你来肛我呀》这篇文章起头,就带起来在小法式里面用 JavaScript 诠释器的潮水。但是四年曩昔了,微信小法式终究明文规定不在让用 JavaScript 诠释器了,那小法式热更的时代能否是就曩昔了?

小法式不让用 JS 诠释器?那我再肛一次鹅厂-1.jpg

大人,时代变了?不!没变!

固然不是,假如就这样曩昔了也就没我这篇文章了,实在早在四年前写前一篇文章的时辰我就已经想好处理计划,只是我是没想到的一年今后微信小法式才起头封 JavaScript 诠释器让我之前设想的计划一向拖到四年后的明天。n那末明天我们这篇文章首要就会商两个点:

  • 若何冲破微信小法式限制 JavaScript 诠释器利用停止热更代码。
  • 为什么从理论上没法从底子上制止小法式代码的热更。
根基步调 & 终极结果

示例代码 Github 仓库:https://github.com/bramblex/jsjs-vm-demo

  • 我们首先要写一个 JavaScript 的编译器,将 JavaScript 代码编译成二进制的字节码。
  • 找一张图片,将字节码编码并隐藏进图片中。
  • 在小法式中引入藏有 JavaScript 字节码的图片,而且解码出字节码。
  • 写一个对应的字节码虚拟机,而且履行从图片中解出的字节码。

小法式不让用 JS 诠释器?那我再肛一次鹅厂-2.jpg

在小法式中加载一张藏着字节码的图片,并履行图片上隐藏的代码

写个编译器将 JavaScript 编译成字节码 & 实现一个字节码虚拟机

为什么我们要将 JavaScript 编译成字节码呢?我们的目标是为了绕过微信小法式的代码考核限制,所以我们要想尽法子隐藏两样工具。第一个是要想法子隐藏诠释器看,由于一个完整的 JavaScript 诠释器代码量很是庞大,而且常常都需要引入他人写的库没法子自己保护,这样的诠释往都不需要用什么高深的技术手,字符串一婚配就能查出来个七七八八。
比如在小法式一个完整可用的 JavaScript 诠释器引入代码,最少需要引入一个最少 100k 以上的代码,这个方针实在是太大了,几近很难隐藏。可是在小法式里面引入一个可以履行字节码的虚拟机实现,可以做到只引入 10k 左右,紧缩前总代码量不跨越千行的代码,这样就更轻易隐藏静态代码的实现。比如我今朝实现的字节码虚拟机,除了 trycatch 和 with 之外,能实现 es5 一切才能的虚拟机总共才 7k 巨细,就这都是还可以再紧缩的。
第二点是我们需要隐藏热更的 JavaScript 代码不被微信发现,比如你把热更的大量 JavaScript 代码经过接口明文传输,只要微信稍微阻挡一下你的收集,这不就全露馅了吗?所以将代码编译成了二进制的字节码今后,微信就没有法子经过简单的阻挡你的接口请求来肯定里面有没有 JavaScript 代码来判定你是能否热更代码了。二进制的文件在你可以明白清楚它的个格式之前是没法子正确接出来他究竟是个什么工具的1,更况且二进制的加密混淆的算法满大街都是,而且还都没有几行……
下面是我实现字节码的指令集,总共只要 50 多个指令:
  1. export enum OpCode {
  2.   NOP = 0x00,
  3.   UNDEF = 0x01, NULL = 0x02, OBJ = 0x03, ARR = 0x04, TRUE = 0x05,
  4.   FALSE = 0x06, NUM = 0x07, ADDR = 0x08, STR = 0x09, POP = 0x0A,
  5.   TOP = 0x0D, TOP2 = 0x0E, VAR = 0x10, LOAD = 0x11, OUT = 0x12,
  6.   JUMP = 0x20, JUMPIF = 0x21, JUMPNOT = 0x22, FUNC = 0x30, CALL = 0x31,
  7.   NEW = 0x32, RET = 0x33, GET = 0x40, SET = 0x41, IN = 0x43,
  8.   DELETE = 0x44, EQ = 0x50, NEQ = 0x51, SEQ = 0x52, SNEQ = 0x53,
  9.   LT = 0x54, LTE = 0x55, GT = 0x56, GTE = 0x57, ADD = 0x60,
  10.   SUB = 0x61, MUL = 0x62, EXP = 0x63, DIV = 0x64, MOD = 0x65,
  11.   BNOT = 0x70, BOR = 0x71, BXOR = 0x72, BAND = 0x73, LSHIFT = 0x73,
  12.   RSHIFT = 0x75, URSHIFT = 0x76, OR = 0x80, AND = 0x81, NOT = 0x82,
  13.   INSOF = 0x90, TYPEOF = 0x91,
  14. }
复制代码
以下是将一段示例代码以及其编译后的字节码:

小法式不让用 JS 诠释器?那我再肛一次鹅厂-3.jpg

JavaScript 代码与编译后的字节码,这个字节码中还能看到 wx showModal 等字样

上面字节码是以下指令(节选)的二进制暗示:
  1. .main_1:
  2.         STR(09)
  3.         "wx" (00 77 00 78 00 00)
  4.         LOAD(11)
  5.         TOP(0d)
  6.         STR(09)
  7.         "showModal" (00 73 00 68 00 6f 00 77 00 4d 00 6f 00 64 00 61 00 6c 00 00)
  8.         GET(40)
  9.         ARR(04)
  10.         TOP(0d)
  11.         NUM(07)
  12.         0 (00 00 00 00 00 00 00 00)
  13.         OBJ(03)
  14.         TOP(0d)
  15.         STR(09)
  16.         "title" (00 74 00 69 00 74 00 6c 00 65 00 00)
  17.         STR(09)
  18.         "这是一段隐藏在图片中的代码" (8f d9 66 2f 4e 00 6b b5 96 90 85 cf 57 28 56 fe 72 47 4e 2d 76 84 4e e3 78 01 00 00)
  19.         SET(41)
  20.         POP(0a)
  21.         TOP(0d)
  22.         STR(09)
  23.         "content" (00 63 00 6f 00 6e 00 74 00 65 00 6e 00 74 00 00)
  24.         STR(09)
  25.         "这是一段隐藏在图片中的代码" (8f d9 66 2f 4e 00 6b b5 96 90 85 cf 57 28 56 fe 72 47 4e 2d 76 84 4e e3 78 01 00 00)
  26.         SET(41)
  27.         POP(0a)
  28.         TOP(0d)
  29.         STR(09)
  30.         "success" (00 73 00 75 00 63 00 63 00 65 00 73 00 73 00 00)
  31.         NULL(02)
  32.         NUM(07)
  33.         1 (3f f0 00 00 00 00 00 00)
  34.         ADDR(08)
  35.         .anonymous_2
  36.         FUNC(30)
  37.         SET(41)
  38.         POP(0a)
  39.         SET(41)
  40.         POP(0a)
  41.         CALL(31)
  42.         POP(0a)
  43.         RET(33)
复制代码
究竟是做个 Demo,假如真的需要适用的话,还有大量的优化空间。比如字节码字面量现在都是很是简单粗鲁间接内联,假如将数据和代码部分区分可以获得一个更好的性能。比如字符串的编码利用的是 utf16 编码,假如转换成 utf8 编码可以节省空间占用等等,这些今后故意情再做。

将字节码藏在图片里

上一章我们说需要隐藏虚拟机和热更的代码,可是我们思考一下,一个普通的小法式成天需要加在二进制文件,这一个行为能否是很是的怪异?没错,这件工作很是很是的希奇,由于一个一般小法式使底子没有什么读写二进制文件的需求。可是假如我告诉一个小法式,需要做一张有小法式二维码的分享图给用户保存,而且这张分享图还经常需要更新,这不是就很是合适逻辑了?
所以我们要将热更的字节码藏在图片里面,伪装成一个一般小法式的行为,而且要保证这场图片看起来也是一般的。以下就是我们开首示例中图片,作图是原图片,而右图是藏了我们上面示例代码的图,只要很是仔细看才能看到纤细的不同。

小法式不让用 JS 诠释器?那我再肛一次鹅厂-4.jpg

仔细看隐藏了字节码的地区,跟原图片有纤细的不同

图片一个像素点有 RGBA 一共四个 byte,为了最少影响图片看上去的结果,我们挑选只将字节码编码隐藏在图片的 Alpha 通道,这里用了最简单的编码方式,将 RGBA 中的 A 当做一个 bit 来停止编码。A 高于 0xF8 则为 1,否则则为 0。编码息争码算法以下:

小法式不让用 JS 诠释器?那我再肛一次鹅厂-5.jpg

在编译器中的编码算法(左)在小法式中履行的解码算法(右)

在小法式中只需要把图片画在 Canvas 上面,而且逐一读取 Alpha 通道上的数据就能隐藏在图片中的字节码接解码出来。最初经过我们上一小节实现的字节码虚拟机,就能履行我们想要热更的代码了。

为什么没法从底子上制止小法式代码的热更

先说结论,只要满足以下两个条件,那末从底子上制止热更都是流言蜚语:

  • 宿主说话图灵完整
  • 答应经过收集读取数据
第一,宿主说话假如图灵完整的话,那末宿主说话便可以实现任何其他图灵完整的编程说话。比如 JavaScript 图灵完整,那末你就能用 JavaScript 实现 JavaScript 诠释器、Python 诠释器、PHP 诠释器等等只要你能想获得的编程说话诠释器,甚至你还可以设想一个自己的比如本文的字节码虚拟机。所以当通告一出来的时辰,楼底下第一个答复的朋友就一语道破封 JavaScript 诠释器是一件何等可笑的工作。

小法式不让用 JS 诠释器?那我再肛一次鹅厂-6.jpg

公密告出来的第一天,就有朋友在批评区中抖机灵

第二,你可以把一切可以从获得分歧输入,而且发生分歧成果的法式都称之为诠释器,不过就是它表达才能的强与弱、是通用的还是公用的区分而已,所以这个界限是很是模糊的。比如我们营业中,能够需要法式去办事器上拉一份设置,这份设置能够是某些功用的开关显现与否等等,那末这时辰我拉的一份设置文件和拉了一份 JavaScript 代码静态履行有本质上的区分吗?实在也你可以了解代码不外是一份诠释器/编译器的设置文件而已,没有那末特别,唯一的区分仅仅是代码设想通用且复杂。所以才有那末一句话,代码既数据,数据既代码。

写在最初

在文章的最初,要向两位科学家致敬。第一位是艾伦·图灵,提出了图灵机奠基了计较理论的根本。第二位是香农,奠基了现代信息论的根本。感激伟人们给我们供给的肩膀。

小法式不让用 JS 诠释器?那我再肛一次鹅厂-7.jpg

艾伦·图灵(左) 克劳德·香农(右)
回复

使用道具

大神点评

liuhenry 2022-7-15 21:43:05 显示全部楼层
我们挑选lisp ,间接下发一段json[思考]坐等json违规。
回复

使用道具 举报

公子无咎 2022-7-15 21:43:42 显示全部楼层
[酷]实在差不多,hhhh
回复

使用道具 举报

QGSbDJqi 2022-7-15 21:44:11 显示全部楼层
JSON 表达法式,利好 Cirru!
回复

使用道具 举报

香客斯 2022-7-15 21:45:01 显示全部楼层
看到企鹅新规时就想到你之前那篇文章,没想到这么快跟进了[欣喜]
回复

使用道具 举报

帝国 2022-7-15 21:46:01 显示全部楼层
我代码实在在新规出来的阿谁周末就已经写完了,只是文章拖到了现在[捂脸]
回复

使用道具 举报

zhangjjqb 2022-7-15 21:47:30 显示全部楼层
别做做题家了,对着干只会让规矩越加越多,考核越来越严,开辟越来越扭曲。他人不让用看不惯就削减在小法式上的投入,让市场去做挑选,做做题家还是太纯真
回复

使用道具 举报

Kaoyao123 2022-7-15 21:47:42 显示全部楼层
[吃瓜]我就做个玩具炫技,隔邻上纲上线呢
回复

使用道具 举报

永恒永恒 2022-7-15 21:47:55 显示全部楼层
怪不得小法式这么卡[大笑]
回复

使用道具 举报

安安安安安 2022-7-15 21:49:14 显示全部楼层
这个就不是技术能处理的题目,跑得了僧人跑不了庙,企鹅要下重手不用经过技术,发现搞热更的公司统统关停小法式拉黑名单就行,公司在物理上又跑不掉。对于这类行为只能说要末忍了,要末道分歧不相为谋,搞技术匹敌只会升级惩办力度。
回复

使用道具 举报

说点什么

您需要登录后才可以回帖 登录 | 立即注册
HOT • 推荐

神回复

站长姓名:王殿武 杭州共生网络科技 创始人 云裂变新零售系统 创始人 飞商人脉对接平台 创始人 同城交友聚会平台 创始人 生活经验分享社区 创始人 合作微信:15924191378(注明来意)