Skip to content

Commit 3ad008b

Browse files
committed
public
0 parents  commit 3ad008b

File tree

6 files changed

+230
-0
lines changed

6 files changed

+230
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
wxapkg.iml
3+
wxapkg.exe

decrypt.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package main
2+
3+
import (
4+
"crypto/aes"
5+
"crypto/cipher"
6+
"crypto/sha1"
7+
"fmt"
8+
"golang.org/x/crypto/pbkdf2"
9+
"log"
10+
"os"
11+
)
12+
13+
type DecryptOptions struct {
14+
Wxid string
15+
Iv string
16+
Salt string
17+
WxapkgPath string
18+
DecWxapkgPath string
19+
}
20+
21+
const DecryptTo = "_decrypt"
22+
23+
func Decrypt(from string, wxid string) error {
24+
return decrypt(&DecryptOptions{
25+
Wxid: wxid,
26+
Iv: "the iv: 16 bytes",
27+
Salt: "saltiest",
28+
WxapkgPath: from,
29+
DecWxapkgPath: from + DecryptTo,
30+
})
31+
}
32+
33+
func decrypt(options *DecryptOptions) error {
34+
dataByte, err := os.ReadFile(options.WxapkgPath)
35+
if err != nil {
36+
log.Fatal(err)
37+
}
38+
39+
dk := pbkdf2.Key([]byte(options.Wxid), []byte(options.Salt), 1000, 32, sha1.New)
40+
block, _ := aes.NewCipher(dk)
41+
blockMode := cipher.NewCBCDecrypter(block, []byte(options.Iv))
42+
originData := make([]byte, 1024)
43+
blockMode.CryptBlocks(originData, dataByte[6:1024+6])
44+
45+
afData := make([]byte, len(dataByte)-1024-6)
46+
var xorKey = byte(0x66)
47+
if len(options.Wxid) >= 2 {
48+
xorKey = options.Wxid[len(options.Wxid)-2]
49+
}
50+
for i, b := range dataByte[1024+6:] {
51+
afData[i] = b ^ xorKey
52+
}
53+
54+
originData = append(originData[:1023], afData...)
55+
56+
err = os.WriteFile(options.DecWxapkgPath, originData, 0666)
57+
if err != nil {
58+
return fmt.Errorf("write file error: %v", err)
59+
}
60+
61+
return nil
62+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module wxapkg
2+
3+
go 1.20
4+
5+
require golang.org/x/crypto v0.11.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
2+
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=

main.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
)
8+
9+
func main() {
10+
from := strings.ReplaceAll(os.Args[1], "\\", "/")
11+
fromParts := strings.Split(from, "/")
12+
wxid := fromParts[len(fromParts)-3]
13+
fmt.Println("wxid", wxid)
14+
15+
err := Decrypt(from, wxid)
16+
if err != nil {
17+
fmt.Println(err)
18+
return
19+
}
20+
21+
err = Unpack(from + DecryptTo)
22+
if err != nil {
23+
fmt.Println(err)
24+
return
25+
}
26+
27+
fmt.Println("success")
28+
}

unpack.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package main
2+
3+
import (
4+
"encoding/binary"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
type UnpackFile struct {
11+
nameLen uint32
12+
name string
13+
offset uint32
14+
size uint32
15+
}
16+
17+
func Unpack(from string) error {
18+
f, err := os.Open(from)
19+
if err != nil {
20+
return fmt.Errorf("error opening file: %v", err)
21+
}
22+
defer f.Close()
23+
24+
root := filepath.Dir(from)
25+
name := filepath.Base(from) + "_unpack"
26+
27+
var firstMark byte
28+
if err := binary.Read(f, binary.BigEndian, &firstMark); err != nil {
29+
return fmt.Errorf("error reading first header mark: %v", err)
30+
}
31+
fmt.Println("first header mark =", firstMark)
32+
33+
var info1 uint32
34+
if err := binary.Read(f, binary.BigEndian, &info1); err != nil {
35+
return fmt.Errorf("error reading info1: %v", err)
36+
}
37+
fmt.Println("info1 =", info1)
38+
39+
var indexInfoLength uint32
40+
if err := binary.Read(f, binary.BigEndian, &indexInfoLength); err != nil {
41+
return fmt.Errorf("error reading indexInfoLength: %v", err)
42+
}
43+
fmt.Println("indexInfoLength =", indexInfoLength)
44+
45+
var bodyInfoLength uint32
46+
if err := binary.Read(f, binary.BigEndian, &bodyInfoLength); err != nil {
47+
return fmt.Errorf("error reading bodyInfoLength: %v", err)
48+
}
49+
fmt.Println("bodyInfoLength =", bodyInfoLength)
50+
51+
var lastMark byte
52+
if err := binary.Read(f, binary.BigEndian, &lastMark); err != nil {
53+
return fmt.Errorf("error reading last header mark: %v", err)
54+
}
55+
fmt.Println("last header mark =", lastMark)
56+
57+
if firstMark != 0xBE || lastMark != 0xED {
58+
return fmt.Errorf("it's not a wxapkg file")
59+
}
60+
61+
var fileCount uint32
62+
if err := binary.Read(f, binary.BigEndian, &fileCount); err != nil {
63+
return fmt.Errorf("error reading fileCount: %v", err)
64+
}
65+
fmt.Println("fileCount =", fileCount)
66+
67+
fileList := make([]UnpackFile, 0, fileCount)
68+
69+
for i := uint32(0); i < fileCount; i++ {
70+
var data UnpackFile
71+
if err := binary.Read(f, binary.BigEndian, &data.nameLen); err != nil {
72+
return fmt.Errorf("error reading nameLen: %v", err)
73+
}
74+
75+
nameBytes := make([]byte, data.nameLen)
76+
if _, err := f.Read(nameBytes); err != nil {
77+
return fmt.Errorf("error reading name: %v", err)
78+
}
79+
data.name = string(nameBytes)
80+
81+
if err := binary.Read(f, binary.BigEndian, &data.offset); err != nil {
82+
return fmt.Errorf("error reading offset: %v", err)
83+
}
84+
85+
if err := binary.Read(f, binary.BigEndian, &data.size); err != nil {
86+
return fmt.Errorf("error reading size: %v", err)
87+
}
88+
89+
fmt.Println("readFile =", data.name, "at Offset =", data.offset)
90+
91+
fileList = append(fileList, data)
92+
}
93+
94+
for _, d := range fileList {
95+
d.name = "/" + name + d.name
96+
path := filepath.Join(root, filepath.Dir(d.name))
97+
98+
if err := os.MkdirAll(path, os.ModePerm); err != nil {
99+
return fmt.Errorf("error creating directory: %v", err)
100+
}
101+
102+
w, err := os.Create(filepath.Join(root, d.name))
103+
if err != nil {
104+
return fmt.Errorf("error creating file: %v", err)
105+
}
106+
107+
_, err = f.Seek(int64(d.offset), 0)
108+
if err != nil {
109+
w.Close()
110+
return fmt.Errorf("error seeking to offset: %v", err)
111+
}
112+
113+
buf := make([]byte, d.size)
114+
_, err = f.Read(buf)
115+
if err != nil {
116+
w.Close()
117+
return fmt.Errorf("Error reading from file: %v", err)
118+
}
119+
120+
_, err = w.Write(buf)
121+
if err != nil {
122+
return fmt.Errorf("error writing to file: %v", err)
123+
}
124+
125+
w.Close()
126+
fmt.Println("writeFile =", filepath.Join(root, d.name))
127+
}
128+
129+
return nil
130+
}

0 commit comments

Comments
 (0)