`
阅读更多

1. 下载这位大神的开源项目:https://github.com/qwerty472123/wxappUnpacker.git ,要是啥也没看到注意选择分支试试

2. 使用root后的android手机或模拟器,安装微信并运行一下小程序,在目录“/data/data/com.tencent.mm/MicroMsg/{User}/appbrand/pkg”中找到对应的.wxapkg文件,对应哪一个文件就根据文件修改时间看吧

3. 在项目根目录下安装依赖:

npm install esprima
npm install css-tree
npm install cssbeautify
npm install vm2
npm install uglify-es
npm install js-beautify
npm install escodegen

 4. 

node wuWxapkg.js 你的wxapkg文件

 

补充,处理wxss时报错,wuWxss.js修改为如下:(参考项目中的第一个pull request)

const wu=require("./wuLib.js");
const path=require("path");
const fs=require("fs");
const {VM}=require('vm2');
const cssbeautify=require('cssbeautify');
const csstree=require('css-tree');
function doWxss(dir,cb){
	function GwxCfg(){}
	GwxCfg.prototype={$gwx(){}};
	for(let i=0;i<300;i++)GwxCfg.prototype["$gwx"+i]=GwxCfg.prototype.$gwx;
	let runList={},pureData={},result={},actualPure={},importCnt={},frameName="",onlyTest=true,blockCss=[];//custom block css file which won't be imported by others.(no extension name)
	function cssRebuild(data){//need to bind this as {cssFile:__name__} before call
		let cssFile;
		function statistic(data){
			function addStat(id){
				if(!importCnt[id])importCnt[id]=1,statistic(pureData[id]);
				else ++importCnt[id];
			}
			if(typeof data==="number")return addStat(data);
			for(let content of data)if(typeof content==="object"&&content[0]==2)addStat(content[1]);
		}
		function makeup(data){
			var isPure=typeof data==="number";
			if(onlyTest){
				statistic(data);
				if(!isPure){
					if(data.length==1&&data[0][0]==2)data=data[0][1];
					else return "";
				}
				if(!actualPure[data]&&!blockCss.includes(wu.changeExt(wu.toDir(cssFile,frameName),""))){
					console.log("Regard "+cssFile+" as pure import file.");
					actualPure[data]=cssFile;
				}
				return "";
			}
			let res=[],attach="";
			if(isPure&&actualPure[data]!=cssFile){
				if(actualPure[data])return '@import "'+wu.changeExt(wu.toDir(actualPure[data],cssFile),".wxss")+'";\n';
				else{
					res.push("/*! Import by _C["+data+"], whose real path we cannot found. */");
					attach="/*! Import end */";
				}
			}
			let exactData=isPure?pureData[data]:data;
			for(let content of exactData)
				if(typeof content==="object"){
					switch(content[0]){
					case 0://rpx
						res.push(content[1]+"rpx");
						break;
					case 1://add suffix, ignore it for restoring correct!
						break;
					case 2://import
						res.push(makeup(content[1]));
						break;
					}
				}else res.push(content);
			return res.join("")+attach;
		}
		return ()=>{
			cssFile=this.cssFile;
			if(!result[cssFile])result[cssFile]="";
			result[cssFile]+=makeup(data);
		};
	}
	function runVM(name, code) {
		let wxAppCode = {}, handle = { cssFile: name };
		let gg = new GwxCfg();
		let tsandbox = { $gwx: GwxCfg.prototype["$gwx"], __mainPageFrameReady__: GwxCfg.prototype["$gwx"], __wxAppCode__: wxAppCode, setCssToHead: cssRebuild.bind(handle) };
		let vm = new VM({ sandbox: tsandbox });
		vm.run(code);
		for (let name in wxAppCode) {
			if (name.endsWith(".wxss")) {
				handle.cssFile = path.resolve(frameName, "..", name);
				wxAppCode[name]();
			}
		}
	}
	function preRun(dir, frameFile, mainCode, files, cb) {
		wu.addIO(cb);
		runList[path.resolve(dir, "./app.wxss")] = mainCode;
		for (let name of files) if (name != frameFile) {
			wu.get(name, code => {
				code = code.slice(0, code.indexOf("\n"));
				if (code.indexOf("setCssToHead") > -1) runList[name] = code.slice(code.indexOf("setCssToHead"));
			});
		}
	}
	function runOnce() {
		// for (let name in runList) runVM(name, runList[name]);
		for (let name in runList) {
			// console.log(name, runList[name]);
			var start = `var window = window || {}; var __pageFrameStartTime__ = Date.now(); 	var __webviewId__; 	var __wxAppCode__={}; 	var __mainPageFrameReady__ = function(){}; 	var __WXML_GLOBAL__={entrys:{},defines:{},modules:{},ops:[],wxs_nf_init:undefined,total_ops:0}; 	var __vd_version_info__=__vd_version_info__||{};	 
			
			$gwx=function(path,global){
				if(typeof global === 'undefined') global={};if(typeof __WXML_GLOBAL__ === 'undefined') {__WXML_GLOBAL__={};
				}__WXML_GLOBAL__.modules = __WXML_GLOBAL__.modules || {};
			}`;
			runVM(name, start + " \r\n" + runList[name]);
		}
	}
	function transformCss(style){
		let ast=csstree.parse(style);
		csstree.walk(ast,function(node){
			if(node.type=="Comment"){//Change the comment because the limit of css-tree
				node.type="Raw";
				node.value="\n/*"+node.value+"*/\n";
			}
			if(node.type=="TypeSelector"){
				if(node.name.startsWith("wx-"))node.name=node.name.slice(3);
				else if(node.name=="body")node.name="page";
			}
			if(node.children){
				const removeType=["webkit","moz","ms","o"];
				let list={};
				node.children.each((son,item)=>{
					if(son.type=="Declaration"){
						if(list[son.property]){
							let a=item,b=list[son.property],x=son,y=b.data,ans=null;
							if(x.value.type=='Raw'&&x.value.value.startsWith("progid:DXImageTransform")){
								node.children.remove(a);
								ans=b;
							}else if(y.value.type=='Raw'&&y.value.value.startsWith("progid:DXImageTransform")){
								node.children.remove(b);
								ans=a;
							}else{
								let xValue=x.value.children&&x.value.children.head&&x.value.children.head.data.name,yValue=y.value.children&&y.value.children.head&&y.value.children.head.data.name;
								if(xValue&&yValue)for(let type of removeType)if(xValue==`-${type}-${yValue}`){
									node.children.remove(a);
									ans=b;
									break;
								}else if(yValue==`-${type}-${xValue}`){
									node.children.remove(b);
									ans=a;
									break;
								}else{
									let mValue=`-${type}-`;
									if(xValue.startsWith(mValue))xValue=xValue.slice(mValue.length);
									if(yValue.startsWith(mValue))yValue=yValue.slice(mValue.length);
								}
								if(ans===null)ans=b;
							}
							list[son.property]=ans;
						}else list[son.property]=item;
					}
				});
				for(let name in list)if(!name.startsWith('-'))
					for(let type of removeType){
						let fullName=`-${type}-${name}`;
						if(list[fullName]){
							node.children.remove(list[fullName]);
							delete list[fullName];
						}
					}
			}
		});
		return cssbeautify(csstree.generate(ast),{indent:'    ',autosemicolon:true});
	}
	wu.scanDirByExt(dir,".html",files=>{
		let frameFile="";
		if(fs.existsSync(path.resolve(dir,"page-frame.html")))
			frameFile=path.resolve(dir,"page-frame.html");
		else if(fs.existsSync(path.resolve(dir,"app-wxss.js")))
			frameFile=path.resolve(dir,"app-wxss.js");
		else if(fs.existsSync(path.resolve(dir,"page-frame.js")))
			frameFile=path.resolve(dir,"page-frame.js");
		else throw Error("page-frame-like file is not found in the package by auto.");
		wu.get(frameFile,code=>{
			code=code.slice(code.indexOf('var setCssToHead = function(file, _xcInvalid'));
			code=code.slice(code.indexOf('\nvar _C= ')+1);
			let oriCode=code;
			code=code.slice(0,code.indexOf('\n'));
			let vm=new VM({sandbox:{}});
			pureData=vm.run(code+"\n_C");
			let mainCode=oriCode.slice(oriCode.indexOf("setCssToHead"),oriCode.lastIndexOf(";var __pageFrameEndTime__"));
			console.log("Guess wxss(first turn)...");
			preRun(dir,frameFile,mainCode,files,()=>{
				frameName=frameFile;
				onlyTest=true;
				runOnce();
				onlyTest=false;
				console.log("Import count info: %j",importCnt);
				for(let id in pureData)if(!actualPure[id]){
					if(!importCnt[id])importCnt[id]=0;
					if(importCnt[id]<=1){
						console.log("Cannot find pure import for _C["+id+"] which is only imported "+importCnt[id]+" times. Let importing become copying.");
					}else{
						let newFile=path.resolve(dir,"__wuBaseWxss__/"+id+".wxss");
						console.log("Cannot find pure import for _C["+id+"], force to save it in ("+newFile+").");
						id=Number.parseInt(id);
						actualPure[id]=newFile;
						cssRebuild.call({cssFile:newFile},id)();
					}
				}
				console.log("Guess wxss(first turn) done.\nGenerate wxss(second turn)...");
				runOnce()
				console.log("Generate wxss(second turn) done.\nSave wxss...");
				for(let name in result)wu.save(wu.changeExt(name,".wxss"),transformCss(result[name]));
				let delFiles={};
				for(let name of files)delFiles[name]=8;
				delFiles[frameFile]=4;
				cb(delFiles);
			});
		});
	});
}
module.exports={doWxss:doWxss};
if(require.main===module){
    wu.commandExecute(doWxss,"Restore wxss files.\n\n<dirs...>\n\n<dirs...> restore wxss file from a unpacked directory(Have page-frame.html (or app-wxss.js) and other html file).");
}

 

 

0
0
分享到:
评论

相关推荐

    微信小程序反编译脚本!

    总的来说,微信小程序反编译虽然能提供一定程度的学习和研究机会,但也需要我们意识到潜在的风险和责任。合理利用这些工具,可以加深对微信小程序开发的理解,提升自己的技术水平,但务必遵守相关规定,尊重他人的...

    微信小程序反编译工具,操作简单

    微信小程序反编译工具,操作简单。电脑打开微信小程序操作一遍,然后在Applet中找到__APP__.wxapkg。把附件放入__APP__.wxapkg一个文件夹内,在此文件夹地址栏中运行cmd,输入unveilr.exe __APP__.wxapkg即可完成反...

    微信小程序反编译工具_wx_微信小程序_

    总结起来,微信小程序反编译工具主要用于开发者和研究者的分析和学习,通过抓包断点调试可以深入了解小程序的运行机制,而像wxappUnpacker这样的工具则提供了解压和查看小程序内部结构的可能。在使用这些工具时,...

    微信小程序反编译(最新版).7z

    "微信小程序反编译(最新版).7z"这个压缩包文件提供了一个反编译工具,它经过更新并经过测试,可以有效地处理微信小程序的编译文件,帮助用户获取源码。 这个工具包的主要功能包括: 1. **分包修复**:微信小程序...

    不需要安装依赖包可直接运行的微信小程序反编译完整代码

    在本文中,我们将深入探讨如何不需要额外安装依赖包就能直接运行的微信小程序反编译完整代码,以及这一过程涉及的关键技术点。 首先,我们要理解微信小程序的编译与反编译过程。微信小程序的源代码是用WXML(Weixin...

    微信小程序反编译工具wxappUnpacker

    总的来说,`wxappUnpacker` 是一款强大的微信小程序反编译工具,它为开发者提供了窥探小程序内部结构的窗口,同时也带来了一系列的技术挑战和伦理考量。正确合理地使用此类工具,可以极大地促进个人技能的提升和行业...

    微信小程序反编译获取代码工具

    标题中的“微信小程序反编译获取代码工具”是指一类专门用于解析和提取微信小程序编译后代码的软件工具。这些工具通常能够帮助开发者或者安全研究人员查看并理解已经编译过的微信小程序的源代码,尽管原始的源码可能...

    微信小程序反编译工具-mac.zip

    仅限于学习交流使用

    微信小程序反编译工具

    2.观看 wxapkg\小程序反编译全套\视频教程-解包流程 教学视屏 3.是否有分包处理方式不同,经过测试,目前还没有不能反编译的小程序 4.即使小程序有N个分包也能反编译,工具包里自带典型小程序 5.获取 wxapkg 包请...

    微信小程序反编译教程获取源码工具.exe

    反编译微信小程序,代码已截图展示,请参考博客文章

    基于node的微信小程序反编译工具+项目说明.zip

    【资源说明】 ...基于node的微信小程序反编译工具+项目说明.zip基于node的微信小程序反编译工具+项目说明.zip基于node的微信小程序反编译工具+项目说明.zip基于node的微信小程序反编译工具+项目说明.zip

    微信小程序反编译.zip

    而“微信小程序反编译”涉及的技术点主要包括对微信小程序的代码解析、逆向工程以及可能的安全问题。 1. 微信小程序的结构: 微信小程序的源代码由JSON配置文件、WXML(结构文件)、WXSS(样式文件)和JS(逻辑...

    微信小程序自动反编译,小程序安全评估工具,发现小程序安全问题,自动解密,

    微信小程序自动反编译,小程序安全评估工具,发现小程序安全问题,自动解密,解包,可以恢复项目目录,支持Hook,小程序修改,KillWxapkg

    获取微信小程序源代码反编译微信小程序说明(这里是电脑微信访问微信小程序记录)

    2 反编译的脚本 3 小程序包解密工具 获取小程序包: C:\Users\yourname\Documents\WeChat Files\Applet\018fd*****\****.wxapkg 请看wechatMiniAppReverse-main里面说明,装好node.js环境后,直接按目录里面1和2...

    node微信小程序反编译工具

    "Node微信小程序反编译工具"就是针对这种情况应运而生的工具,它可以帮助开发者解析并理解微信小程序的内部结构,以便于进行二次开发、调试或者学习。 首先,我们要明白微信小程序的编译过程。微信小程序的源代码是...

    微信小程序反编译脚本wxappUnpacker

    而“微信小程序反编译脚本wxappUnpacker”则是针对这种平台的工具,它能够帮助开发者或者逆向工程师分析和理解微信小程序的内部结构,以进行调试、学习或者研究。 首先,我们需要理解微信小程序的编译过程。在开发...

    微信小程序反编译工具,微信小程序查看源码

    微信小程序反编译工具,微信小程序查看源码,使用反编译脚本wxappUnpacker,小程序解密工具,node.js等工具实现微信小程序反编译获取源代码功能,资源里有工具和反编译教程的文档,可以根据操作步骤一一实现,内容...

    一键反编译微信小程序获取源码,并转换为uniapp或taro跨端项目

    一键反编译微信小程序获取源码,并转换为uniapp或taro跨端项目

    微信小程序反编译wxappUnpacker包

    本文将深入探讨使用wxappUnpacker工具进行微信小程序反编译的过程及其相关知识点。 首先,微信小程序的源代码是经过编译和加密的,这主要是为了保护开发者的知识产权和防止恶意篡改。然而,对于开发者而言,有时...

Global site tag (gtag.js) - Google Analytics