7z 自解压功能,实际是将三个文件连接在一起,第一个文件是 7z 的自解压模块(实际是一个通用的包含了界面界面的应用程序)+ config.txt(配置文件)+ 实际要解压的 7z 压缩包文件。三个文件通过 Windows 的 copy 命令拼接在一起,你也可以自己实现代码,将三个文件拼接在一起,因为第一个文件的首地址 PE 结构不变,所以当程序运行时相当于运行了 7z 的自解压模块。他们的组成如下图: 图中可以看的出来,使用 copy /b
将三个文件连接在了一起,我们需要在自解压的模块程序 7z_sfx.exe
中实现读取查找 config.txt
文件的位置和内容,从而也就可以得到自解压文件的起始位置。这样在解压文件的时候将包装在我们程序中的自解压程序起始地址传递进去就可以了。
前提条件
首先要在代码中找到被追加进自己程序的 config.txt 文件内容,config.txt 必须要有一个标识来记录文件的开头和结束,这样我们才知道这个文件中间的内容,参考 7z 自解压模块的代码,其在 config.txt 头部和尾部分别设计了两个标识,如下所示:
1 | ;!@Install@!UTF-8! |
在程序中只要将程序一块一块的读取到内存,对比每一个字节如果存在 ;!@Install@!UTF-8!
就是 config 文件的开头,存在 ;!@InstallEnd@!
就是 config 文件的结尾。这样中间的内容也就确定了,文件结尾的位置就是 7z 压缩包文件的开头。
实现代码
代码实现起来要考虑的内容还是比较多的,我参考了 7z 的代码从头实现了一遍,对每一个变量都做了作用注释,因为 7z 官方的代码一个注释都没有,看起来很难懂,索性就参考他的思路一点一点重写了一遍。调用 FindSignature
方法就可以查找到 config.txt 中的内容了,用 strOutput
参数将内容传出。 程序编译完成后,使用 copy /b 程序名 + 带有标记的 config.txt 就可以测试出效果,自己再加上解压的代码你就可以实现一个属于自己的自解压模块了。
1 | #include <iostream> |