小程序前端代码/素材提取

小程序前端代码提取

准备

  1. 提取Android端小程序(微信、支付宝):
    a. 一部已经root的Android手机, 打开开发者模式USB调试
    b. 安装adb (官方下载链接: https://developer.android.com/studio/releases/platform-tools)
    c. python运行环境 (本人使用WSL)
    d. 安装微信或支付宝
  2. 提取PC端(微信):
    a. python、python3(含pip3)运行环境 (本人使用WSL)
    b. 安装PC端微信

微信小程序 (Android端)

  1. 将Android手机通过USB连接PC, 通过adb.exe devices能看到该设备
  2. 执行adb.exe shell
  3. 执行su切换到root模式下, 如果是第一次操作, 可能需要Android端 授权获取root"$“变为”#"即切换到root用户成功
  4. 进入小程序缓存路径, 根据时间找到你需要的小程序缓存(wxapkg)
    路径: /data/data/com.tencent.mm/MicroMsg/<32位id>/appbrand/pkg/
  5. 把文件cp到非root权限可以访问的路径下, 例如: /storage/emulated/0/Android/
  6. 退出Android root和shell, 需要两次exit, 通过adb.exe pull拉取到本地
  7. 用以下代码进行解包
#!/usr/bin/env python2

# usage python2 unwxapkg.py filename
 
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'
  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 = ' + str(firstMark)
 
  info1 = struct.unpack('>L', f.read(4))[0]
  print 'info1 = ' + str(info1)
 
  indexInfoLength = struct.unpack('>L', f.read(4))[0]
  print 'indexInfoLength = ' + str(indexInfoLength)
 
  bodyInfoLength = struct.unpack('>L', f.read(4))[0]
  print 'bodyInfoLength = ' + str(bodyInfoLength)
 
  lastMark = struct.unpack('B', f.read(1))[0]
  print 'last header mark = ' + str(lastMark)
 
  if firstMark != 0xBE or lastMark != 0xED:
    print 'its not a wxapkg file!!!!!'
    exit()
 
  fileCount = struct.unpack('>L', f.read(4))[0]
  print 'fileCount = ' + str(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 = ' + data.name + ' at Offset = ' + str(data.offset)
 
    fileList.append(data)
 
  #save files
   
  for d in fileList:
    d.name = '/' + name + d.name
    path = root + os.path.dirname(d.name)
 
    if not os.path.exists(path):
      os.makedirs(path)
 
    w = open(root + d.name, 'w')
    f.seek(d.offset)
    w.write(f.read(d.size))
    w.close()
 
    print 'writeFile = ' + root + d.name
 
  f.close()

支付宝小程序 (Android端)

支付宝的小程序路径为: /data/data/com.eg.android.AlipayGphone/files/nebulaInstallApps/<支付宝appid>/<32位id>/xxx.tar
直接tar -xf <file>解压即可

微信小程序 (PC端)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import argparse
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA1
from Crypto.Cipher import AES

# 微信小程序包 自定义标识
WXAPKG_FLAG = 'V1MMWX'
WXAPKG_FLAG_LEN = len(WXAPKG_FLAG)

def main():

    parser = argparse.ArgumentParser(description='PC微信小程序wxapkg包解密工具')
    parser.add_argument('--wxid', metavar='微信小程序ID', required=True)
    parser.add_argument('--iv', metavar='iv', required=False, default='the iv: 16 bytes')
    parser.add_argument('--salt', metavar='salt', required=False, default='saltiest')
    parser.add_argument('-f', '--file', metavar='加密的小程序包文件路径', required=True)
    parser.add_argument('-o', '--output', metavar='解密后的小程序包文件路径', required=True)

    args = parser.parse_args()

    key = PBKDF2(args.wxid.encode('utf-8'), args.salt.encode('utf-8'), 32, count=1000, hmac_hash_module=SHA1)

    # 读取加密的内容
    if not os.path.exists(args.file):
        raise Exception('文件不存在')

    with open(args.file, mode='rb') as f:
        dataByte = f.read()

    if dataByte[0:WXAPKG_FLAG_LEN].decode() != WXAPKG_FLAG:
        raise Exception('该文件无需解密, 或者不是微信小程序wxapkg加密包')

    # 初始化密钥
    cipher = AES.new(key, AES.MODE_CBC, args.iv.encode('utf-8'))
    
    # 解密头部1024个字节
    originData = cipher.decrypt(dataByte[WXAPKG_FLAG_LEN: 1024 + WXAPKG_FLAG_LEN])

    # 初始化xor密钥, 解密剩余字节
    xorKey = 0x66
    if len(args.wxid) >= 2:
        xorKey = ord(args.wxid[len(args.wxid) - 2])

    afData = dataByte[1024 + WXAPKG_FLAG_LEN:]

    out = bytearray()
    for i in range(len(afData)):
        out.append(afData[i] ^ xorKey)

    originData = originData[0:1023] + out

    # 保存解密后的数据
    with open(args.output, mode='wb') as f:
        f.write(originData)

    print('解密成功', args.output)

if __name__ == "__main__":
    main()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值