mirror of
https://github.com/wux1an/wxapkg.git
synced 2025-12-24 12:47:52 +08:00
feat: implemented JavaScript code beautification for HTML files
This commit is contained in:
44
README.md
44
README.md
@@ -1,46 +1,46 @@
|
||||
# wxapkg
|
||||
|
||||
> **Disclaimer**: This tool is only for the purpose of learning and studying the design ideas and principles contained within the software. Users shall assume all legal and related liabilities resulting from the use of this tool! The author shall not be held liable for any legal consequences!
|
||||
>
|
||||
> **免责声明**:此工具仅限于学习和研究软件内含的设计思想和原理,用户承担因使用此工具而导致的所有法律和相关责任!作者不承担任何法律责任!
|
||||
|
||||
**Usage:**
|
||||
**🎨 用法**
|
||||
|
||||

|
||||
|
||||
- scan mini program
|
||||
- 微信小程序扫描 + 解密 + 解包
|
||||
> 不指定参数的话,会在默认安装目录扫描小程序 wxid,然后获取小程序信息(需要网络)
|
||||
|
||||
键盘上下键选中想要处理的小程序,然后按回车
|
||||
|
||||
```bash
|
||||
# wxapkg.exe scan --help
|
||||
wxapkg.exe scan
|
||||
```
|
||||
|
||||
- unpack mini program
|
||||
|
||||
```bash
|
||||
# wxapkg.exe unpack --help
|
||||
- 单独解密 + 解包指定的微信小程序
|
||||
> 指定小程序路径,自动获取 wxid 然后解密解包
|
||||
```bash
|
||||
wxapkg.exe unpack -o out-dir -r "%USERPROFILE%\Documents\WeChat Files\Applet\wx00000000000000"
|
||||
```
|
||||
|
||||
**Install:**
|
||||
**⚒️ 安装**
|
||||
|
||||
Download the latest [release](https://github.com/wux1an/wxapkg/releases/latest) or build with `go install` by yourself
|
||||
下载最新的发布版本 [release](https://github.com/wux1an/wxapkg/releases/latest),或者用下面的命令自己编译
|
||||
|
||||
```
|
||||
go install github.com/wux1an/wxapkg@latest
|
||||
```
|
||||
|
||||
**Todo:**
|
||||
**📝 其他功能**
|
||||
|
||||
- [x] scan more information (need networking)
|
||||
- [x] json beautify
|
||||
- [x] javascript beautify
|
||||
- [x] html beautify
|
||||
- [ ] auto export uri in files
|
||||
- [x] 获取小程序信息(需要网络连接)
|
||||
- [x] 代码美化,默认开启,可以使用 `--disable-beautify` 参数禁用
|
||||
- [x] 美化 `JSON` 文件
|
||||
- [x] 美化 `JavaScript` 文件(会有点慢)
|
||||
- [x] 美化 `Html` 文件,包括其中的 `<script>` 标签(会有点慢)
|
||||
- [ ] 自动导出文件中的敏感 url 和 key 等信息
|
||||
|
||||
**References:**
|
||||
**🔗 参考**
|
||||
|
||||
- decrypt: https://github.com/BlackTrace/pc_wxapkg_decrypt
|
||||
- unpack: [https://gist.github.com/Integ/bcac5c21de5ea3...](https://gist.github.com/Integ/bcac5c21de5ea35b63b3db2c725f07ad)
|
||||
- introduce: [https://misakikata.github.io/2021/03/%E5%BE%...](https://misakikata.github.io/2021/03/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%A7%A3%E5%8C%85/)
|
||||
- terminal ui: https://github.com/charmbracelet/bubbletea
|
||||
- 小程序解密: https://github.com/BlackTrace/pc_wxapkg_decrypt
|
||||
- 小程序解包: [https://gist.github.com/Integ/bcac5c21de5ea3...](https://gist.github.com/Integ/bcac5c21de5ea35b63b3db2c725f07ad)
|
||||
- 原理介绍: [https://misakikata.github.io/2021/03/%E5%BE%...](https://misakikata.github.io/2021/03/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%A7%A3%E5%8C%85/)
|
||||
- 终端 ui 库: https://github.com/charmbracelet/bubbletea
|
||||
@@ -12,8 +12,9 @@ import (
|
||||
)
|
||||
|
||||
var scanCmd = &cobra.Command{
|
||||
Use: "scan",
|
||||
Short: "Scan the wechat mini program",
|
||||
Use: "scan",
|
||||
Short: "Scan the wechat mini program",
|
||||
Example: " " + programName + " scan -r \"D:\\WeChat Files\\Applet\\wx12345678901234\"",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
root, err := cmd.Flags().GetString("root")
|
||||
if err != nil {
|
||||
|
||||
@@ -8,12 +8,9 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ditashi/jsbeautifier-go/jsbeautifier"
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tidwall/pretty"
|
||||
"github.com/wux1an/wxapkg/util"
|
||||
"github.com/yosssi/gohtml"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"io"
|
||||
"log"
|
||||
@@ -28,7 +25,7 @@ var programName = filepath.Base(os.Args[0])
|
||||
var unpackCmd = &cobra.Command{
|
||||
Use: "unpack",
|
||||
Short: "Decrypt wechat mini program",
|
||||
Example: " " + programName + "unpack -o unpack -r \"%USERPROFILE%\\Documents\\WeChat Files\\Applet\\wx00000000000000\"",
|
||||
Example: " " + programName + "unpack -o unpack -r \"D:\\WeChat Files\\Applet\\wx12345678901234\"",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
root, _ := cmd.Flags().GetString("root")
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
@@ -184,6 +181,11 @@ func unpack(decryptedData []byte, unpackRoot string, thread int, beautify bool)
|
||||
|
||||
var exts = make(map[string]int)
|
||||
var extsLocker = sync.Mutex{}
|
||||
var beautify = map[string]func([]byte) []byte{
|
||||
".json": util.PrettyJson,
|
||||
".html": util.PrettyHtml,
|
||||
".js": util.PrettyJavaScript,
|
||||
}
|
||||
|
||||
func fileBeautify(name string, data []byte) (result []byte) {
|
||||
defer func() {
|
||||
@@ -192,28 +194,18 @@ func fileBeautify(name string, data []byte) (result []byte) {
|
||||
}
|
||||
}()
|
||||
|
||||
result = data
|
||||
var ext = filepath.Ext(name)
|
||||
|
||||
extsLocker.Lock()
|
||||
exts[ext] = exts[ext] + 1
|
||||
extsLocker.Unlock()
|
||||
|
||||
switch ext {
|
||||
case ".json":
|
||||
result = pretty.Pretty(data)
|
||||
case ".html": // todo beautify js code in html
|
||||
result = gohtml.FormatBytes(bytes.TrimSpace(data)) // remove leading whitespace
|
||||
case ".js":
|
||||
var code = string(bytes.TrimSpace(data)) // remove leading whitespace
|
||||
options := jsbeautifier.DefaultOptions()
|
||||
beautify, err := jsbeautifier.Beautify(&code, options)
|
||||
if err == nil {
|
||||
result = []byte(beautify)
|
||||
}
|
||||
b, ok := beautify[ext]
|
||||
if !ok {
|
||||
return data
|
||||
}
|
||||
|
||||
return result
|
||||
return b(data)
|
||||
}
|
||||
|
||||
func parseWxid(root string) (string, error) {
|
||||
|
||||
57
util/beautify.go
Normal file
57
util/beautify.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/ditashi/jsbeautifier-go/jsbeautifier"
|
||||
"github.com/tidwall/pretty"
|
||||
"github.com/yosssi/gohtml"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var regScriptInHtml = regexp.MustCompile(`(?s) *<script.*?>(.*?)</script>`)
|
||||
var jsOptions = jsbeautifier.DefaultOptions()
|
||||
|
||||
func PrettyJson(data []byte) []byte {
|
||||
return pretty.Pretty(data)
|
||||
}
|
||||
|
||||
func PrettyHtml(data []byte) []byte {
|
||||
data = gohtml.FormatBytes(bytes.TrimSpace(data)) // use `TrimSpace` to remove leading whitespace
|
||||
data = regScriptInHtml.ReplaceAllFunc(data, func(script []byte) []byte {
|
||||
var space = countLeadingSpaces(script)
|
||||
|
||||
var jsCode = regScriptInHtml.FindSubmatch(script)[1]
|
||||
var jsStr = strings.Repeat(" ", space+2) + string(bytes.TrimSpace(jsCode))
|
||||
|
||||
beautify, err := jsbeautifier.Beautify(&jsStr, jsOptions)
|
||||
if err == nil {
|
||||
return bytes.Replace(script, jsCode, []byte("\n"+beautify+"\n"+strings.Repeat(" ", space)), 1)
|
||||
}
|
||||
return script
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
func PrettyJavaScript(data []byte) []byte {
|
||||
var code = string(bytes.TrimSpace(data)) // use `TrimSpace` to remove leading whitespace
|
||||
beautify, err := jsbeautifier.Beautify(&code, jsOptions)
|
||||
if err != nil {
|
||||
return data
|
||||
}
|
||||
|
||||
return []byte(beautify)
|
||||
}
|
||||
|
||||
func countLeadingSpaces(data []byte) int {
|
||||
var result = 0
|
||||
for _, c := range data {
|
||||
if c == ' ' {
|
||||
result++
|
||||
} else {
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user