微信小程序反编译总结

微信小程序反编译总结参考博客 https www cnblogs com yangda p 12941806 htmlhttps blog csdn net larasse article details 106264834htt blog csdn net 41297837 article details 103962564 操作步骤下载 node js 下载 wxappUnpacke 链接 https pan baidu com s 1l36TaGk2VgY

参考博客

操作步骤

  1. 下载node.js
  2. 下载 wxappUnpacker https://github.com/ROBOT008/wxappUnpacker 或者自行在github上搜索wxappUnpacker选择下载 或者百度云链接 提取码:hao6
  3. 在cmd中切换到wxappUnpacker的目录下,输入以下命令安装依赖(百度云下载可以不执行这一步),会创建一个 node_modules 的文件夹:
npm install esprima --save npm install css-tree --save npm install cssbeautify --save npm install vm2 --save npm install uglify-es --save npm install js-beautify --save npm install escodegen --save npm install cheerio --save 
  1. 下载安卓模拟器,登录微信并打开微信小程序
  2. 找到文件路径 /data/data/com.tencent.mm/MicroMsg/{User}/appbrand/pkg 其中{User} 为当前用户的用户名,类似于 2bcb65
  3. 文件后缀为.wxapkg就是微信小程序的’包’,发送这样的文件到电脑,如果发送不了就压缩一下。
  4. 解析主包命令执行命令 node wuWxapkg.js testpkg/master-xxx.wxapkg(主包)
    解析子包命令执行命令 node wuWxapkg.js testpkg/sub-1-xxx.wxapkg -s=../master-xxx
    注:-s参数可为相对路径或绝对路径相对路径的起点不是当前目录 而是子包解包后的目录,如果相对路径的文件夹不存在,就无法产生wxml和js文件到主包的目录




├── testpkg │ ├── sub-1-xxx.wxapkg #被解析子包 │ └── sub-1-xxx #相对路径的起点 │ ├── app-service.js │ ├── master-xxx.wxapkg #被解析主包 │ └── master-xxx # ../master-xxx 就是这个目录 │ ├── app.json 

在这里插入图片描述

一些说明

  1. 在找寻wxapkg包的时候,有一个大约10M的wxapkg的包反编译出来没有pages、lib等文件夹,并且这个包反编译会报This package is unrecognizable或者 not a directory, scandir 'D:\223\__432\WAAutoService.js'错误,这个包有可能是微信小程序运行的一些核心包
  2. 分包和主包的文件名下划线后面的数字都是一样,主包的大小要比分包大
    在这里插入图片描述

遇到的问题

编译报magic number is not correct

编译出来没有wxss文件 vd_version_info is not define

在这里插入图片描述【解决】只需要进wuWxss.js文件里修改一下方法就行,找到function runOnce() 方法,修改成以下代码:

function runOnce() { for (let name in runList) { 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]); } } 

修改wxWxss文件的runVm函数 ,改为

