在目录“计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run”下写入test.exe
服务中注册一个exe自启动程序到HKEY_CURRENT_USER,比注册到HKEY_LOCAL_MACHINE要复杂一点。
首先要进行session切换,由服务所在session 0切换到当前用户账号下,虽然切换了,但是此时仍然是LocalSystem权限,仍然无法写入成功。还需要降低权限。
代码流程如下:
{
DWORD dwSessionId,dwExplorerLogonPid,dwSize,dwRegDataSize;
HANDLE hProcess,hPToken;
char szUserName[MAX_PATH];
char szRegData[MAX_PATH];
LPCTSTR szRegPath=L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
HKEY hKey; //Handle to registry Key
long lRegResult; //Registry operation result
DWORD dwDisposition;
//Get the active desktop session id
dwSessionId = WTSGetActiveConsoleSessionId();
//We find the explorer process since it will have the user token
//
// Find the explorer process
PROCESSENTRY32 procEntry;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
return 1 ;
}
procEntry.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnap, &procEntry))
{
return 1 ;
}
do
{
if (_tcsicmp(procEntry.szExeFile, TEXT("explorer.exe")) == 0)
{
DWORD dwExplorerSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &dwExplorerSessId)
&& dwExplorerSessId == dwSessionId)
{
dwExplorerLogonPid = procEntry.th32ProcessID;
break;
}
}
} while (Process32Next(hSnap, &procEntry));
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwExplorerLogonPid);
if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY
|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID
|TOKEN_READ|TOKEN_WRITE,&hPToken))
{
int abcd = GetLastError();
printf("Process token open Error: %u\n",GetLastError());
}
//Impersonate the explorer token which runs under the user account
ImpersonateLoggedOnUser(hPToken);
int iImpersonateResult = GetLastError();
if(iImpersonateResult == ERROR_SUCCESS)
{
//GetUserName will now return the username
GetUserName((LPWSTR)szUserName,&dwSize);
//Since the thread is running as the user we can access the HKCU now
dwRegDataSize = sizeof(szRegData);
lRegResult = RegOpenKeyEx(HKEY_CURRENT_USER,
szRegPath,0,KEY_QUERY_VALUE,&hKey);
if (lRegResult == ERROR_SUCCESS)
RegQueryValueEx(hKey,_T("SideBar"),NULL,NULL,
(LPBYTE)&szRegData,&dwRegDataSize);
}
LONG status = RegOpenCurrentUser(KEY_ALL_ACCESS, &hKey);
if (status != ERROR_SUCCESS) {
CloseHandle(hProcess);
}
//open startup intem Key
long lRet=RegCreateKeyEx(HKEY_CURRENT_USER,szRegPath,
0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&dwDisposition);
if (lRet==ERROR_SUCCESS)
{
wchar_t pFileName[MAX_PATH]={0};
//get path of LLVRService.exe
DWORD dwRet= ::GetModuleFileName(NULL,pFileName,MAX_PATH);
std::wstring str = pFileName;
int pos = (int)str.find_last_of(_T("\\"));
std::wstring DirPath = str.substr(0, pos);
std::wstring exepath = DirPath + _T("\\test.exe");
wchar_t pExePath[512] = { 0 };
//
lstrcpy(pExePath, exepath.c_str());
dwRet = wcslen(pExePath);
//add a key, and set value
lRet=RegSetValueEx(hKey,L"test",0,REG_SZ,(BYTE *)pExePath,dwRet*2);
//close reg
RegCloseKey(hKey);
// return TRUE;
}
//Once the operation is over revert back to system account.
RevertToSelf();
return TRUE;
}
注册成功:
-----------------------------------------2017/12/01
Note:
1. 自启动的程序不能要求管理员权限才能运行的程序。
2.HKEY_LOCAL_MACHINE下Run中创建子键在SYSTEM权限下也可以创建,不需要降权限。
-----------------------------------------2017/12/04
1.自启动exe被注册后,可以不再需要服务程序去启动。