wxapkg 是微信小程序编译包格式,文件内包含小程序的源码与图像等资源文件。
将微信卸载重装,或者清空所有小程序后,重新加载要分析的小程序,
在/data/data/com.tencent.mm/MicroMsg/appbrand目录下搜索wxapkg会得到所在目录,导出即可。
wxapkg 文件的数据格式分成三个部分:
第一部分:文件的前 6 字节为 V1MMWX;
第二部分:之后的 1024 字节为 AES CBC 加密数据;
第三部分:从 1024+6 之后的所有数据为异或加密的数据。
用 010、UE 等十六进制编辑器打开一个 wxapkg,会很容易看到三个部分的界限。
文件第二部分的 AES CBC 加密,使用的 key 与对应的微信小程序id有关。
文件第三部分的异或加密,真就是简单的异或,xorkey 为微信小程序 id 的倒数第二字节的内容。
上源码,在main函数下给定dir_path即导出后wxapkg所在电脑文件夹路径。
__author__
=
'行简'
import
sys, os
import
struct
class
WxapkgFile(
object
):
nameLen
=
0
name
=
""
offset
=
0
size
=
0
def
main(dir_path):
with
open
(dir_path,
"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
]
firstMark
=
struct.unpack(
'B'
, f.read(
1
))[
0
]
print
(
'first header mark = {}'
.
format
(firstMark))
info1
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'info1 = {}'
.
format
(info1))
indexInfoLength
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'indexInfoLength = {}'
.
format
(indexInfoLength))
bodyInfoLength
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'bodyInfoLength = {}'
.
format
(bodyInfoLength))
lastMark
=
struct.unpack(
'B'
, f.read(
1
))[
0
]
print
(
'last header mark = {}'
.
format
(lastMark))
if
firstMark !
=
0xBE
or
lastMark !
=
0xED
:
print
(
'its not a wxapkg file!!!!!'
)
f.close()
exit()
fileCount
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'fileCount = {}'
.
format
(fileCount))
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 = {} at Offset = {}'
.
format
(
str
(data.name, encoding
=
"utf-8"
), data.offset))
fileList.append(data)
for
d
in
fileList:
d.name
=
'/'
+
name
+
str
(d.name, encoding
=
"utf-8"
)
path
=
root
+
os.path.dirname(d.name)
if
not
os.path.exists(path):
os.makedirs(path)
w
=
open
(root
+
d.name,
'wb'
)
f.seek(d.offset)
w.write(f.read(d.size))
w.close()
print
(
'writeFile = {}{}'
.
format
(root, d.name))
f.close()
if
__name__
=
=
'__main__'
:
dir_path
=
r
'xxxx'
main(dir_path)
__author__
=
'行简'
import
sys, os
import
struct
class
WxapkgFile(
object
):
nameLen
=
0
name
=
""
offset
=
0
size
=
0
def
main(dir_path):
with
open
(dir_path,
"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
]
firstMark
=
struct.unpack(
'B'
, f.read(
1
))[
0
]
print
(
'first header mark = {}'
.
format
(firstMark))
info1
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'info1 = {}'
.
format
(info1))
indexInfoLength
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
print
(
'indexInfoLength = {}'
.
format
(indexInfoLength))
bodyInfoLength
=
struct.unpack(
'>L'
, f.read(
4
))[
0
]
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-6-9 09:32
被行简编辑
,原因: