1 Star 2 Fork 1

郑佳煜/wxappUnpacker

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
wuRestoreZ.js 7.02 KB
一键复制 编辑 原始数据 按行查看 历史
const wu=require("./wuLib.js");
const {VM}=require('vm2');
function catchZGroup(code,groupPreStr,cb){
const debugPre="(function(z){var a=11;function Z(ops,debugLine){";
let zArr={};
for(let preStr of groupPreStr){
let content=code.slice(code.indexOf(preStr)),z=[];
content=content.slice(content.indexOf("(function(z){var a=11;"));
content=content.slice(0,content.indexOf("})(__WXML_GLOBAL__.ops_cached.$gwx"))+"})(z);";
let vm=new VM({sandbox:{z:z,debugInfo:[]}});
vm.run(content);
if(content.startsWith(debugPre))for(let i=0;i<z.length;i++)z[i]=z[i][1];
zArr[preStr.match(/function gz\$gwx(\d*\_\d+)/)[1]]=z;
}
cb({"mul":zArr});
}
function catchZ(code,cb){
let groupTest=code.match(/function gz\$gwx(\d*\_\d+)\(\)\{\s*if\( __WXML_GLOBAL__\.ops_cached\.\$gwx\d*\_\d+\)/g);
if(groupTest!==null)return catchZGroup(code,groupTest,cb);
let z=[],vm=new VM({sandbox:{
z:z,
debugInfo:[]
}});
let lastPtr=code.lastIndexOf("(z);__WXML_GLOBAL__.ops_set.$gwx=z;");
if(lastPtr==-1)lastPtr=code.lastIndexOf("(z);__WXML_GLOBAL__.ops_set.$gwx");
code=code.slice(code.indexOf('(function(z){var a=11;function Z(ops){z.push(ops)}'),lastPtr+4);
vm.run(code);
cb(z);
}
function restoreSingle(ops,withScope=false){
if(typeof ops=="undefined")return "";
function scope(value){
if(value.startsWith('{')&&value.endsWith('}'))return withScope?value:"{"+value+"}";
return withScope?value:"{{"+value+"}}";
}
function enBrace(value,type='{'){
if(value.startsWith('{')||value.startsWith('[')||value.startsWith('(')||value.endsWith('}')||value.endsWith(']')||value.endsWith(')'))value=' '+value+' ';
switch(type){
case '{':
return '{'+value+'}';
case '[':
return '['+value+']';
case '(':
return '('+value+')';
default:
throw Error("Unknown brace type "+type);
}
}
function restoreNext(ops,w=withScope){
return restoreSingle(ops,w);
}
function jsoToWxon(obj){//convert JS Object to Wechat Object Notation(No quotes@key+str)
let ans="";
if(typeof obj==="undefined"){
return 'undefined';
}else if(obj===null){
return 'null';
}else if(obj instanceof RegExp){
return obj.toString();
}else if(obj instanceof Array){
for(let i=0;i<obj.length;i++)ans+=','+jsoToWxon(obj[i]);
return enBrace(ans.slice(1),'[');
}else if(typeof obj=="object"){
for(let k in obj)ans+=","+k+":"+jsoToWxon(obj[k]);
return enBrace(ans.slice(1),'{');
}else if(typeof obj=="string"){
let parts=obj.split('"'),ret=[];
for(let part of parts){
let atoms=part.split("'"),ans=[];
for(let atom of atoms)ans.push(JSON.stringify(atom).slice(1,-1));
ret.push(ans.join("\\'"));
}
return "'"+ret.join('"')+"'";
}else return JSON.stringify(obj);
}
let op=ops[0];
if(typeof op!="object"){
switch(op){
case 3://string
return ops[1];//may cause problems if wx use it to be string
case 1://direct value
return scope(jsoToWxon(ops[1]));
case 11://values list, According to var a = 11;
let ans="";
ops.shift();
for(let perOp of ops)ans+=restoreNext(perOp);
return ans;
}
}else{
let ans="";
switch(op[0]){//vop
case 2://arithmetic operator
{
function getPrior(op,len){
const priorList={
"?:":4,"&&":6,"||":5,"+":13,"*":14,"/":14,"%":14,"|":7,"^":8,"&":9,"!":16,"~":16,
"===":10,"==":10,"!=":10,"!==":10,">=":11,"<=":11,">":11,"<":11,"<<":12,">>":12,
"-":len==3?13:16
};
return priorList[op]?priorList[op]:0;
}
function getOp(i){
let ret=restoreNext(ops[i],true);
if(ops[i] instanceof Object&&typeof ops[i][0]=="object"&&ops[i][0][0]==2){
//Add brackets if we need
if(getPrior(op[1],ops.length)>getPrior(ops[i][0][1],ops[i].length))ret=enBrace(ret,'(');;
}
return ret;
}
switch(op[1]){
case"?:":
ans=getOp(1)+"?"+getOp(2)+":"+getOp(3);
break;
case "!":
case "~":
ans=op[1]+getOp(1);
break;
case"-":
if(ops.length!=3){
ans=op[1]+getOp(1);
break;
}//shoud not add more in there![fall through]
default:
ans=getOp(1)+op[1]+getOp(2);
}
break;
}
case 4://unkown-arrayStart?
ans=restoreNext(ops[1],true);
break;
case 5://merge-array
{
switch (ops.length) {
case 2:
ans=enBrace(restoreNext(ops[1],true),'[');
break;
case 1:
ans='[]';
break;
default:
{
let a=restoreNext(ops[1],true);
//console.log(a,a.startsWith('[')&&a.endsWith(']'));
if(a.startsWith('[')&&a.endsWith(']')){
if(a!='[]'){
ans=enBrace(a.slice(1,-1).trim()+','+restoreNext(ops[2],true),'[');
//console.log('-',a);
}else{
ans=enBrace(restoreNext(ops[2],true),'[');
}
}else{
ans=enBrace('...'+a+','+restoreNext(ops[2],true),'[');//may/must not support in fact
}
}
}
break;
}
case 6://get value of an object
{
let sonName=restoreNext(ops[2],true);
if(sonName._type==="var")
ans=restoreNext(ops[1],true)+enBrace(sonName,'[');
else{
let attach="";
if(/^[A-Za-z\_][A-Za-z\d\_]*$/.test(sonName)/*is a qualified id*/)
attach='.'+sonName;
else attach=enBrace(sonName,'[');
ans=restoreNext(ops[1],true)+attach;
}
break;
}
case 7://get value of str
{
switch(ops[1][0]){
case 11:
ans=enBrace("__unTestedGetValue:"+enBrace(jsoToWxon(ops),'['),'{');
break;
case 3:
ans=new String(ops[1][1]);
ans._type="var";
break;
default:
throw Error("Unknown type to get value");
}
break;
}
case 8://first object
ans=enBrace(ops[1]+':'+restoreNext(ops[2],true),'{');//ops[1] have only this way to define
break;
case 9://object
{
function type(x){
if(x.startsWith('...'))return 1;
if(x.startsWith('{')&&x.endsWith('}'))return 0;
return 2;
}
let a=restoreNext(ops[1],true);
let b=restoreNext(ops[2],true);
let xa=type(a),xb=type(b);
if(xa==2||xb==2)ans=enBrace("__unkownMerge:"+enBrace(a+","+b,'['),'{');
else{
if(!xa)a=a.slice(1,-1).trim();
if(!xb)b=b.slice(1,-1).trim();
//console.log(l,r);
ans=enBrace(a+','+b,'{');
}
break;
}
case 10://...object
ans='...'+restoreNext(ops[1],true);
break;
case 12:
{
let arr=restoreNext(ops[2],true);
if(arr.startsWith('[')&&arr.endsWith(']'))
ans=restoreNext(ops[1],true)+enBrace(arr.slice(1,-1).trim(),'(');
else ans=restoreNext(ops[1],true)+'.apply'+enBrace('null,'+arr,'(');
break;
}
default:
ans=enBrace("__unkownSpecific:"+jsoToWxon(ops),'{');
}
return scope(ans);
}
}
function restoreGroup(z){
let ans=[];
for(let g in z.mul){
let singleAns=[];
for(let e of z.mul[g])singleAns.push(restoreSingle(e,false));
ans[g]=singleAns;
}
let ret=[];//Keep a null array for remaining global Z array.
ret.mul=ans;
return ret;
}
function restoreAll(z){
if(z.mul)return restoreGroup(z);
let ans=[];
for(let e of z)ans.push(restoreSingle(e,false));
return ans;
}
module.exports={getZ(code,cb){
catchZ(code,z=>cb(restoreAll(z)));
}};
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ZJaGee/wxappUnpacker.git
git@gitee.com:ZJaGee/wxappUnpacker.git
ZJaGee
wxappUnpacker
wxappUnpacker
master

搜索帮助