用最简单的方法来完成需要做的事情,test.exe
inline void Copy()
{
ifstream fin;
ofstream fout;
fin.open("Test.exe",ios::binary);
fout.open("Back.exe",ios::app|ios::binary);
#ifndef _RELEASE
cout<<fin.good()<<endl;
cout<<fout.good()<<endl;
system("pause");#endif
char tmp;
while(fin.get(tmp))
{
fout<<tmp;
}
fin.close();
fout.close();
}
使用二进制方式打开文件来保证正确地读取数据
使用fin.get()而不是fin>>来保证注入'/n' '/t' ' '等分隔符不会被跳过
同样的,使用fin.get()作为while循环的条件可以正确的结束文件读取,不会出现eof常有的判断失效问题。
这段代码的另一个好处是,如果配合fstream下的函数seekp来使用,可以在已有的文件中寻找足够长的{000...000}的区域,然后将自身程序写入其中,使得在目标文件尺寸没有任何变化的情况下将自身插入。当需要从目标调用的使用,只需要先从自身头部读取特征,然后在目标文件中逐个读入数据对比,一旦吻合便可以将整个文件读出。经测试,以二进制方式读出的代码只要头部正确,即使尾部出现额外代码也不会影响程序正常执行。同样的,将自身加载在其他exe文件尾部的话,同样不会影响其他exe文件的正确运行。
再补充写一点:
如何获取文件长度?其实方法再简单不过了,还是上面那段代码,稍微修改下就可以了。
const int len=sizeof(char);
//其他代码
inline void GetFileLength(const char& FileName[])
{
ifstream fin;
int i=0;
fin.open(FileName,ios::binary);
char tmp;
while(fin.get(tmp))
{
i=i+len;
}
fin.close();
cout<<i<<endl;
system("pause");
}
所得到的i就是文件长度了,单位为字节byte,保证精确性。
显然的,FileName那里也可以用其他的方式来获取。