php微信小程序解包过程实例详解


Posted in PHP onMarch 31, 2021

这个解包只能看个大概

1.找到小程序压缩包

1.1、手机root或安装模拟器(我用的是夜神)

1.2、在模拟器上安装微信(用android5系统的模拟器,低版本小程序容易打不开)

1.3、打开登陆微信后,打开小程序

1.4、打开模拟器自带的文件管理器来到目录:/data/data/com.tencent.mm/MicroMsg/{{一串32位的16进制字符串文件夹}}/appbrand/pkg/

1.5、里面有很多wxapkg文件,找到最新修改日期的文件比如 -357038350_91.wxapkg,前面打勾选中

1.6、文件管理器回到/mnt/shared/Other目录,粘贴即可,打开安卓模拟器上我的电脑 =〉打开电脑文件夹找到粘贴的文件-357038350_91.wxapkg 夜神教程链接:跳转查看

2.对压缩包解包

详细参考:https://codechina.csdn.net/mirrors/leo9960/wechat-app-unpack?utm_source=csdn_github_accelerator

我用的php类:

使用方法:cmd =>cd php文件目录 =〉php wx_unpak.php 357038350_91.wxapkg

我主要是想用其中的一些图片,很多图片都被base64了放到js(app-service.js)和样式(app-wxss.js)文件中了;需要我们匹配组装一下

<?php
$str = file_get_contents('_-357038350_97.wxapkg.unpacked/app-service.js');
$preg = '/(data:image.*?)\"/';
$len = strlen('data:image/png;base64,');
if(preg_match_all($preg, $str, $arr)){
  foreach($arr[1] as $k => $img){
    file_put_contents('./images/'.$k.'.png',base64_decode(substr($img,$len)));
    //echo substr($img,$len);exit;
  }
} else {
  echo 'no';
}

$str = file_get_contents('_-357038350_97.wxapkg.unpacked/app-wxss.js');
$preg = '/\((data:image.*?)\)/';
$len = strlen('data:image/png;base64,');
if(preg_match_all($preg, $str, $arr)){
  foreach($arr[1] as $k => $img){
    file_put_contents('./images/a2_'.$k.'.png',base64_decode(substr($img,$len)));
    //echo substr($img,$len);exit;
  }
} else {
  echo 'no';
}

wx_unpak.php

<?php
/**
源文件目录
  /data/data/com.tencent.mm/MicroMsg/{{一串32位的16进制字符串文件夹}}/appbrand/pkg/
  /data/data/com.eg.android.AlipayGphone, 在files/nebulaInstallApps/目录下存储了所有加载过的小程序
 * [php] /path/to/unpack-wxapkg.php <xxx.wxapkg>
 * php unpak.php _1123949441_351.wxapkg
 */

function unpack_wxapkg($file, $targetDir)
{
  if (!is_dir($targetDir)){
    mkdir($targetDir);
  }

  echo "Reading file.\n";
  $file = file_get_contents($file);
  $ptr = 18;

  $headerStruct = new StructDef([
    'mask1' => 'ushort',
    'info1' => 'ulong',
    'indexInfoLength' => 'ulong',
    'bodyInfoLength' => 'ushort',
    'mask2' => 'ushort',
    'fileCount' => 'ulong',
  ]);

  echo "Parsing file header...\n";

  $header = $headerStruct->unpack($file);
//  print_r(['header' => $header]);

  $unpackULong = function () use (&$file, &$ptr) {
    $ret = unpack_ulong(substr($file, $ptr, 4));
    $ptr += 4;
    return $ret;
  };

  $unpackUShort = function () use (&$file, &$ptr) {
    $ret = unpack_ushort(substr($file, $ptr, 2));
    $ptr += 2;
    return $ret;
  };


  $unpackStr = function ($len) use (&$file, &$ptr) {
    $ret = substr($file, $ptr, $len);
    $ptr += $len;
    return $ret;
  };


  $fileCount = $header['fileCount'];

  echo "Got $fileCount files.\n";

  $unpackedFiles = [];

  for ($i = 0; $i < $fileCount; $i++) {
    $nameLength = $unpackULong();
    $f = [
      'nameLength' => $nameLength,
      'name' => $unpackStr($nameLength),
      'offset' => $unpackULong(),
      'size' => $unpackULong(),
    ];

    echo "Unpacking file {$f['name']} ({$f['size']}bytes)...\n";

    $f['content'] = substr($file, $f['offset'], $f['size']);
    $unpackedFiles[] = $f;

    $destFile = $targetDir . $f['name'];
    $destDir = dirname($destFile);
    if (!is_dir($destDir)){
      mkdir($destDir, 0777, true);
    }

    file_put_contents($targetDir . $f['name'], $f['content']);
  }


//  print_r(['unpackedFiles' => $unpackedFiles]);



  echo "All done.\n";
}

function unpack_ulong($str)
{
  $x = unpack('N', $str);
  return $x[1];
}

function unpack_ushort($str)
{
  $x = unpack('n', $str);
  return $x[1];
}

class StructDef
{
  protected $def;
  protected $unpackFormat;

  public function __construct($def)
  {
    $this->def = $def;
    $this->unpackFormat = self::convertStructDefToUnpackFormat($def);
  }

