0x00 序言

很久之前就听说过VM加密,但一直对VM概念很模糊,于是最近便想去下VM壳相关的技术,但在网上各种帖子学习到的知识有限,不能很好的去了解VM壳的一些原理和机制,于是就在想去找个VM壳进行逆向,看看能不能去学习到些什么东西。

本次逆向的是某鹅基于JavaScript语言的一个栈式虚拟机,不得不说刚接触这个代码的时候着实看不懂写的是什么东西,可是随着慢慢的深入,越发觉得这个虚拟机犹如一个艺术品,很是奇妙。

下面就随着我一起一步步,揭开这个虚拟机的神秘面纱吧!

注:若有侵权,请联系我立即删除,本文只作为交流学习用途,一些关键信息已做相关处理。

0x01 准备工作

首先说明下我们的目的,验证码在滑动完成以后会向服务器发送一些数据,这些数据包含了一些必要或者非必要的信息。必要的信息如下:

某鹅滑块验证码破解笔记

image-20210910202439882.png

可以看到字段名是collect,根据字段名可以猜测到这个字段值是一些收集的数据,可能包含一些浏览器环境信息以及我们滑动滑块的轨迹或者是鼠标的移动轨迹这类的信息,另一个必要信息如下:

某鹅滑块验证码破解笔记

image-20210910202905631.png

以上两个加密字段值,是如何生成的,里面包含了一些什么数据,如何去模拟达到破解滑块的目的,便是此文章的目的。

0x02 定位加密点

通过浏览器控制台的搜索,我们试着搜索下这个collect字段:

某鹅滑块验证码破解笔记

image-20210910203451250.png

跟进去,在此处下断点:

某鹅滑块验证码破解笔记

image-20210910203537714.png

再次滑动,果不其然在这个地方断了下来:

某鹅滑块验证码破解笔记

image-20210910203711040.png

简单分析了下e的值,发现和我们提交的参数格式基本一致,所以collect应该就是在这个地方赋值的,接下来就是看看R()函数是怎么生成collect的,跟进R函数如下:

某鹅滑块验证码破解笔记

image-20210910203926637.png

现在跟到了getData这个函数,我们下断点,继续执行代码,让断点触发,然后到控制台打印了下a变量,a看起来像是一个接口,提供了一些函数:

某鹅滑块验证码破解笔记

image-20210910204229899.png

继续往上面找找,看看a是怎么来的,在上面几行找到了a的赋值:

某鹅滑块验证码破解笔记

image-20210910204412760.png

a = window.TDC

看起来是在window对象里面又定义了一个TDC对象,然后将TDC对象赋值给了a,现在让我们看看getData函数的实现,跟进来,就跟到了这个地方:

所以getData函数的实现应如下:

//getData实现function k() {        var B = A.slice(0);        B[0] = [this],        B[1] = [arguments],        B[2] = [k];        for (var M = 0; M < G.length && M < arguments.length; M++)                0 < G[M] && (B[G[M]] = [arguments[M]]);        return __TENCENT_CHAOS_VM(w, C, T, B, H, U, J, Z)}//getData外层匿名函数function() {        for (var w = C[D++], A = [], B = C[D++], M = C[D++], G = [], Q = 0; Q < B; Q++)                A[C[D++]] = E[C[D++]];        for (Q = 0; Q < M; Q++)                G[Q] = C[D++];        E.push(        function k() {                        var B = A.slice(0);                        B[0] = [this],                        B[1] = [arguments],                        B[2] = [k];                        for (var M = 0; M < G.length && M < arguments.length; M++)                                0 < G[M] && (B[G[M]] = [arguments[M]]);                        return __TENCENT_CHAOS_VM(w, C, T, B, H, U, J, Z)                })}//getData函数体里面,A、B、G变量对应的都是外层匿名函数的局部变量,就是当getData函数被push进E的时候的变量值

可能解释的有些不太清楚,我们先来看看下面的代码:

var E = []; //声明了一个空数组E,用来存放函数(function TEST(){ //立即执行函数    var rand = Math.random() //生成随机数    console.log(rand)    E.push(function (){ //将函数存入数组        var test = rand;        console.log(test) //打印上文生成的随机数    })    if(E.length > 1)return;    TEST()})()E[0]() E[1]()