function runVM(name, code) { let wxAppCode = {}; let handle = {cssFile: name}; let gg = new GwxCfg(); let tsandbox = { $gwx: GwxCfg.prototype["$gwx"], __mainPageFrameReady__: GwxCfg.prototype["$gwx"], //解决 $gwx is not defined __vd_version_info__: GwxCfg.prototype["$gwx"], //解决 __vd_version_info__ is not defined __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](); } } } 

【未解决】反编译wxss文件时报错 SyntaxError: Unexpected end of input在这里插入图片描述

.wxapkg不是微信小程序的包

【报错】This package is unrecognizable 或者 not a directory, scandir 'D:\223\__432\WAAutoService.js'
【说明】当前反编译的包不是工程文件夹,里面都是微信的基础包,无需还原。
在这里插入图片描述在这里插入图片描述




【未解决】Illegal return statement

请选择app.json/project.config.json 的目录在这里插入图片描述

【解决】将项目下的 app-config.json 改名为 app.json

成功截图

在这里插入图片描述

手动获取相关的js代码

- `node wuConfig.js 
    ` 将 app-config.json 中的内容拆分到各个文件对应的 .json 和 app.json , 并通过搜索 app-config.json 所在文件夹下的所有文件尝试将 iconData 还原为 iconPath 。 - `node wuJs.js 
    ` 将 app-service.js (或小游戏中的 game.js ) 拆分成一系列原先独立的 javascript 文件,并使用 Uglify-ES 美化,从而尽可能还原编译前的情况。如果是子包的app-service.js,则需要另外处理(和主包的app-service.js保持结构一致定义了__wxAppCode__,并没有`$gwx('init', global);`- `node wuWxml.js [-m] 
    ` 将编译/混合到 page-frame.html ( 或 app-wxss.js 或 page-frame.js ) 中的 wxml 和 wxs 文件还原为独立的、未编译的文件。如果加上`-m`指令,就会阻止`block`块自动省略,可能帮助解决一些相关过程的 bug 。 - `node wuWxss.js 
    ` 通过获取文件夹{ 
   { 
   dirs}}下的 page-frame.html ( 或 app-wxss.js ) 和其他 html 文件的内容,还原出编译前 wxss 文件的内容。
- `node wuWxapkg.js [-o] [-d] [-s= 
    
]
`
将 wxapkg 文件解包,并将包中上述命令中所提的被编译/混合的文件自动地恢复原状。如果加上`-o`指令,表示仅解包,不做后续操作。如果加上`-d`指令,就会保留编译/混合后所生成的新文件,否则会自动删去这些文件。同时,前面命令中的指令也可直接加在这一命令上。而如果需要解压分包,请先解压主包,然后执行`node wuWxapkg.js [-d] -s=
`
,其中`Main Dir`为主包解压地址。除`-d``-s`外,这些指令两两共存的后果是未定义的(当然,是不会有危险的)。

微信小程序中js相关的代码都在 app-service.js中,在下面这段代码中,/bookingSuccess/bookingSuccess.js是js文件名【绿色的】,其中 define()括号中 "use strict";}); require("/bookingSuccess/bookingSuccess.js");之间的代码为 js文件的内容【红色的】。在 app-service.js文件中,你只需要关心类似于下面这段代码的其他代码,一般在最后。

__wxRoute = ‘/bookingSuccess/bookingSuccess’;__wxRouteBegin = true; wxAppCurrentFile = ‘/bookingSuccess/bookingSuccess.js’; define(“ / b o o k i n g S u c c e s s / b o o k i n g S u c c e s s . j s \color{#228B22}{/bookingSuccess/bookingSuccess.js} /bookingSuccess/bookingSuccess.js“, function(require, module, exports, window,document,frames,self,location,navigator,localStorage,history,Caches,screen,alert,confirm,prompt,XMLHttpRequest,WebSocket,Reporter,webkit,WeixinJSCore){ “use strict”; Page({data:{num:0,time:””,shopName:””},onLoad:function(n){this.setData({num:n.num,time:n.time,shopName:n.shopName}),wx.hideShareMenu()},myBooking:function(){wx.redirectTo({url:”/myYuyue/myYuyue”})},onReady:function(){},onShow:function(){},onHide:function(){},onUnload:function(){},onPullDownRefresh:function(){},onReachBottom:function(){},onShareAppMessage:function(){}});
});

require(“ / b o o k i n g S u c c e s s / b o o k i n g S u c c e s s . j s \color{#228B22}{/bookingSuccess/bookingSuccess.js} /bookingSuccess/bookingSuccess.js“);

手动获取wxss

参考 https://blog.csdn.net/weixin_/article/details/

wxss和wxml 的代码在 page-frame.js,例如想获取 /bookingSuccess/bookingSuccess.wxss的内容:

  • 将以下代码另存为html文件
  • 首先搜索 wxAppCode[’/bookingSuccess/bookingSuccess.wxss’] = setCssToHead,可以看到setCssToHead是一个函数
  • 将函数的第一个参数(数组)替换为以下html代码中setCssToHead的第一个参数
  • 最后运行html就可以得到wxss
<br><br>结果:<br><br> <script type="text/javascript"> var __wxAppCode__= __wxAppCode__ || { 
     }; var BASE_DEVICE_WIDTH = 750; var isIOS=navigator.userAgent.match("iPhone"); var deviceWidth = window.screen.width || 375; var deviceDPR = window.devicePixelRatio || 2; var checkDeviceWidth = window.__checkDeviceWidth__ || function() { 
      var newDeviceWidth = window.screen.width || 375 var newDeviceDPR = window.devicePixelRatio || 2 var newDeviceHeight = window.screen.height || 375 if (window.screen.orientation && /^landscape/.test(window.screen.orientation.type || '')) newDeviceWidth = newDeviceHeight if (newDeviceWidth !== deviceWidth || newDeviceDPR !== deviceDPR) { 
      deviceWidth = newDeviceWidth deviceDPR = newDeviceDPR } } checkDeviceWidth() var eps = 1e-4; var transformRPX = window.__transformRpx__ || function(number, newDeviceWidth) { 
      if ( number === 0 ) return 0; number = number / BASE_DEVICE_WIDTH * ( newDeviceWidth || deviceWidth ); number = Math.floor(number + eps); if (number === 0) { 
      if (deviceDPR === 1 || !isIOS) { 
      return 1; } else { 
      return 0.5; } } return number; } window.__rpxRecalculatingFuncs__ = window.__rpxRecalculatingFuncs__ || []; var __COMMON_STYLESHEETS__ = __COMMON_STYLESHEETS__||{ 
     } var setCssToHead = function(file, _xcInvalid, info) { 
      var Ca = { 
     }; var css_id; var info = info || { 
     }; var _C = __COMMON_STYLESHEETS__ function makeup(file, opt) { 
      var _n = typeof(file) === "string"; 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], opt.deviceWidth) + "px" + res; else if ( op == 1) res = opt.suffix + res; else if ( op == 2 ) res = makeup(content[1], opt) + res; } else res = content + res } return res; } var styleSheetManager = window.__styleSheetManager2__ var rewritor = function(suffix, opt, style){ 
      opt = opt || { 
     }; suffix = suffix || ""; opt.suffix = suffix; if ( opt.allowIllegalSelector != undefined && _xcInvalid != undefined ) { 
      if ( opt.allowIllegalSelector ) console.warn( "For developer:" + _xcInvalid ); else { 
      console.error( _xcInvalid ); } } Ca={ 
     }; css = makeup(file, opt); if (styleSheetManager) { 
      var key = (info.path || Math.random()) + ':' + suffix if (!style) { 
      styleSheetManager.addItem(key, info.path); window.__rpxRecalculatingFuncs__.push(function(size){ 
      opt.deviceWidth = size.width; rewritor(suffix, opt, true); }); } styleSheetManager.setCss(key, css); return; } if ( !style ) { 
      var head = document.head || document.getElementsByTagName('head')[0]; style = document.createElement('style'); style.type = 'text/css'; style.setAttribute( "wxss:path", info.path ); head.appendChild(style); window.__rpxRecalculatingFuncs__.push(function(size){ 
      opt.deviceWidth = size.width; rewritor(suffix, opt, style); }); } if (style.styleSheet) { 
      style.styleSheet.cssText = css; } else { 
      if ( style.childNodes.length == 0 ) style.appendChild(document.createTextNode(css)); else style.childNodes[0].nodeValue = css; } return css } return rewritor; } __wxAppCode__['pages'] = setCssToHead([".",[1],"container{background-color:#f7f7f7}\n.",[1],"gray{color:#dcdcdc!important}\n.",[1],"purple{color:#9f8bea!important}\n.",[1],"repair-state-panel,.",[1],"work-sheet-panel{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;margin-top:",[0,15],"}\n.",[1],"repair-state-title,.",[1],"work-sheet-title{color:#888;padding:",[0,5]," 0 ",[0,10]," ",[0,30],"}\n.",],undefined,{ 
     path:"./pages"}); document.write(__wxAppCode__['pages']("",{ 
     deviceWidth:375},document.body))  
     script> 

