There are many wxapkg unpacking tools, the text is attached with python3 unpacking tools, others can be searched on github
# coding: utf-8
# py2 origin author lrdcq
# usage python3 unwxapkg.py filename
__author__ = 'Integ: https://github.com./integ'
import sys, os
import struct
class WxapkgFile(object):
nameLen = 0
name = ""
offset = 0
size = 0
if len(sys.argv) < 2:
print('usage: unwxapkg.py filename [output_dir]')
exit()
with open(sys.argv[1], "rb") as f:
root = os.path.dirname(os.path.realpath(f.name))
name = os.path.basename(f.name) + '_dir'
if len(sys.argv) > 2:
name = sys.argv[2]
#read header
firstMark = struct.unpack('B', f.read(1))[0]
print('first header mark = {}'.format(firstMark))
info1 = struct.unpack('>L', f.read(4))[0]
print('info1 = {}'.format(info1))
indexInfoLength = struct.unpack('>L', f.read(4))[0]
print('indexInfoLength = {}'.format(indexInfoLength))
bodyInfoLength = struct.unpack('>L', f.read(4))[0]
print('bodyInfoLength = {}'.format(bodyInfoLength))
lastMark = struct.unpack('B', f.read(1))[0]
print('last header mark = {}'.format(lastMark))
if firstMark != 0xBE or lastMark != 0xED:
print('its not a wxapkg file!!!!!')
f.close()
exit()
fileCount = struct.unpack('>L', f.read(4))[0]
print('fileCount = {}'.format(fileCount))
#read index
fileList = []
for i in range(fileCount):
data = WxapkgFile()
data.nameLen = struct.unpack('>L', f.read(4))[0]
data.name = f.read(data.nameLen)
data.offset = struct.unpack('>L', f.read(4))[0]
data.size = struct.unpack('>L', f.read(4))[0]
print('readFile = {} at Offset = {}'.format(str(data.name, encoding = "utf-8"), data.offset))
fileList.append(data)
#save files
for d in fileList:
d.name = '/' + name + str(d.name, encoding = "utf-8")
path = root + os.path.dirname(d.name)
if not os.path.exists(path):
os.makedirs(path)
w = open(root + d.name, 'wb')
f.seek(d.offset)
w.write(f.read(d.size))
w.close()
print('writeFile = {}{}'.format(root, d.name))
f.close()
unpacked file path
-\pages wxss style files for each page
-app-config.json Summary of page configuration (app.json + configuration file for each page)
-app-service.js Summary of source code js, just format it directly
-page-frame.html summary of wxml files
Mainly deal with the page-frame.html file, you need to modify some of the code inside, the modified code is as follows:
Add wxml output method:
function forwxml(raw){
var str="";
for(var i in raw){
if(i=="tag"){
if(raw[i]!="virtual"){
str+="<"+raw[i];
}
if(raw["wx:for-items"]!=undefined){
str+=" wx:for-items=\""+raw["wx:for-items"]+"\"";
}
if(raw["wx:key"]!=undefined){
str+=" wx:key=\""+raw["wx:key"]+"\"";
}
if(raw["attr"]!=undefined){
for(var j in raw["attr"]){
str+=" "+j+"=\""+raw["attr"][j]+"\"";
}
}
if(raw[i]!="virtual"){
str+=">";
}
if(raw["children"]!=undefined){
for(var k in raw["children"]){
if(typeof(raw["children"][k])=="object"){
str+=forwxml(raw["children"][k]);
}else{
str+=raw["children"][k];
}
}
}
if(raw[i]!="virtual"){
str+="</"+raw[i]+">";
}
}
}
return str;
}
Modify the method as follows:
function _v(k) {
if (typeof(k) != 'undefined') return {
tag: 'block',
'wx:for-items': k,
children: []
};
return {
tag: 'virtual',
children: []
};
}
function _n(tag) {
$gwxc++;
if ($gwxc >= 16000) {
throw 'Dom limit exceeded, please check if there\'s any mistake you\'ve made.'
};
return {
tag: 'wx-' + tag,
attr: {},
children: [],
n: [],
raw: {},
generics: {}
}
}
function $gwrt(should_pass_type_info) {
function ArithmeticEv(ops, e, s, g, o) {
var _f = false;
var rop = ops[0][1];
var _a, _b, _c, _d, _aa, _bb;
switch (rop) {
case '?:':
_a = rev(ops[1], e, s, g, o, _f);
_c = should_pass_type_info && (wh.hn(_a) === 'h');
_d = wh.rv(_a) ? rev(ops[2], e, s, g, o, _f) : rev(ops[3], e, s, g, o, _f);
_d = _c && wh.hn(_d) === 'n' ? wh.nh(_d, 'c') : _d;
//return _d;
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
return "{{" + _a + "?'" + rev(ops[2], e, s, g, o) + "':'" + rev(ops[3], e, s, g, o) + "'}}";
break;
case '&&':
_a = rev(ops[1], e, s, g, o, _f);
_c = should_pass_type_info && (wh.hn(_a) === 'h');
_d = wh.rv(_a) ? rev(ops[2], e, s, g, o, _f) : wh.rv(_a);
_d = _c && wh.hn(_d) === 'n' ? wh.nh(_d, 'c') : _d;
//return _d;
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_b = rev(ops[2], e, s, g, o);
if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
_b = _b.replace("{{", "").replace("}}", "");
}
return _a + "&&" + _b;
break;
case '||':
_a = rev(ops[1], e, s, g, o, _f);
_c = should_pass_type_info && (wh.hn(_a) === 'h');
_d = wh.rv(_a) ? wh.rv(_a) : rev(ops[2], e, s, g, o, _f);
_d = _c && wh.hn(_d) === 'n' ? wh.nh(_d, 'c') : _d;
//return _d;
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_b = rev(ops[2], e, s, g, o);
if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
_b = _b.replace("{{", "").replace("}}", "");
}
return _a + "||" + _b;
break;
case '+':
case '*':
case '/':
case '%':
case '|':
case '^':
case '&':
case '===':
case '==':
case '!=':
case '!==':
case '>=':
case '<=':
case '>':
case '<':
case '<<':
case '>>':
_a = rev(ops[1], e, s, g, o, _f);
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_b = rev(ops[2], e, s, g, o, _f);
if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
_b = _b.replace("{{", "").replace("}}", "");
}
_c = should_pass_type_info && (wh.hn(_a) === 'h' || wh.hn(_b) === 'h');
switch (rop) {
case '+':
_d = wh.rv(_a) + wh.rv(_b);
break;
case '*':
_d = wh.rv(_a) * wh.rv(_b);
break;
case '/':
_d = wh.rv(_a) / wh.rv(_b);
break;
case '%':
_d = wh.rv(_a) % wh.rv(_b);
break;
case '|':
_d = wh.rv(_a) | wh.rv(_b);
break;
case '^':
_d = wh.rv(_a) ^ wh.rv(_b);
break;
case '&':
_d = wh.rv(_a) & wh.rv(_b);
break;
case '===':
_d = wh.rv(_a) === wh.rv(_b);
break;
case '==':
_d = wh.rv(_a) == wh.rv(_b);
break;
case '!=':
_d = wh.rv(_a) != wh.rv(_b);
break;
case '!==':
_d = wh.rv(_a) !== wh.rv(_b);
break;
case '>=':
_d = wh.rv(_a) >= wh.rv(_b);
break;
case '<=':
_d = wh.rv(_a) <= wh.rv(_b);
break;
case '>':
_d = wh.rv(_a) > wh.rv(_b);
break;
case '<':
_d = wh.rv(_a) < wh.rv(_b);
break;
case '<<':
_d = wh.rv(_a) << wh.rv(_b);
break;
case '>>':
_d = wh.rv(_a) >> wh.rv(_b);
break;
default:
break;
}
//return _c ? wh.nh( _d, "c" ) : _d;
return "" + _a + rop + _b + "";
break;
case '-':
_a = ops.length === 3 ? rev(ops[1], e, s, g, o, _f) : 0;
_b = ops.length === 3 ? rev(ops[2], e, s, g, o, _f) : rev(ops[1], e, s, g, o, _f);
_c = should_pass_type_info && (wh.hn(_a) === 'h' || wh.hn(_b) === 'h');
_d = _c ? wh.rv(_a) - wh.rv(_b) : _a - _b;
//return _c ? wh.nh( _d, "c" ) : _d;
return "" + _a + rop + _b + "";
break;
case '!':
_a = rev(ops[1], e, s, g, o, _f);
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_c = should_pass_type_info && (wh.hn(_a) == 'h');
_d = !wh.rv(_a);
//return _c ? wh.nh( _d, "c" ) : _d;
return "" + rop + _a + "";
case '~':
_a = rev(ops[1], e, s, g, o, _f);
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_c = should_pass_type_info && (wh.hn(_a) == 'h');
_d = ~wh.rv(_a);
//return _c ? wh.nh( _d, "c" ) : _d;
return "" + rop + _a + "";
default:
$gwn('unrecognized op' + rop);
}
}
function rev(ops, e, s, g, o, newap) {
var op = ops[0];
var _f = false;
if (typeof newap !== "undefined") o.ap = newap;
if (typeof(op) === 'object') {
var vop = op[0];
var _a, _aa, _b, _bb, _c, _d, _s, _e, _ta, _tb, _td;
switch (vop) {
case 2:
return ArithmeticEv(ops, e, s, g, o);
break;
case 4:
return rev(ops[1], e, s, g, o, _f);
break;
case 5:
switch (ops.length) {
case 2:
_a = rev(ops[1], e, s, g, o, _f);
return should_pass_type_info ? [_a] : [wh.rv(_a)];
return [_a];
break;
case 1:
return [];
break;
default:
_a = rev(ops[1], e, s, g, o, _f);
_b = rev(ops[2], e, s, g, o, _f);
_a.push(should_pass_type_info ? _b: wh.rv(_b));
return _a;
break;
}
break;
case 6:
_a = rev(ops[1], e, s, g, o);
if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
_a = _a.replace("{{", "").replace("}}", "");
}
_b = rev(ops[2], e, s, g, o);
if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
_b = _b.replace("{{", "").replace("}}", "");
}
if (typeof(_b) == "number") {
return "{{" + _a + "[" + _b + "]}}";
}
return "{{" + _a + "." + _b + "}}";
var ap = o.ap;
_ta = wh.hn(_a) === 'h';
_aa = _ta ? wh.rv(_a) : _a;
o.is_affected |= _ta;
if (should_pass_type_info) {
if (_aa === null || typeof(_aa) === 'undefined') {
return _ta ? wh.nh(undefined, 'e') : undefined;
}
_b = rev(ops[2], e, s, g, o, _f);
_tb = wh.hn(_b) === 'h';
_bb = _tb ? wh.rv(_b) : _b;
o.ap = ap;
o.is_affected |= _tb;
if (_bb === null || typeof(_bb) === 'undefined' || _bb === "__proto__" || _bb === "prototype" || _bb === "caller") {
return (_ta || _tb) ? wh.nh(undefined, 'e') : undefined;
}
_d = _aa[_bb];
if (typeof _d === 'function' && !ap) _d = undefined;
_td = wh.hn(_d) === 'h';
o.is_affected |= _td;
return (_ta || _tb) ? (_td ? _d: wh.nh(_d, 'e')) : _d;
} else {
if (_aa === null || typeof(_aa) === 'undefined') {
return undefined;
}
_b = rev(ops[2], e, s, g, o, _f);
_tb = wh.hn(_b) === 'h';
_bb = _tb ? wh.rv(_b) : _b;
o.ap = ap;
o.is_affected |= _tb;
if (_bb === null || typeof(_bb) === 'undefined' || _bb === "__proto__" || _bb === "prototype" || _bb === "caller") {
return undefined;
}
_d = _aa[_bb];
if (typeof _d === 'function' && !ap) _d = undefined;
_td = wh.hn(_d) === 'h';
o.is_affected |= _td;
return _td ? wh.rv(_d) : _d;
}
case 7:
switch (ops[1][0]) {
case 11:
o.is_affected |= wh.hn(g) === 'h';
return g;
case 3:
_s = wh.rv(s);
_e = wh.rv(e);
_b = ops[1][1];
if (g && g.f && g.f.hasOwnProperty(_b)) {
_a = g.f;
o.ap = true;
} else {
_a = _s && _s.hasOwnProperty(_b) ? s: (_e && _e.hasOwnProperty(_b) ? e: undefined);
}
if (should_pass_type_info) {
if (_a) {
_ta = wh.hn(_a) === 'h';
_aa = _ta ? wh.rv(_a) : _a;
_d = _aa[_b];
_td = wh.hn(_d) === 'h';
o.is_affected |= _ta || _td;
_d = _ta && !_td ? wh.nh(_d, 'e') : _d;
return _d;
}
} else {
if (_a) {
_ta = wh.hn(_a) === 'h';
_aa = _ta ? wh.rv(_a) : _a;
_d = _aa[_b];
_td = wh.hn(_d) === 'h';
o.is_affected |= _ta || _td;
//return wh.rv(_d);
if (!new RegExp("{{").test(_d)) {
return "" + _d + "";
}
return "" + ops[1][1] + "";
}
}
//return undefined;
return "{{" + ops[1][1] + "}}";
}
break;
case 8:
_a = {};
_a[ops[1]] = rev(ops[2], e, s, g, o, _f);
return _a;
break;
case 9:
_a = rev(ops[1], e, s, g, o, _f);
_b = rev(ops[2], e, s, g, o, _f);
function merge(_a, _b, _ow) {
var ka, _bbk;
_ta = wh.hn(_a) === 'h';
_tb = wh.hn(_b) === 'h';
_aa = wh.rv(_a);
_bb = wh.rv(_b);
for (var k in _bb) {
if (_ow || !_aa.hasOwnProperty(k)) {
_aa[k] = should_pass_type_info ? (_tb ? wh.nh(_bb[k], 'e') : _bb[k]) : wh.rv(_bb[k]);
}
}
return _a;
}
var _c = _a
var _ow = true
if (typeof(ops[1][0]) === "object" && ops[1][0][0] === 10) {
_a = _b _b = _c _ow = false
}
if (typeof(ops[1][0]) === "object" && ops[1][0][0] === 10) {
var _r = {}
return merge(merge(_r, _a, _ow), _b, _ow);
} else return merge(_a, _b, _ow);
break;
case 10:
_a = rev(ops[1], e, s, g, o, _f);
_a = should_pass_type_info ? _a: wh.rv(_a);
return _a;
break;
case 125:
var _r;
_a = rev(ops[1], e, s, g, o);
if (!o.ap) {
return should_pass_type_info && wh.hn(_a) === 'h' ? wh.nh(_r, 'f') : _r;
}
var ap = o.ap;
_b = rev(ops[2], e, s, g, o, _f);
o.ap = ap;
_ta = wh.hn(_a) === 'h';
_tb = _ca(_b);
_aa = wh.rv(_a);
_bb = wh.rv(_b);
snap_bb = $gdc(_bb, "nv_");
try {
_r = typeof _aa === "function" ? $gdc(_aa.apply(null, snap_bb)) : undefined;
} catch(e) {
e.message = e.message.replace(/nv_/g, "");
e.stack = e.stack.substring(0, e.stack.indexOf("\n", e.stack.lastIndexOf("at nv_")));
e.stack = e.stack.replace(/\snv_/g, " ");
e.stack = $gstack(e.stack);
if ("undefined" !== typeof debugInfo) e.stack += "\n " + " " + " " + " at " + debugInfo[g.opindex][0] + ":" + debugInfo[g.opindex][1] + ":" + debugInfo[g.opindex][2];
throw e;
}
return should_pass_type_info && (_tb || _ta) ? wh.nh(_r, 'f') : _r;
}
} else {
if (op === 3 || op === 1) return ops[1];
else if (op === 11) {
var _a = '';
for (var i = 1; i < ops.length; i++) {
var xp = wh.rv(rev(ops[i], e, s, g, o, _f));
_a += typeof(xp) === 'undefined' ? '': xp;
}
return _a;
}
}
}
return rev;
}
gra = $gwrt(true);
grb = $gwrt(false);
function TestTest(expr, ops, e, s, g, expect_a, expect_b, expect_affected) {
{
var o = {
is_affected: false
};
var a = gra(ops, e, s, g, o);
if (JSON.stringify(a) != JSON.stringify(expect_a) || o.is_affected != expect_affected) {
console.warn("A. " + expr + " get result " + JSON.stringify(a) + ", " + o.is_affected + ", but " + JSON.stringify(expect_a) + ", " + expect_affected + " is expected");
}
} {
var o = {
is_affected: false
};
var a = grb(ops, e, s, g, o);
if (JSON.stringify(a) != JSON.stringify(expect_b) || o.is_affected != expect_affected) {
console.warn("B. " + expr + " get result " + JSON.stringify(a) + ", " + o.is_affected + ", but " + JSON.stringify(expect_b) + ", " + expect_affected + " is expected");
}
}
}
function wfor(to_iter, func, env, _s, global, father, itemname, indexname, keyname) {
console.info(itemname);
var _n = wh.hn(to_iter) === 'n';
var scope = wh.rv(_s);
var has_old_item = scope.hasOwnProperty(itemname);
var has_old_index = scope.hasOwnProperty(indexname);
var old_item = scope[itemname];
var old_index = scope[indexname];
var full = Object.prototype.toString.call(wh.rv(to_iter));
var type = full[8];
if (type === 'N' && full[10] === 'l') type = 'X';
var _y;
if (_n) {
if (type === 'A') {
var r_iter_item;
for (var i = 0; i < to_iter.length; i++) {
scope[itemname] = to_iter[i];
scope[indexname] = _n ? i: wh.nh(i, 'h');
r_iter_item = wh.rv(to_iter[i]);
var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
_y = _v(key);
_(father, _y);
func(env, scope, _y, global);
}
} else if (type === 'O') {
var i = 0;
var r_iter_item;
for (var k in to_iter) {
scope[itemname] = to_iter[k];
scope[indexname] = _n ? k: wh.nh(k, 'h');
r_iter_item = wh.rv(to_iter[k]);
var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
_y = _v(key);
_(father, _y);
func(env, scope, _y, global);
i++;
}
} else if (type === 'S') {
for (var i = 0; i < 1; i++) {
scope[itemname] = to_iter;
scope[indexname] = _n ? i: wh.nh(i, 'h');
_y = _v(to_iter);
_y["wx:key"] = keyname _(father, _y);
func(env, scope, _y, global);
}
} else if (type === 'N') {
for (var i = 0; i < to_iter; i++) {
scope[itemname] = i;
scope[indexname] = _n ? i: wh.nh(i, 'h');
_y = _v(i);
_(father, _y);
func(env, scope, _y, global);
}
} else {}
} else {
var r_to_iter = wh.rv(to_iter);
var r_iter_item, iter_item;
if (type === 'A') {
for (var i = 0; i < r_to_iter.length; i++) {
iter_item = r_to_iter[i];
iter_item = wh.hn(iter_item) === 'n' ? wh.nh(iter_item, 'h') : iter_item;
r_iter_item = wh.rv(iter_item);
scope[itemname] = iter_item scope[indexname] = _n ? i: wh.nh(i, 'h');
var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
_y = _v(key);
_(father, _y);
func(env, scope, _y, global);
}
} else if (type === 'O') {
var i = 0;
for (var k in r_to_iter) {
iter_item = r_to_iter[k];
iter_item = wh.hn(iter_item) === 'n' ? wh.nh(iter_item, 'h') : iter_item;
r_iter_item = wh.rv(iter_item);
scope[itemname] = iter_item;
scope[indexname] = _n ? k: wh.nh(k, 'h');
var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
_y = _v(key);
_(father, _y);
func(env, scope, _y, global);
i++
}
} else if (type === 'S') {
for (var i = 0; i < r_to_iter.length; i++) {
iter_item = wh.nh(r_to_iter[i], 'h');
scope[itemname] = iter_item;
scope[indexname] = _n ? i: wh.nh(i, 'h');
_y = _v(to_iter[i] + i);
_(father, _y);
func(env, scope, _y, global);
}
} else if (type === 'N') {
for (var i = 0; i < r_to_iter; i++) {
iter_item = wh.nh(i, 'h');
scope[itemname] = iter_item;
scope[indexname] = _n ? i: wh.nh(i, 'h');
_y = _v(i);
_(father, _y);
func(env, scope, _y, global);
}
} else {}
}
if (has_old_item) {
scope[itemname] = old_item;
} else {
delete scope[itemname];
}
if (has_old_index) {
scope[indexname] = old_index;
} else {
delete scope[indexname];
}
}
Modify this, add log output
if (path && e_[path]) {
window.__wxml_comp_version__ = 0.02
return function(env, dd, global) {
$gwxc = 0;
var root = {
"tag": "wx-page"
};
root.children = []
var main = e_[path].f
if (typeof global === "undefined") global = {};
global.f = $gdc(f_[path], "", 1);
if (typeof(window.__webview_engine_version__) != 'undefined' && window.__webview_engine_version__ + 1e-6 >= 0.02 + 1e-6 && window.__mergeData__) {
env = window.__mergeData__(env, dd);
}
try {
main(env, {},
root, global);
if (typeof(window.__webview_engine_version__) == 'undefined' || window.__webview_engine_version__ + 1e-6 < 0.01 + 1e-6) {
console.log(forwxml(_ev(root)));
return _ev(root);
}
} catch(err) {
console.log(err)
}
console.log("result:" + root) return root;
}
}
}
Modify the following method, add output, open the web page, you can see the corresponding wxss in the console (check the wxss in each page, replace setCssToHead):
function makeup(file, suffix) {
var _n = typeof(file) === "number";
if ( _n && Ca.hasOwnProperty(file)) return "";
if ( _n ) Ca[file] = 1;
var ex = _n ? _C[file] : file;
var res="";
for (var i = ex.length - 1; i >= 0; i--) {
var content = ex[i];
if (typeof(content) === "object")
{
var op = content[0];
if ( op == 0 )
res = transformRPX(content[1]) + "px" + res;
else if ( op == 1)
res = suffix + res;
else if ( op == 2 )
res = makeup(content[1], suffix) + res;
}
else
res = content + res
}
console.log(res);
return res;
}
Different mini programs may have different functions and variables due to different compilation and launch times.
This article is for the version of window.__wcc_version__='v0.6vv_20171208_cua_xc', other versions may have some problems
Open page-frame.html in chrome and enter in the console:
//解析单个wxml
$gwx("...wxml地址...")(); //例如$gwx("./pages/all/all.wxml")();
The wxml address is at this location in the page-frame.html file var x=['./pages/all/all.wxml'];