运行结果如下:

0.53717861187188860.64748716256169070.53717861187188860.6474871625616907

从这里可以发现,随机数被保存了下来,所以可以通过这种方式去实现函数部分传参的保存,当函数被调用时,所需要的变量值未被销毁,仍可以进行访问使用,那么问题来了,为什么要通过这种方式进行函数调用呢,直接写一个函数去实现相应的功能不行吗?

这个问题就要随着我一步步分析,你就会明白为什么会这样写。

为了验证getData函数是不是通过上述地方进行调用,我们把代码复制过来,通过nodejs的环境来进行调用,为了模拟真实的浏览器环境,用到一个叫做jsdom的库。

jsdom介绍如下:

jsdom 是许多 Web 标准的纯 JavaScript 实现,特别是 WHATWG DOM和HTML标准,用于 Node.js。一般来说,该项目的目标是模拟足够多的 Web 浏览器子集,以用于测试和抓取真实的 Web 应用程序。

node环境下安装:

npm install jsdom

用法:

const jsdom = require("jsdom");const {JSDOM} = jsdom;const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);window = dom.window;document = window.document;XMLHttpRequest = window.XMLHttpRequest;

完成环境模拟,我们就可以将代码复制到编辑器里面去,如下图所示:

某鹅滑块验证码破解笔记

image-20210929203518634.png

我们在代码末尾加上:

console.log(window.TDC)

打印结果如下:

