服务-钩子-权限

一、

服务程序,要同桌面程序交换,程序属性必须设置:SERVICE_INTERACTIVE_PROCESS

 SC_HANDLE hService = ::CreateService(
        hSCM, szServiceName, szServiceName,
        SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,//
        SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,//SERVICE_DEMAND_START
        szFilePath, NULL, NULL, _T(""), NULL, NULL);

二、

设置钩子:

hHook = ::SetWindowsHookEx(WH_GETMESSAGE,HookGetMsgProc,hInst,dwThreadID);

dwThreadID为0 设置全局钩子。

这种情况下是没有任何权限问题的,但是一旦你想注入指定的进程设置线程钩子,这个时候就会出现拒绝访问 的权限问题了,以我的程序为例:服务程序调用CreateProcess启动一个控制台程序,再由控制台程序来挂钩:

	if(!::CreateProcess(NULL,cFilePath,
	NULL,
	NULL,
	FALSE,
	0,
	NULL,
	NULL,
	&sInfo,
	&pInfo))

因为服务程序是执行的SYSTEM权限,由SYSTEM调用CreateProcess启动的控制台程序权限也是继承的服务程序的权限,所以也是SYSTEM权限

而桌面的程序都是用的Administrator权限,所以对桌面程序挂钩会访问失败(至于为什么全局钩子可以,这个没有去了解,待研究),所以,我就用了

explorer.exe进程的权限去启动控制台程序 CreateProcessAsUser

//枚举进程
DWORD Process(BOOL bExit)
{
	DWORD		lpidprocesses[1024],cbneeded,cprocesses;
	HANDLE		hprocess,hExplorer = NULL;
	HMODULE		hmodule;
	TCHAR		normalname[MAX_PATH]=_T("UnknownProcess");
	BOOL		bMonitor = FALSE;

	if(!EnumProcesses(lpidprocesses,sizeof(lpidprocesses),&cbneeded))
	{
		OutputDebugString(_T("EnumProcesses Error\n"));
		return -1;  
	}
	cprocesses=cbneeded/sizeof(DWORD);
	//
	for(UINT i=0;i<cprocesses;i++)
	{
		hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,lpidprocesses[i]);
		if(hprocess)
		{
			if(EnumProcessModules(hprocess,&hmodule,sizeof(hmodule),&cbneeded))
			{
				GetModuleBaseName(hprocess,hmodule,normalname,sizeof(normalname));
				if(_tcsicmp(normalname,szProcessname[0]) == 0)  
				{
					bMonitor = TRUE;
					dwMonitorProcessId = lpidprocesses[i];
					
				}
				else if (_tcsicmp(normalname,szProcessname[1]) == 0)
				{
					hExplorer = hprocess;
				}
			}
		}
	}

	//启动ABMonitor
	if (bMonitor == FALSE)
	{
		dwMonitorProcessId  = 0;
		TCHAR	szFilePath[MAX_PATH] = {0};
		TCHAR	cFilePath[MAX_PATH] = {0};
		GetAppPath(szFilePath);
		_tcscpy(cFilePath,_T("\""));
		_tcscat(cFilePath,szFilePath);
		_tcscat(cFilePath,_T("ABMonitor.exe\""));

		//清空结构
		STARTUPINFO sInfo;
		PROCESS_INFORMATION pInfo;
		ZeroMemory(&sInfo,sizeof(sInfo));
		sInfo.cb=sizeof(sInfo);
		sInfo.dwFlags=STARTF_USESHOWWINDOW;
		sInfo.wShowWindow=SW_SHOWNORMAL;
		ZeroMemory(&pInfo,sizeof(pInfo));

		//////////////////////////////////////////////////////////////////////////
		//用桌面账户启动ABMonitor,以Administrator身份,否则SYSTEM权限无法挂钩线程钩子
		//只能设置全局钩子
		if (hExplorer != NULL)
		{
			HANDLE hToken = NULL,hNewToken = NULL;
			if (OpenProcessToken(hExplorer,MAXIMUM_ALLOWED, &hToken))
			{
				if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,SecurityImpersonation, TokenPrimary, &hNewToken))
				{
					BOOL bRet = CreateProcessAsUser(hNewToken, NULL,cFilePath, NULL, NULL, FALSE,0, NULL, NULL, &sInfo, &pInfo);

					if(!bRet)
					{
						return -1;
					}

					CloseHandle(hNewToken);
				}
				CloseHandle(hToken);
			}
		}
	}

	CloseHandle(hprocess);
	return 0;
}


这样就可以控制台程序执行的就是Administrator权限了,SetWindowsHookEx 也可以正常执行了……


你可能感兴趣的:(服务-钩子-权限)