C++笔记-一种二进制文件拼接技术的实现方式
·
知识点
将一个文件的数据附加到另一个可执行文件的末尾,而不影响原可执行文件的运行,同时原可执行文件可以通过特定方式读取这些附加的数据。
技术原理:
① 可执行文件格式(如 Windows 的 PE、Linux 的 ELF)允许在文件末尾添加额外数据而不影响其执行
② 程序 A 在程序 B 末尾先写入附加文件的内容,再写入文件大小(8 字节)。
③ 程序 B 运行时,读取程序 B 末尾附件文件的大小,再定位并读取附加内容
代码与实现
程序 A(文件写入器)的功能是将指定文件附加到程序 B 的末尾
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
// 程序A:将一个文件附加到程序B的末尾
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 检查参数
if (argc != 4) {
qDebug() << QString::fromLocal8Bit("用法: ") << argv[0] << QString::fromLocal8Bit("<程序B路径> <要附加的文件路径> <输出文件路径>");
return 1;
}
QString programBPath = argv[1];
QString fileToAppendPath = argv[2];
QString outputPath = argv[3];
// 打开程序B
QFile programB(programBPath);
if (!programB.open(QIODevice::ReadOnly)) {
qDebug() << QString::fromLocal8Bit("无法打开程序B: ") << programB.errorString();
return 1;
}
// 打开要附加的文件
QFile fileToAppend(fileToAppendPath);
if (!fileToAppend.open(QIODevice::ReadOnly)) {
qDebug() << QString::fromLocal8Bit("无法打开要附加的文件: ") << fileToAppend.errorString();
programB.close();
return 1;
}
// 创建输出文件
QFile outputFile(outputPath);
if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << QString::fromLocal8Bit("无法创建输出文件: ") << outputFile.errorString();
programB.close();
fileToAppend.close();
return 1;
}
// 写入程序B的内容
outputFile.write(programB.readAll());
// 写入要附加的文件内容
outputFile.write(fileToAppend.readAll());
// 先写入附加文件的大小(8字节),方便程序B读取时定位
qint64 fileSize = fileToAppend.size();
outputFile.write((char*)&fileSize, sizeof(qint64));
qDebug() << QString::fromLocal8Bit("文件已成功附加到程序B末尾");
// 关闭所有文件
programB.close();
fileToAppend.close();
outputFile.close();
return 0;
}
程序 B(读取器)的功能是执行自身并读取被附加的文件内容:
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
#include <QString>
// 程序B:读取自身末尾附加的文件内容
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 获取当前程序的路径
QString programPath = QCoreApplication::applicationFilePath();
// 打开当前程序文件
QFile programFile(programPath);
if (!programFile.open(QIODevice::ReadOnly)) {
qDebug() << QString::fromLocal8Bit("无法打开程序文件: ") << programFile.errorString();
return 1;
}
// 获取文件大小
qint64 fileSize = programFile.size();
// 移动到文件末尾前8个字节的位置(存储了文件大小)
if (!programFile.seek(fileSize - sizeof(qint64))) {
qDebug() << QString::fromLocal8Bit("无法定位到文件大小存储位置");
programFile.close();
return 1;
}
// 读取附加文件的大小
qint64 appendedFileSize;
programFile.read((char*)&appendedFileSize, sizeof(qint64));
// 移动到附加文件的起始位置
qint64 appendedFileOffset = fileSize - sizeof(qint64) - appendedFileSize;
if (!programFile.seek(appendedFileOffset)) {
qDebug() << QString::fromLocal8Bit("无法定位到附加文件的起始位置");
programFile.close();
return 1;
}
// 读取附加的文件内容
QByteArray appendedData = programFile.read(appendedFileSize);
qDebug() << QString::fromLocal8Bit("成功读取到附加的文件内容,大小为") << appendedData.size() << QString::fromLocal8Bit("字节");
qDebug() << QString::fromLocal8Bit("内容如下:");
qDebug() << QString(appendedData);
programFile.close();
return 0;
}
程序运行截图如下:

1.txt内容:

注意
如果是Linux,使用chmod设置下权限,或者直接root去操作即可。
如果是windows,就需要以管理员身份运行。或者编辑权限(与linux chmod原理一致)

更多推荐

所有评论(0)