手动获取html信息

wxml 的代码也在 page-frame.js中,使用wxml.js只能得到wxml的整体架构,但是有很多值为Empty,这是因为解析__WXML_GLOBAL__.ops_cached.$gwx1_1数组失败,手动根据var m0=function(e,s,r,gg)函数的执行过程还原

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225080.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午10:10
下一篇 2026年3月17日 上午10:10


相关推荐

  • VS2013+uCOSII V2.91(uCOSII移植)

    VS2013+uCOSII V2.91(uCOSII移植)最近在看任哲的 嵌入式实时操作系统原理及应用 看了前面 8 章 虽然能看懂书上的代码 但因为没有动手写过 心里没有底 所以还是得动手写点代码测试 书上推荐的是 BorlandC3 1 但因为 Win10 不知道什么原因 安装不了 就放弃了 uCOSII 既然是用 C 写的可移植实时操作系统 能不能移植到 PC 上用 VS 编译呢 于是就在网上搜索了一下 果然有前辈开路 下面开始讲述怎么把 uCOSII 移植到 VS20

    2026年3月8日
    3
  • CentOS时间的查看与修改

    CentOS时间的查看与修改

    2022年2月21日
    67
  • gear s3刷android wear,【干货】三星Gear S3/Gear S3 classic 智能手表刷机教程「建议收藏」

    gear s3刷android wear,【干货】三星Gear S3/Gear S3 classic 智能手表刷机教程「建议收藏」今年九月在IFA电子展正式亮相的三星GearS3在本月即将在国内开卖,目前不少电商的商家已经为这款新品进行预热,从电商的价格来看这两款定位不同的智能手表(经典款/先锋款)的价格都为3599元,三星GearS3支持IP68级别防水,兼容Android4.4以及之后的安卓系统版本以及运存1.5GB以上的安卓智能手机。与苹果AppleWatch有诊断接口但是无法刷机不同,三星GearS系列手表支…

    2022年7月21日
    66
  • java StringBuffer和StringBuilder

    java StringBuffer和StringBuilder一、前言我们在实际的开发中,如果需要进行字符串的频繁拼接,会出现以下问题:java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存。造成内存空间的浪费。eg.Strings=”abc”;s+=”hello”;就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:”abc””hello””abchello”因此引出StringBuffer和StringBuilder可变字符串!二、如何优化StringBuffer和StringBuild

    2022年7月17日
    15
  • java getrealpath_从request获取各种路径总结 request.getRealPath(“url”)

    java getrealpath_从request获取各种路径总结 request.getRealPath(“url”)equest getRealPath 这个方法已经不推荐使用了 代替方法是 request getSession getServletCo getRealPath 从 Request 对象中可以获取各种路径信息 以下例子 假设请求的页面是 index jsp 项目是 WebDemo 则在 index jsp 中获取有关 request 对象的各种路径信息如下 Stringpath requ

    2026年3月17日
    1
  • 大数据,云计算和物联网三者的关系是什么_云计算侧重于数据分析

    大数据,云计算和物联网三者的关系是什么_云计算侧重于数据分析1、云计算为大数据提供了技术基础,大数据为云计算提供用武之地2、物联网是大数据的重要来源,大数据技术为物联网数据分析提供支持3、云计算为物联网提供了海量数据存储能力,物联网为云技术提供了广阔的应用空间…

    2022年10月6日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号