微信小程序反编译教程获取源码

背景:

开发的时候需要一些素材,发现小程序(.wxapkg)里有一些图标或背景图很好看,但又没办法直接获取到(小程序里如果打包时候直接集成进去的fiddler是无法监听到网络请求的),于是研究小程序结构,决定通过代码解放小程序...

开工

厦门植物园 小程序为例

首先打开电脑上小程序的位置

注:为了便于找到可以把小程序先移除再重新打开,这样就会在本地出现一个最新日期的小程序文件

下载文章上部的微信小程序 反编译小工具

点击选择文件按钮选择对应的小程序目录如下图

 点击 打开按钮即可解压,下图中的文件夹即是 小程序反编译后的代码

 

代码解析及原理

这个反编译的原理就是 利用这个文件的一个 组织结构,文件的存储结构进行分析,这个原理是网上网友(代码果)分享的,如果一般人 真的无法知晓这个小程序的编译结构!

第一步 重新组织文件结构

string fileName = openFileDialog.FileName;
byte[] source = this.FileContent(fileName);
string miniAppFlag = Encoding.UTF8.GetString(source.Take(6).ToArray<byte>());
this.textBox2.AppendText("文件选择:" + fileName + "\r\n");
bool needUnEncrypt = miniAppFlag == "V1MMWX";
string appId = this.GetStr(fileName, "Applet\\\\", "\\\\");
if (needUnEncrypt)
{
	if (string.IsNullOrEmpty(appId))
	{
		this.textBox2.AppendText("疑似非小程序,请重新选择!\r\n");
	}
	else
	{
		this.outFileName = "\\" + appId + ".wxapkg";
		this.textBox2.AppendText("文件解密中...\r\n");
		string salts = "saltiest";
		byte[] bytes = Encoding.UTF8.GetBytes("the iv: 16 bytes");
		byte[] strKey = this.PBKDF2(appId, salts);
		byte[] source2 = Form1.AESDecrypt(source.Skip(6).Take(1024).ToArray<byte>(), bytes, strKey);
		byte[] array2 = source.Skip(1030).ToArray<byte>();
		int num = Form1.Asc(appId.Substring(appId.Length - 2, 1));
		int num2 = array2.Length;
		List<byte> list = new List<byte>();
		list.AddRange(source2.Take(1023).ToArray<byte>());
		int num3;
		for (int i = 0; i < num2; i = num3 + 1)
		{
			list.Add((byte)((int)array2[i] ^ num));
			num3 = i;
		}
		this.textBox2.AppendText("解密成功->" + this.outFileName + "\r\n");
		this.writerFile(list.ToArray(), this.AppPath + this.outFileName);
	}
}

第二步 解压缩

FileStream fileStream = new FileStream(this.AppPath + this.outFileName,FileMode.Open);
BinaryReader binaryReader = new BinaryReader(fileStream);
binaryReader.BaseStream.Position = 14;

int fileCount = readInt(binaryReader);
List<WxapkgItem> wxapkgItems = new List<WxapkgItem>();
for (int i = 0; i < fileCount; i++) {
	int nameLen = readInt(binaryReader);
	byte[] buf = new byte[nameLen];
	buf = binaryReader.ReadBytes(nameLen);

	string name = System.Text.Encoding.UTF8.GetString(buf, 0, nameLen);
	int start = readInt(binaryReader);
	int length = readInt(binaryReader);
	wxapkgItems.Add(new WxapkgItem(name, start, length));
}

foreach (WxapkgItem wxapkgItem in wxapkgItems) {
	byte[] file = new byte[wxapkgItem.getLength()];
	binaryReader.BaseStream.Position = wxapkgItem.getStart();
	file = binaryReader.ReadBytes(wxapkgItem.getLength());
	string filepath = this.AppPath + "\\" + appId + wxapkgItem.getName();
	this.textBox2.AppendText(filepath.Replace("\\","/")+ "\r\n");
	writerFile(file.ToArray(), filepath);
}
binaryReader.Close();

总结 

这个小程序的结构也算是行业通用组织结构,类似于谷歌浏览器的插件也是类似结构,放置到运行前端,提升速度,真正核心的还是 小程序 所对应的后端代码,放置在微信里的可以理解为是一套UI图~

转载请注明出处,谢谢!