以前看过authorware,authorware 生成的东西只有在authorware 里才能运行。 恰巧网上有人讨论怎么从一个程序生成另一个程序。 网上是有一些软件要怎么做。 比如电子教室, 录制生成的东西本身是exe。如游戏制作工具, 制作完就是一个exe(这里的exe不外带数据文件, 和库
文件文件)
我想软件就是数据+执行代码。 执行代码是很诡异的事情, 从母程序编译执行代码是不可思议的事情吧。 那么做法应该是很确定了, 先准
备一个子程序模板, 这个模板子程序放个数据占位, 只做数据解析工作,以先前的authorware为例, 子程序拥有解析母程序生成数据的模块
。
然后母程序加个功能, 先拷贝一份模板子程序, 然后在其插入数据 。
windows 的可执行程序是PE格式。 资源数据放在.rsrc节里, 但是PE的解析, 是十分繁琐的事情. 而API也是有相关的函数的。
下面是我写的一个模块做个演示,没写完, 有时间补上。
//头文件
//
//可执行文件产生器
class Generator
{
public:
Generator(){}
virtual ~Generator(){}
public:
virtual bool IsBinary() const = 0; //检查完整性
//替换资源
virtual bool ReplaceResource(const char* name, const char* type, const void* dat a, unsigned long len) = 0;
virtual bool GeneratorBin() = 0; //拷贝文件
};
//
//可执行文件产生器--API实现
class MSApiGenerator : public Generator
{
public:
MSApiGenerator(const char* binaryDest, const char* binarySource);
virtual ~MSApiGenerator();
protected:
MSApiGenerator(const MSApiGenerator& ){}
MSApiGenerator& operator= (const MSApiGenerator&){}
public:
virtual bool IsBinary() const;
virtual bool ReplaceResource(const char* name, const char* type, const void* data, unsigned long len) ;
virtual bool GeneratorBin() ;
private:
std::string mBinaryDest;
std::string mBinarySource;
};
//
//可执行文件产生器--PE实现
class PEGenerator : public Generator
{
public:
virtual bool IsBinary() const {}
virtual bool ReplaceResource(const char* name, const char* type, const void* da ta, unsigned long len) {}
virtual bool GeneratorBin() {}
};
//
//类构造器
class GeneratorCreator
{
public:
GeneratorCreator(void){}
~GeneratorCreator(void){ mInstance = 0;}
protected:
GeneratorCreator(const GeneratorCreator& ){}
GeneratorCreator& operator= (const GeneratorCreator&){}
public:
static GeneratorCreator* GetInstance();
public:
//API 子类产生函数
Generator* MSApiProduct(const char* binaryDest, const char* binarySource) const;
//PE 子类产生函数
Generator* PEProduct(const char* binaryDest, const char* binarySource) const;
private:
static GeneratorCreator *mInstance;
};
//实现文件
//
MSApiGenerator::MSApiGenerator(const char* binaryDest, const char* binarySource)
:mBinaryDest(binaryDest), mBinarySource(binarySource)
{
}
MSApiGenerator::~MSApiGenerator()
{
}
bool MSApiGenerator::IsBinary() const
{
if (mBinaryDest.empty() || mBinarySource.empty())
{
return false;
}
if (!GetBinaryType(mBinarySource.c_str(),SCS_32BIT_BINARY))
{
return false;
}
return true;
}
bool MSApiGenerator::ReplaceResource(const char* name, const char* type, const void* data, unsigned long len)
{
if (!IsBinary())
{
return false;
}
HANDLE hUpdate = BeginUpdateResource(mBinarySource.c_str(), FALSE);
if (hUpdate==NULL)
{
return false;
}
if (!UpdateResource(hUpdate, type, name, -1/*乱写的*/, (LPVOID)data, len))
{
return false;
}
EndUpdateResource(hUpdate, FALSE);
return true;
}
bool MSApiGenerator::GeneratorBin()
{
return true;
}
//
GeneratorCreator* GeneratorCreator::mInstance=0;
GeneratorCreator* GeneratorCreator::GetInstance()
{
if (mInstance)
{
return mInstance;
}
mInstance = new GeneratorCreator;
return mInstance;
}
Generator* GeneratorCreator::MSApiProduct(const char* binaryDest, const char* binarySource) const
{
return new MSApiGenerator(binaryDest, binarySource);
}
Generator* GeneratorCreator::PEProduct(const char* binaryDest, const char* binarySource) const
{
return 0;
}
//demo
///
//修改程序
int main(int argc, char *argv[])
{
Generator *generator = GeneratorCreator::GetInstance()->MSApiProduct("...", "....");
if (generator->IsBinary())
{
generator->ReplaceResource(....);
generator->ReplaceResource(....);
generator->GeneratorBin();
}
delete generator;
delete GeneratorCreator::GetInstance();
return 0;
}