  public function unpack($data)
  {
    return unpack($this->unpackFormat, $data);
  }

  protected static function convertStructDefToUnpackFormat($def)
  {
    $defTypeToUnpackType = [
      'byte' => 'C',
      'uchar' => 'C',
      'u8' => 'C',
      'ushort' => 'n',
      'u16' => 'n',
      'ulong' => 'N',
      'u32' => 'N',
    ];

    $ret = [];
    foreach ($def as $key => $type) {
      $ret[] = $defTypeToUnpackType[$type] . $key;
    }

    return implode('/', $ret);
  }
}

$packageFile = $argv[1];

//支持目录下文件批量解压
 if (is_dir($packageFile)){
  $handle = opendir($packageFile);
  if($handle){
    while(($fl = readdir($handle)) !== false){
      $temp = $packageFile.DIRECTORY_SEPARATOR.$fl;
      //如果不加 $fl!='.' && $fl != '..' 则会造成把$dir的父级目录也读取出来
      if(is_file($temp)){
        if($fl!='.' && $fl != '..'){
          $targetDir = $temp . '.unpacked';
          unpack_wxapkg($temp, $targetDir);
        }
      }
    }
  } 
}else if (is_file($packageFile)){
  $targetDir = $packageFile . '.unpacked';
  unpack_wxapkg($packageFile, $targetDir);
}else{
  echo <<<HELP
Usage:
  [php] {$argv[0]} <xxx.wxapkg>
  - Unpack the `xxx.wxapkg` to `xxx.wxapkg.unpacked` directory.
HELP;

  exit(1);
}

exit(0);

到此这篇关于php微信小程序解包的文章就介绍到这了,更多相关php微信小程序解包内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
PHP新手上路(六)
Oct 09 PHP
MySql 按时间段查询数据方法(实例说明)
Nov 02 PHP
解析thinkphp的左右值无限分类
Jun 20 PHP
php中单个数据库字段多列显示(单字段分页、横向输出)
Jul 28 PHP
php采集自中央气象台范围覆盖全国的天气预报代码实例
Jan 04 PHP
ThinkPHP控制器详解
Jul 27 PHP
Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法
Mar 29 PHP
php简单压缩css样式示例
Sep 22 PHP
zend框架实现支持sql server的操作方法
Dec 08 PHP
PHP编译configure时常见错误的总结
Aug 17 PHP
PHP调用接口用post方法传送json数据的实例
May 31 PHP
php获取小程序码的实现代码(B类接口)
Jun 13 PHP
ThinkPHP5和ThinkPHP6的区别
Mar 31 #PHP
PHP基本语法
PHP中->和=>的意思
Mar 31 #PHP
Mac M1安装mnmp (Mac+Nginx+MySQL+PHP) 开发环境
Laravel中Kafka的使用详解
Mar 24 #PHP
thinkphp5 redis缓存新增方法实例讲解
php优化查询foreach代码实例讲解
Mar 24 #PHP
You might like
精致的人儿就要挑杯子喝咖啡
2021/03/03 冲泡冲煮
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
php操作xml入门之cdata区段
2015/01/23 PHP
谈谈PHP连接Access数据库的注意事项
2016/08/12 PHP
详解php中serialize()和unserialize()函数
2017/07/08 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
jQuery 源码分析笔记(3) Deferred机制
2011/06/19 Javascript
使用jsonp完美解决跨域问题
2014/11/27 Javascript
浅谈轻量级js模板引擎simplite
2015/02/13 Javascript
Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别
2015/12/30 Javascript
JavaScript比较当前时间是否在指定时间段内的方法
2016/08/02 Javascript
jquery 属性选择器(匹配具有指定属性的元素)
2016/09/06 Javascript
jQuery实现遮罩层登录对话框
2016/12/29 Javascript
javascript实现简单的可随机变色网页计算器示例
2016/12/30 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
jQuery length 和 size()区别总结
2018/04/26 jQuery
Element Dropdown下拉菜单的使用方法
2020/07/26 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
[56:17]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第三场 8.22
2019/09/05 DOTA
Python 时间处理datetime实例
2008/09/06 Python
浅谈Python中的数据类型
2015/05/05 Python
python编写简单爬虫资料汇总
2016/03/22 Python
python实现将读入的多维list转为一维list的方法
2018/06/28 Python
python实现zabbix发送短信脚本
2018/09/17 Python
利用python实现简易版的贪吃蛇游戏(面向python小白)
2018/12/30 Python
python 杀死自身进程的实现方法
2019/07/01 Python
Django+python服务器部署与环境部署教程详解
2020/03/30 Python
python中rc1什么意思
2020/06/19 Python
HTML5重塑Web世界它将如何改变互联网
2012/12/17 HTML / CSS
html5自定义video标签的海报与播放按钮功能
2019/12/04 HTML / CSS
英国领先的在线高尔夫设备零售商:Golfgeardirect
2020/12/11 全球购物
医药类个人求职的自我评价
2014/02/12 职场文书
营销部内勤岗位职责
2014/04/30 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
培训通知
2015/04/17 职场文书
巾帼建功标兵先进事迹材料
2016/02/29 职场文书