#include "stdafx.h"
/*
runas是一个常用的命令,你会用吗?
我不会,但我要探究它的进一步的原理。
其实很简单,参见:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx
注意事项:见注释。
不过要在不同的会话中运行,那就麻烦了。
普通的程序需要提权。
而进程的权限是继承自用户的,所以还要给用户分派权限。
具体的设置可以参考本地安全策略:http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/08bc7712-548c-4308-a49c-d551a4b5e245.mspx?mfr=true。
注意:这些设置还要重启后生效。
所以常用的办法是用服务,服务默认是具有这些权限的。再次郑重说明:不用服务也是可以的。
正好这有解决了服务在Vista及以后系统的编程交互(如:弹出对话框)的问题。
提示:命令行输入空的参数,可以使用双引号,也就是这两个引号之间没有内容,包括空格。
made by correy
made at 2014.05.17
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
#include <windows.h>
#include <stdio.h>
#include <userenv.h>
#pragma comment(lib, "userenv.lib")
void DisplayError(LPWSTR pszAPI)
{
LPVOID lpvMessageBuffer;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpvMessageBuffer, 0, NULL);
//... now display this string
wprintf(L"ERROR: API = %s.\n", pszAPI);
wprintf(L" error code = %d.\n", GetLastError());
wprintf(L" message = %s.\n", (LPWSTR)lpvMessageBuffer);
LocalFree(lpvMessageBuffer);// Free the buffer allocated by the system
ExitProcess(GetLastError());
}
void wmain(int argc, WCHAR *argv[])
{
if (argc != 4)
{
wprintf(L"Usage: %s [user@domain] [password] [cmd]", argv[0]);
wprintf(L"\n\n");
return;
}
// TO DO: change NULL to '.' to use local account database
HANDLE hToken;
if (!LogonUser(argv[1], NULL, argv[2], LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) { //必须有密码,不然失败。
DisplayError(L"LogonUser");
}
//得到的内容其实就是:The environment block is an array of null-terminated Unicode strings. The list ends with two nulls (\0\0).
LPVOID lpvEnv;
if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) {
DisplayError(L"CreateEnvironmentBlock");
}
//获取用户的文件夹。
WCHAR szUserProfile[256] = L"";
DWORD dwSize = sizeof(szUserProfile)/sizeof(WCHAR);
if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize)) {//用户必须登录运行过一次,不必此时这个用户运行着。
DisplayError(L"GetUserProfileDirectory");
}
// TO DO: change NULL to '.' to use local account database
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi = {0};
if (!CreateProcessWithLogonW(argv[1], NULL, argv[2], LOGON_WITH_PROFILE, NULL, argv[3], CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile, &si, &pi)) {
DisplayError(L"CreateProcessWithLogonW");
}
if (!DestroyEnvironmentBlock(lpvEnv)) {
DisplayError(L"DestroyEnvironmentBlock");
}
CloseHandle(hToken);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
2014年5月17日星期六
以另一个用户启动一个进程
订阅:
博文评论 (Atom)
没有评论:
发表评论