总是启动以后就立即停止 或仅仅能维持一小段时间, 无论我添加什么样的服务程序都这样
劳烦各位高手帮我看看 #include <stdafx.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <windows.h>#define DEFAULT_SERVICE "TestService"/*声明省略*/HANDLE hDll = NULL; //dll module handle used to get dll path in InstallService
SERVICE_STATUS_HANDLE hSrv; //Service HANDLE & STATUS used to get service state
DWORD dwCurrState;BOOL APIENTRY DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hDll = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
TellSCM( SERVICE_STOP_PENDING, 0, 0 );
Sleep(1500);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
}
return TRUE;
}__declspec(dllexport) void WINAPI ServiceMain( int argc, wchar_t* argv[] )
{
char svcname[256]=DEFAULT_SERVICE;
hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
if( hSrv == NULL )
{
return;
} TellSCM( SERVICE_START_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_RUNNING, 0, 0 ); //Real Service 这里是服务 我没有加入服务函数 或线程 do
{
Sleep(10);//not quit until receive stop command, otherwise the service will stop
}
while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED);
return;
}
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
SERVICE_STATUS srvStatus;
srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
srvStatus.dwCurrentState = dwCurrState = dwState;
srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
srvStatus.dwWin32ExitCode = dwExitCode;
srvStatus.dwServiceSpecificExitCode = 0;
srvStatus.dwCheckPoint = dwProgress;
srvStatus.dwWaitHint = 3000;
return SetServiceStatus( hSrv, &srvStatus );
}
int InstallService(char *name)
{
// Open a handle to the SC Manager database.
int rc = 0;
HKEY hkRoot = HKEY_LOCAL_MACHINE, hkParam = 0;
SC_HANDLE hscm = NULL, schService = NULL; try
{
char buff[500];
char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name; //query svchost setting
char *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
rc = RegOpenKeyEx(hkRoot, pSvchost, 0, KEY_QUERY_VALUE, &hkRoot);
if(ERROR_SUCCESS != rc)
{
throw "";
} DWORD type, size = sizeof buff;
rc = RegQueryValueEx(hkRoot, "netsvcs", 0, &type, (unsigned char*)buff, &size);
RegCloseKey(hkRoot);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegQueryValueEx(Svchost\\netsvcs)"; //install service
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
throw "OpenSCManager()";
char *bin = "%SystemRoot%\\System32\\svchost.exe -k netsvcs"; schService = CreateService(
hscm, // SCManager database
svcname, // name of service
NULL, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_SHARE_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
bin, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password if (schService == NULL)
{
throw "";
} CloseServiceHandle(schService);
CloseServiceHandle(hscm); //config service
hkRoot = HKEY_LOCAL_MACHINE;
strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
strncat(buff, svcname, 100);
rc = RegOpenKeyEx(hkRoot, buff, 0, KEY_ALL_ACCESS, &hkRoot);
if(ERROR_SUCCESS != rc)
{
throw "";
} rc = RegCreateKey(hkRoot, "Parameters", &hkParam);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegCreateKey(Parameters)"; if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff))
throw "GetModuleFileName() get dll path"; rc = RegSetValueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegSetValueEx(ServiceDll)"; }
catch(char *str)
{
if(str && str[0])
{
rc = GetLastError();
}
} RegCloseKey(hkRoot);
RegCloseKey(hkParam);
CloseServiceHandle(schService);
CloseServiceHandle(hscm); return rc;
}
/*
used to install by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK InstallA(
HWND hwnd, // handle to owner window
HINSTANCE hinst, // instance handle for the DLL
char *param, // string the DLL will parse
int nCmdShow // show state
)
{
InstallService(param);
}
int UninstallService(char *name)
{
int rc = 0;
SC_HANDLE schService;
SC_HANDLE hscm; __try
{
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
{
return rc;
} char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name; schService = OpenService(hscm, svcname, DELETE);
if (schService == NULL)
{
return rc;
} if (!DeleteService(schService) )
{
return rc;
} }__except(1){} CloseServiceHandle(schService);
CloseServiceHandle(hscm);
return rc;
}
/*
used to uninstall by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK UninstallA(
HWND hwnd, // handle to owner window
HINSTANCE hinst, // instance handle for the DLL
char *param, // string the DLL will parse
int nCmdShow // show state
)
{
UninstallService(param);
}void __stdcall ServiceHandler( DWORD dwCommand )
{
switch( dwCommand )
{
case SERVICE_CONTROL_STOP:
TellSCM( SERVICE_STOP_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
case SERVICE_CONTROL_PAUSE:
TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_PAUSED, 0, 0 );
break;
case SERVICE_CONTROL_CONTINUE:
TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_RUNNING, 0, 0 );
break;
case SERVICE_CONTROL_INTERROGATE:
TellSCM( dwCurrState, 0, 0 );
break;
case SERVICE_CONTROL_SHUTDOWN:
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
}
}
还有 我想在这种程序里面加入 全局Hook 行不行?
劳烦各位高手帮我看看 #include <stdafx.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <windows.h>#define DEFAULT_SERVICE "TestService"/*声明省略*/HANDLE hDll = NULL; //dll module handle used to get dll path in InstallService
SERVICE_STATUS_HANDLE hSrv; //Service HANDLE & STATUS used to get service state
DWORD dwCurrState;BOOL APIENTRY DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hDll = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
TellSCM( SERVICE_STOP_PENDING, 0, 0 );
Sleep(1500);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
}
return TRUE;
}__declspec(dllexport) void WINAPI ServiceMain( int argc, wchar_t* argv[] )
{
char svcname[256]=DEFAULT_SERVICE;
hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
if( hSrv == NULL )
{
return;
} TellSCM( SERVICE_START_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_RUNNING, 0, 0 ); //Real Service 这里是服务 我没有加入服务函数 或线程 do
{
Sleep(10);//not quit until receive stop command, otherwise the service will stop
}
while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED);
return;
}
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
SERVICE_STATUS srvStatus;
srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
srvStatus.dwCurrentState = dwCurrState = dwState;
srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
srvStatus.dwWin32ExitCode = dwExitCode;
srvStatus.dwServiceSpecificExitCode = 0;
srvStatus.dwCheckPoint = dwProgress;
srvStatus.dwWaitHint = 3000;
return SetServiceStatus( hSrv, &srvStatus );
}
int InstallService(char *name)
{
// Open a handle to the SC Manager database.
int rc = 0;
HKEY hkRoot = HKEY_LOCAL_MACHINE, hkParam = 0;
SC_HANDLE hscm = NULL, schService = NULL; try
{
char buff[500];
char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name; //query svchost setting
char *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
rc = RegOpenKeyEx(hkRoot, pSvchost, 0, KEY_QUERY_VALUE, &hkRoot);
if(ERROR_SUCCESS != rc)
{
throw "";
} DWORD type, size = sizeof buff;
rc = RegQueryValueEx(hkRoot, "netsvcs", 0, &type, (unsigned char*)buff, &size);
RegCloseKey(hkRoot);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegQueryValueEx(Svchost\\netsvcs)"; //install service
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
throw "OpenSCManager()";
char *bin = "%SystemRoot%\\System32\\svchost.exe -k netsvcs"; schService = CreateService(
hscm, // SCManager database
svcname, // name of service
NULL, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_SHARE_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
bin, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password if (schService == NULL)
{
throw "";
} CloseServiceHandle(schService);
CloseServiceHandle(hscm); //config service
hkRoot = HKEY_LOCAL_MACHINE;
strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
strncat(buff, svcname, 100);
rc = RegOpenKeyEx(hkRoot, buff, 0, KEY_ALL_ACCESS, &hkRoot);
if(ERROR_SUCCESS != rc)
{
throw "";
} rc = RegCreateKey(hkRoot, "Parameters", &hkParam);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegCreateKey(Parameters)"; if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff))
throw "GetModuleFileName() get dll path"; rc = RegSetValueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegSetValueEx(ServiceDll)"; }
catch(char *str)
{
if(str && str[0])
{
rc = GetLastError();
}
} RegCloseKey(hkRoot);
RegCloseKey(hkParam);
CloseServiceHandle(schService);
CloseServiceHandle(hscm); return rc;
}
/*
used to install by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK InstallA(
HWND hwnd, // handle to owner window
HINSTANCE hinst, // instance handle for the DLL
char *param, // string the DLL will parse
int nCmdShow // show state
)
{
InstallService(param);
}
int UninstallService(char *name)
{
int rc = 0;
SC_HANDLE schService;
SC_HANDLE hscm; __try
{
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
{
return rc;
} char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name; schService = OpenService(hscm, svcname, DELETE);
if (schService == NULL)
{
return rc;
} if (!DeleteService(schService) )
{
return rc;
} }__except(1){} CloseServiceHandle(schService);
CloseServiceHandle(hscm);
return rc;
}
/*
used to uninstall by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK UninstallA(
HWND hwnd, // handle to owner window
HINSTANCE hinst, // instance handle for the DLL
char *param, // string the DLL will parse
int nCmdShow // show state
)
{
UninstallService(param);
}void __stdcall ServiceHandler( DWORD dwCommand )
{
switch( dwCommand )
{
case SERVICE_CONTROL_STOP:
TellSCM( SERVICE_STOP_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
case SERVICE_CONTROL_PAUSE:
TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_PAUSED, 0, 0 );
break;
case SERVICE_CONTROL_CONTINUE:
TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
Sleep(10);
TellSCM( SERVICE_RUNNING, 0, 0 );
break;
case SERVICE_CONTROL_INTERROGATE:
TellSCM( dwCurrState, 0, 0 );
break;
case SERVICE_CONTROL_SHUTDOWN:
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
}
}
还有 我想在这种程序里面加入 全局Hook 行不行?
我往里面加过Hook 确实是启动以后什么都钩不住选择合适的服务组 是不是可以实现登陆用户身份运行hook?在有 我在服务子程序里面 写死循环 0仍然是运行议会就停止 自动化程度很高……
但那样和运行普通程序没什么两样了。
可以通过遍历进程来取得登陆用户的Shell的hToken来运行进程。下面就是示例代码:BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName)
{
if(!lpName)
{
return FALSE;
}
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = TRUE;
}
else
bRet = FALSE;
CloseHandle (hProcessSnap);
return (bRet);
}BOOL RunProcess(LPCSTR lpImage)
{
if(!lpImage)
{
return FALSE;
}
HANDLE hToken;
if(!GetTokenByName(hToken,"EXPLORER.EXE"))
{
return FALSE;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default");
BOOL bResult = CreateProcessAsUser(hToken,lpImage,NULL,NULL,NULL,
FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
CloseHandle(hToken);
if(bResult)
{
OutputDebugString("CreateProcessAsUser ok!\r\n");
}
else
{
OutputDebugString("CreateProcessAsUser false!\r\n");
}
return bResult;
}
1.需要消息循环。
2.当前桌面可以有hook权限。
3.不会出现挎桌面hook。
但是我试了一下,可以肯定用了程序中的安装服务以后,这个服务根本就没有运行。
其实 可以注意到 他是运行了的 只不过是运行之后马上停止
你改的这个服务程序其实根本就没有运行,具体的原因我解释一下。
根据Bingle的文章,svchost调用服务可以有四种方式启动:
1) 添加一个新的服务组,在组里添加服务名
2) 在现有组里添加服务名
3) 直接使用现有服务组里的一个服务名,但本机没有安装的服务
4) 修改现有服务组里的现有服务,把它的ServiceDll指向自己
Bingle本来的例子是采用的3的启动方式,他使用了IPrip服务,该服务本来就位于netsvcs服务组中,所以在他的InstallService例程里仅仅是添加了该服务的dll路径,这就够了,所以他的服务可以运行。
而你修改的程序中,改了服务的名称为TestService,这个服务本身并不在netsvcs服务组中,而你也没有修改他的InstallService,将TestService添加到netsvcs服务组中去(修改HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost下netsvcs的键值),所以你修改的服务程序是不会运行的。把TestService改回IPrip,那么你的服务就可以运行了。如果你坚持要用TestService作为服务名,那么你只能使用1或2两种方式,而方式2相对简单一些,因为添加一个服务组也挺麻烦的(详细操作我也没做过)。
其实 我调程序用的一直就是IPRIP
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
TellSCM( SERVICE_STOP_PENDING, 0, 0 );
Sleep(1500);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;把它们注释掉就好了。