MFC程序每次启动前修改文件名

      因为一些众所周知,你们懂得的原因,开发一些特殊软件,比如那些能让你在游戏里释放原力和化身斗帝的软件会被检测软件标题和进程名。进程名其实就是exe的文件名,所以为了安全修真就产生了最好能每次启动软件前都随机修改一下exe文件名的需求。但是我们都知道一旦软件启动后是无法修改其文件名的,网上当然也有大神提供了一个方案:

      需要重命名的exe做成资源打包进一个exe中,也就是把B.exe作为资源打包放入A.exe,启动A.exe后A会先把B.exe作为资源释放到指定目录先改名后再自动运行B.exe。要实现这个过程就比较繁琐了,因此本人的简配版解决方案就是直接用WINDOWS提供的批处理文件直接修改同目录下的指定EXE文件名后再直接启动,从原理和效果上是相同的,实现起来就容易得多了,这样我们每次都双击.bat文件,批处理文件就会自动修改指定exe文件名,然后再自动启动exe。

      这个方案唯一需要解决的就是在我们需要启动的EXE中操作一下批处理文件.bat,修改其中下次启动时的EXE时的文件名,以达到随机文件名的效果。所以在此简配版方案中我们只需要搞清楚读写文件的API就可以了。虽然方法简陋,但是自行车也是车对吧,和春哥搞基那也是搞基呀。

1.首先需要先获取exe所在的目录

用于获取同目录下需要修改的.bat文件路径,具体的API解释可以参考本人博客中的《VS2010获得程序当前运行目录函数详解》博文。

2.下面是.bat文件中的内容

if exist f4wd.exe (goto aaa) else goto bbb
:aaa
ren f4wd.exe,awd4.exe ①
start awd4.exe ②
exit
:bbb
ren sdsd.exe,awd4.exe
start awd4.exe
exit

①把f4wd修改成awd4
②然后运行修改后的exe

 

3.CStdioFile

然后我们用MFC提供的这个CStdioFile类来操作.bat文件,这个类封装了C语言的WINDOWS系统读写文件API,读取文件和写入文件的原理其实也很简单,就是移动文件指针到指定字节,然后向此字节所在位置写入字节。例如:

移动文件指针

file.Seek(100,CFile::begin);///从文件头开始往下移动100字节
file.Seek(-50,CFile::end);///从文件末尾往上移动50字节
file.Seek(-30,CFile::current);///从当前位置往上移动30字节
file.SeekToBegin();///移到文件头
file.SeekToEnd();///移到文件尾


当然也有取巧的办法,就是我们用CStdioFile::ReadString()方法来读取一行,此方法是以行为单位读取文件内容,以换行符为结尾。读取一次就会移动文件指针到某一行,比如我们想读取第三行的内容,就调用3次此方法,又或者我们想向第三行写入也可以调用此方法3次,这样文件指针就会指向第三行。在本方案中,需要读取第三行的"awd4"4个字符,读取出这4个字符用于替换第一行的"f4wd"4个字符,这样下次启动的时候,.bat文件才能正常修改文件名。

 

4.CString::Right()和CString::Left()

现在我们已经成功读取到了"ren f4wd.exe,awd4.exe"第三行中的内容,要如何取出"awd4"这四个字符呢?可以使用CString::Right()和CString::Left两个方法,CString::Right()方法可以把一个字符串从右往左取参数中指定数目的字符,从右往左取刚好是8个字符就能把"awd4.exe"给取出来,然后再从左往右取4个字符,也就是使用CString::Left(),就能得到"awd4"这个修改后的文件名了。


5.CStdioFile::Open()

微软貌似并没有提供删除指定行的API,所以单独改写某一段不能实现。反正我是没有搜出相应方法,CSDN上也说只能清空整个文件,然后再重新写上。无论是读或者写我们都需要打开文件,微软提供了若干打开文件的策略,比如独占打开,打开后别的文件就不能再打开了,以及其他属性,这里我们需要用到CFile::modeCreate此属性,此属性为“如果文件不存在则创建,如果文件存在则打开文件并清空文件内容” 这样就能在我们要写入内容之前清空一个文件的所有内容。