{  getInfo: [Function: M],  setData: [Function: M],   clearTc: [Function: M],  getData: [Function: M] //getData函数已经能够进行调用了}

调用getData函数:

console.log(window.TDC.getData())

结果如下:

e43rYszBdPpLFbYEnvf6EH423DMkVfmqhtQV%2BCnQMWEdGBJzm4MFSOGDFX0ykuQGqe4c1cxY5APK40WOd9u7mbdwXIQ1x9OBSgdVHmORAxmVEXILfudlFIYF4KW7ZuOdX9ixo4efmMqIViV1IKT%2B24mEOmUJ2xtr6ULKcsrp0Xg3GQkNZ7iWy2G87RaR5NpSgHnX6q8eD5UIoml8J6bqef1JDKK%2BW4iXKaj3j5PGwLo%2FqrW1 mWy%2BB0MSvS91m%2FYk%2BNtC79fF0pOuSvflUSrAAohWJXUgpP7b%2BTuue9zspkzK8nLSWZGjTc4sycUohsG5owCAZch4y%2FYdttQ4D4nFT4hWJXUgpP7bM3NuzmNY663gs%2FQ7BKUdIk9HX3mnJQOT%2FB2S9xc25mskD87Pieargmi4QVyC1l%2Bnr5VFrxOHLI%2FkcpgPZqPrbVoWKk8cGT03izOvvebVB7xzp4B06AdsZe 7Q%2FnP%2BALoM%2F3Q6Sp0JU7daFipPHBk9N1oWKk8cGT03mCh6%2FirnaBoh%2BZs4V9dDlA%3D%3D

在调用处下断点:

某鹅滑块验证码破解笔记

image-20210929204326642.png

进入调试模式,F7步入:

某鹅滑块验证码破解笔记

image-20210929204442157.png

可以看到函数进入到了前面我们分析的这个地方。接下来先对整个代码的结构进行分析。

0x03 代码结构分析

先把代码全部折叠,主要的函数是TENCENT_CHAOS_STACK函数,又把TENCENT_CHAOS_STACK函数下级进行展开,结构如下:

var __TENCENT_CHAOS_STACK = function() {    function __TENCENT_CHAOS_VM(c, R, H, h, I, C, w, F) {...}        function I(E) {...}    return __TENCENT_CHAOS_VM.v = 0,        __TENCENT_CHAOS_VM(0,                           function(E){...}(["...",[...]]),                           window)        //TENCENT_CHAOS_VM传参分析:(0, 立即函数返回值, window)                   }();

现在我们把这个立即函数单独提取出来运行:

某鹅滑块验证码破解笔记

image-20210929210108491.png

运行结果如下:

某鹅滑块验证码破解笔记

image-20210929210147252.png

其实这个运行结果可以看做是字节码,然后每一个字节码对应一个不同的操作或是数据,函数TENCENT_CHAOS_VM的作用就是解释并且执行字节码,TENCENT_CHAOS_VM函数的第一个传参是0,这个值代表PC寄存器,作用是指向下一个字节码的位置。

代码结构简化如下:

某鹅滑块验证码破解笔记

image-20210929211453882.png

现在我们知道了TENCENT_CHAOS_VM是用来解释并执行字节码的,现在让我们来看看TENCENT_CHAOS_VM的执行过程(其实到这一步各位读者可以自行去调试一下,更容易理解整个执行流程)

0x04 虚拟机执行过程

在函数入口下断点:

某鹅滑块验证码破解笔记

image-20211014213828123.png

进入调试模式,程序在断点处断下来,此时变量表如下:

某鹅滑块验证码破解笔记

image-20211014214141246.png

c是第一个被传入的变量,也就是PC变量,它指向下一个被执行字节码的位置,也就是第二个传入的变量(R,字节码)的第0个元素,即为7,我们将程序继续往下执行,来到这里:

某鹅滑块验证码破解笔记

image-20211014214818737.png

x部分指令如下:

某鹅滑块验证码破解笔记

image-20211014214856357.png

图片里面的"G为此次函数是否完成的标志",这里用"次"的原因是这个VM包含递归调用,也就是在这个函数里面又调用这个函数,我们现在知道这个函数是不停的执行字节码,PC是下一个被执行字节码或是数据的地址,那么就可以通过在不同的地方定义不同的操作,然后通过调用本函数,传入不同的PC,去完成不同的操作(也就是函数调用),通俗来讲就是和程序里面的函数偏移地址是一样的道理,通过偏移地址去找到函数,并执行函数。这个VM的第一个传参就是PC,所以可以通过定义好的函数偏移,去进行函数调用,函数的本质也是一堆指令的集合。

现在PC的值为0,上面说到对应的字节码是7:

某鹅滑块验证码破解笔记

image-20211014215952630.png

所以要执行x数组里面的第七条指令,跟进如下:

某鹅滑块验证码破解笔记

image-20211014220034306.png

h为栈,所有的数据都是通过栈来操作的,也就是把需要用到的数据存到这个栈中,然后需要用的时候取出来或者直接对栈元素进行操作h.length = R[c++]的含义是定义栈的长度,栈的长度为R[1],R(字节码)不但保存了指令,也保存了数据。

然后又回到循环的位置,执行下一个字节码:

某鹅滑块验证码破解笔记

image-20211014220230087.png

可以看到整个字节码的长度有四万多,一条一条的调试就不太现实了,现在就需要要进一步分析。

0x05 collect加密还原

在这些指令集中(x数组),包含了一个相加的指令:

h[h.length - 2] = h[h.length - 2] + h.pop()

一般字符串的拼接,都是直接相加,我们在这条指令后面,加一句console.log(h[h.length - 1]),将栈顶的数据打印出来看一看会不会有什么发现(代码最后记得加上console.log(window.TDC.getData())去调用加密):

某鹅滑块验证码破解笔记

image-20211014221745160.png

输出了很多整数,在继续往下面找,发现一个熟悉的变量:

某鹅滑块验证码破解笔记

image-20211014221847864.png

这个是tea加密的delta常量值乘以十,这个先留意一下,我们打印代码的时候,再加个判断,使控制台只打印字符串:

if(typeof h[h.length - 1] == "string"){        console.log(h[h.length - 1])}

打印的部分结果如下:

{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,""{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"",{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other"{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",tel:1634221284{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",tel:1634221284,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8"[1024[1024,[1024,768[1024,768]{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768]{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,""{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",[]{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0,{"cd":[24,"about:blank?rand=tel:1519713624347","0-0-0-24-*-*-|-*",[],176688296,[],0,0,"",[],0,0,0,1,9,[],0,0,1634221284,0,"Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/17.0.0","top",259121870,1634221284,0,"?rand=tel:1512991986334",0,"","other",1634221284,"UTF-8",[1024,768],0,1,0,"",[],0,true