From 8afc5f904125e61cb4717485e5361107b431564a Mon Sep 17 00:00:00 2001 From: BlackTrace <8064316+BlackTrace@users.noreply.github.com> Date: Thu, 6 Aug 2020 16:30:24 +0800 Subject: [PATCH] init --- go.mod | 5 ++++ go.sum | 7 ++++++ main.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ readme.md | 34 +++++++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 readme.md diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d518c1b --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module pc_wxapkg_decrypt + +go 1.13 + +require golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1769e6b --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..ec6f9e1 --- /dev/null +++ b/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/sha1" + "flag" + "fmt" + "golang.org/x/crypto/pbkdf2" + "io/ioutil" + "log" +) + + +var ( + wxid string + iv string + salt string + wxapkgPath string + decWxapkgPath string +) + +func main(){ + flag.StringVar(&wxid,"wxid","","小程序的id") + flag.StringVar(&iv,"iv","the iv: 16 bytes","AES加密的IV,默认不需要设置,如果版本有变化,设置") + flag.StringVar(&salt,"salt","saltiest","pbkdf2用到的salt,默认不需要设置") + flag.StringVar(&wxapkgPath,"in","__APP__.wxapkg","需要解密的wxapkg的文件路径") + flag.StringVar(&decWxapkgPath,"out","dec.wxapkg","解密后的wxapkg的文件路径") + flag.Parse() + + if wxid == ""{ + fmt.Println("缺少wx小程序id(wxid),该id在pc存放wxapkg包的路径上寻找") + return + } + dec() +} + +func dec(){ + dataByte,err := ioutil.ReadFile(wxapkgPath) + if err != nil{ + log.Fatal(err) + } + + dk := pbkdf2.Key([]byte(wxid),[]byte(salt),1000,32,sha1.New) + block,_ := aes.NewCipher(dk) + blockMode := cipher.NewCBCDecrypter(block,[]byte(iv)) + originData := make([]byte,1024) + blockMode.CryptBlocks(originData,dataByte[6:1024+6]) + + afData := make([]byte,len(dataByte) - 1024 - 6) + var xorKey = byte(0x66) + if len(wxid) >= 2 { + xorKey = wxid[len(wxid) - 2] + } + for i,b := range dataByte[1024+6:]{ + afData[i] = b ^ xorKey + } + + originData = append(originData[:1023],afData...) + + err = ioutil.WriteFile(decWxapkgPath,originData,0666) + if err != nil{ + fmt.Println("写文件失败") + return + } + fmt.Println("解密成功") +} + + + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e2dc995 --- /dev/null +++ b/readme.md @@ -0,0 +1,34 @@ +# windows PC端wxapkg解密 + +## 说明 +由于不想安装安卓模拟器去提取wxapkg包,windows PC端的微信也支持小程序,但是PC端的wxapkg是被加密存储的。该项目是把wxapkg解密。目前微信PC版本为:**2.9.5.31**. +## 使用方法 +`pc_wxapkg_decrypt.exe -wxid 微信小程序id -in 要解密的wxapkg路径 -out 解密后的路径` + +``` +pc_wxapkg_decrypt.exe -h + +Usage of pc_wxapkg_decrypt.exe: + -in string + 需要解密的wxapkg的文件路径 (default "__APP__.wxapkg") + -iv string + AES加密的IV,默认不需要设置,如果版本有变化,设置 (default "the iv: 16 bytes") + -out string + 解密后的wxapkg的文件路径 (default "dec.wxapkg") + -salt string + pbkdf2用到的salt,默认不需要设置 (default "saltiest") + -wxid string + 小程序的id +``` + +wxapkg路径为:C:\Users\xxxx\Documents\WeChat Files\Applet\\**wx2xxx84w9w7a3xxxx**\\\__APP__.wxapkg,小程序id为:wx2xxx84w9w7a3xxxx + +解密完成后,就可以用wxappUnpacker(https://github.com/gudqs7/wxappUnpacker)解包了。 +## 原理 +PC端微信把wxapkg给加密,加密后的文件的起始为**V1MMWX**。 + +加密方法为: +1. 首先pbkdf2生成AES的key。利用微信小程序id字符串为pass,salt为**saltiest** 迭代次数为1000。调用pbkdf2生成一个32位的key +2. 首先取原始的wxapkg的包得前1023个字节通过AES通过1生成的key和iv(**the iv: 16 bytes**),进行加密 +3. 接着利用微信小程序id字符串的倒数第2个字符为xor key,依次异或1023字节后的所有数据,如果微信小程序id小于2位,则xorkey 为 **0x66** +4. 把AES加密后的数据(1024字节)和xor后的数据一起写入文件,并在文件头部添加**V1MMWX**标识