下面是具体实现代码,在这里我把需要随机改变的文件名写入了ini配置文件中,可以随时修改随机文件名词组,要是觉得麻烦也可以把要随机的文件名写在程序中。

 

void Obopact()//随机修改bat文件
{

	CString cerem,inte,etween,sales,cloth,betweBu;
	CStdioFile file;
	string erved;
	wstring wstr; 
	vector<string> presid; //随机文件名
	BOOL ret;
	int resid,veaare=0;
	wchar_t *path=new wchar_t[256]; 

	GetModuleFileName(NULL,path,256); //获取exe所在路径

	wstr=path;

	cerem=wstr.c_str();

	cerem = cerem.Left(cerem.ReverseFind('\\')+1);//去掉\后面的××.exe

	//CAccorDlg::hungry(cerem);//输出结果

	delete [] path; 

	//获取exe自身所在目录为读取.bat做准备
	//------------------------
	//读取.bat文件中的内容

	cerem+=L"haha.bat";


	ret = file.Open(cerem, CFile::modeRead | CFile::shareDenyNone);
	if (!ret)
	{

		//CAccorDlg::hungry(L"文件打开失败");//输出结果
		veaare=0;

	}
	else
	{

		//CAccorDlg::hungry(L"文件打开成功");//输出结果 

		veaare=1;

		file.SeekToBegin();//把文件指针设置到文件开始

		for (int clot=0;clot<3;clot++)
		{

			file.ReadString(etween);//读取一行

		}



		//CAccorDlg::hungry(etween);//输出结果

		inte=etween.Right(8);

		inte=inte.Left(4);//得到修改后的文件名

		//CAccorDlg::hungry(inte);//输出结果

		// 关闭文件
		file.Close();

	}

	//----------------------
	//--写bat文件

	if (veaare==1)
	{


		ret = file.Open(cerem, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::shareDenyWrite|CFile::modeCreate);
		if (!ret)
		{

			//CAccorDlg::hungry(L"文件打开失败");//输出结果

		}
		else
		{

			//CAccorDlg::hungry(L"文件打开成功");//输出结果


			GetPrivateProfileString(L"随机文件名",L"betwe",NULL,betweBu.GetBufferSetLength(MAX_PATH),MAX_PATH,L"C:\\Warehouse\\config.ini");

			erved=toString(betweBu); //游戏账号转string

			Split(erved,"|",presid); //把账号拆分后放入presid向量

			resid=More(1,10)-1; //随机数生成函数

			cloth=toCString(presid[resid]); //string转CString;下一次启动要修改成的文件名


			file.SeekToBegin();//把文件指针设置到文件开始

			//  写文件
			sales=L"if exist "+inte+L".exe (goto aaa) else goto bbb\n"; //inte放的是变化以后的文件名

			file.WriteString(sales);
			file.WriteString(L":aaa\n");

			sales=L"ren "+inte+L".exe,"+cloth+L".exe\n";
			file.WriteString(sales);

			sales=L"start "+cloth+L".exe\n";
			file.WriteString(sales);

			file.WriteString(L"exit\n");

			file.WriteString(L":bbb\n");

			sales=L"ren ccor.exe,"+cloth+L".exe\n";  
			file.WriteString(sales);

			sales=L"start "+cloth+L".exe\n";
			file.WriteString(sales);

			file.WriteString(L"exit\n");

			// 关闭文件
			file.Close();


		}



	}



}

 

参考文献:
https://blog.csdn.net/hisinwang/article/details/45725299
https://www.cnblogs.com/JiMuStudio/archive/2011/07/17/2108497.html
https://zhidao.baidu.com/question/329107372.html
https://www.jb51.net/article/41399.htm
https://blog.csdn.net/eager7/article/details/11655977

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值