子进程 保护地址空间 运行独立的子进程 管理员以标准用户权限运行时
2013-05-09 16:30
453 查看
为了增加程序的运行效率 一项复杂的功能往往需要创建一个新的线程或者进程 帮助我们完成复杂的工作 但是在一个进程中创建一个线程 会遇到同步的问题 也就是说当主线程需要得到新创建线程运行的结果的时候 会遇到同步问题
但是即使这样 依然会有问题 就是新创建的进程能访问父进程的地址空间 这样就有可能子进程的某些操作改变父进程地址空间中一些重要的数据 为了能让新创建的新进程“老老实实,规规矩矩”的完成自己的工作 我们需要做的就是在程序运行期间保护父进程的地址空间
保护地址空间
这种做法其实很简单 就是控制子进程能访问父进程地址空间的数据 也就是说 让子进程在自己的地址空间中运行 需要的数据由父进程通过多种方式传递或者共享给子进程(动态数据交换,OLE,管道,邮件槽,内存映射文件)
WaitForStringObject
这个函数会一直等待 等待进程对象的终止的时候 所以这个函数的功能其实就是暂停父进程的一切操作给子进程“让路” 直到子进程做完一切操作
运行独立的子进程
像windows的资源管理器一样 当它创建一个新的进程之后 就不再管这个新创建出来的进程做什么操作或者是什么时间结束 所以一般我们需要创建出来的父进程和子进程之间不再相互通信 父进程需要调用CloseHandle来关闭新进程或者其主线程的句柄
Vista 之前的系统,当用户使用管理员账户登录时,一个安全令牌会被创建,之后操作系统访问一些安全资源时会用到它,由 Windows Explorer 开始,这个安全令牌会同新创建的进程关联,进而也影响到它们的子进程。恶意软件也会使用这个安全令牌运行,它就能访问到任意的资源。
从 Windows Vista 开始,如果一个用户作为系统管理员登录,除了相应的安全令牌创建之外,还创建了一个受限令牌(Filtered token),这个令牌仅有标准用户的权限。从 Windows Explorer 开始,受限令牌与每一个新创建的进程相关联,如果一个用户要访问高安全的资源时,必须告诉操作系统提升权限,且只是在这个进程边界中执行,也就是说必须在进程开始之前申请,这就是用户账户控制。
如果一个应用程序必须使用管理员权限运行,比如程序的安装进程,每次你的应用程序运行时操作系统会自动提示用户进行权限提升。
可执行文件中如果被发现嵌入了一个特定类型的资源(RT_MANIFEST),那么系统会查找 <trustInfo> 部分并解析它的内容,以下是一个清单文件的一部分:
?
另一种方法是将这部分内容放到一个后缀为 .manifest 的文件中,并将这个文件置于可执行文件相同的目录中。
除了使用清单文件外,系统还使用一组特定的规则将一个可执行文件识别为设置程序。
CreateProcess 函数中没有选项与提升权限有关,用户可以使用 ShellExecuteEx(LPSHELLEXECUTEINFO pExecInfo) 函数手动申请一个进程提高执行权限,如果用户拒绝权限提升,ShellExecuteEx 返回 FALSE,GetLastError 返回 ERROR_CANCELLED。SHELLEXECUTEINFO 成员 lpVerb 必须设置为 “runas”,lpFile 成员包含要求提升权限的可执行文件的路径。一旦一个进程以提升的权限运行,它随后使用
CreateProcess 创建的子进程都会以相同的权限的执行,可是如果一个使用受限令牌启动的进程试图创建一个需要提升权限的进程,CreateProcess 会失败,GetLastError 返回 ERROR_ELEVATION_REQUIRED
BOOL ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo
);
typedef struct _SHELLEXECUTEINFO{
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
// Optional members
LPVOID lpIDList;
LPCSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
};
HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
这个结构体唯一有趣的2个字段是lpVerb和lpFile,前者必须被设置为"runas",后者必须包含使用提升后的权限来启动的一个可执行文件的路径,如下代码:
SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)};
sei.lpVerb = TEXT("runas");
sei.lpFile = TEXT("cmd.exe");
sei.nShow = SW_NORMAL;
if (!ShellExecuteEx(&sei))
{
DWORD dwStatus = GetLastError();
if (dwStatus == ERROR_CANCELLED)
{
printf("没有以管理员权限运行");
}
else
if(dwStatus == ERROR_FILE_NOT_FOUND)
{
printf("没有找到该文件");
}
}
但是即使这样 依然会有问题 就是新创建的进程能访问父进程的地址空间 这样就有可能子进程的某些操作改变父进程地址空间中一些重要的数据 为了能让新创建的新进程“老老实实,规规矩矩”的完成自己的工作 我们需要做的就是在程序运行期间保护父进程的地址空间
保护地址空间
这种做法其实很简单 就是控制子进程能访问父进程地址空间的数据 也就是说 让子进程在自己的地址空间中运行 需要的数据由父进程通过多种方式传递或者共享给子进程(动态数据交换,OLE,管道,邮件槽,内存映射文件)
WaitForStringObject
这个函数会一直等待 等待进程对象的终止的时候 所以这个函数的功能其实就是暂停父进程的一切操作给子进程“让路” 直到子进程做完一切操作
运行独立的子进程
像windows的资源管理器一样 当它创建一个新的进程之后 就不再管这个新创建出来的进程做什么操作或者是什么时间结束 所以一般我们需要创建出来的父进程和子进程之间不再相互通信 父进程需要调用CloseHandle来关闭新进程或者其主线程的句柄
Vista 之前的系统,当用户使用管理员账户登录时,一个安全令牌会被创建,之后操作系统访问一些安全资源时会用到它,由 Windows Explorer 开始,这个安全令牌会同新创建的进程关联,进而也影响到它们的子进程。恶意软件也会使用这个安全令牌运行,它就能访问到任意的资源。
从 Windows Vista 开始,如果一个用户作为系统管理员登录,除了相应的安全令牌创建之外,还创建了一个受限令牌(Filtered token),这个令牌仅有标准用户的权限。从 Windows Explorer 开始,受限令牌与每一个新创建的进程相关联,如果一个用户要访问高安全的资源时,必须告诉操作系统提升权限,且只是在这个进程边界中执行,也就是说必须在进程开始之前申请,这就是用户账户控制。
自动提升一个进程的权限
如果一个应用程序必须使用管理员权限运行,比如程序的安装进程,每次你的应用程序运行时操作系统会自动提示用户进行权限提升。可执行文件中如果被发现嵌入了一个特定类型的资源(RT_MANIFEST),那么系统会查找 <trustInfo> 部分并解析它的内容,以下是一个清单文件的一部分:
?
除了使用清单文件外,系统还使用一组特定的规则将一个可执行文件识别为设置程序。
手动提升进程权限
CreateProcess 函数中没有选项与提升权限有关,用户可以使用 ShellExecuteEx(LPSHELLEXECUTEINFO pExecInfo) 函数手动申请一个进程提高执行权限,如果用户拒绝权限提升,ShellExecuteEx 返回 FALSE,GetLastError 返回 ERROR_CANCELLED。SHELLEXECUTEINFO 成员 lpVerb 必须设置为 “runas”,lpFile 成员包含要求提升权限的可执行文件的路径。一旦一个进程以提升的权限运行,它随后使用CreateProcess 创建的子进程都会以相同的权限的执行,可是如果一个使用受限令牌启动的进程试图创建一个需要提升权限的进程,CreateProcess 会失败,GetLastError 返回 ERROR_ELEVATION_REQUIRED
BOOL ShellExecuteEx(
LPSHELLEXECUTEINFO lpExecInfo
);
typedef struct _SHELLEXECUTEINFO{
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
// Optional members
LPVOID lpIDList;
LPCSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
};
HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
这个结构体唯一有趣的2个字段是lpVerb和lpFile,前者必须被设置为"runas",后者必须包含使用提升后的权限来启动的一个可执行文件的路径,如下代码:
SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)};
sei.lpVerb = TEXT("runas");
sei.lpFile = TEXT("cmd.exe");
sei.nShow = SW_NORMAL;
if (!ShellExecuteEx(&sei))
{
DWORD dwStatus = GetLastError();
if (dwStatus == ERROR_CANCELLED)
{
printf("没有以管理员权限运行");
}
else
if(dwStatus == ERROR_FILE_NOT_FOUND)
{
printf("没有找到该文件");
}
}
相关文章推荐
- 管理员以标准用户权限运行时
- VC 判断进程是否是以管理员权限运行,并且判断是否是用户进程而非服务进程
- 用户是否是用管理员权限运行本进程
- 2.1 Windows核心编程-进程UAC下以管理员权限运行
- 一个进程是否以管理员权限运行
- System.UnauthorizedAccessException: 拒绝访问 temp 目录。用来运行 XmlSerializer 的标识“NT AUTHORITY\NETWORK SERVICE”没有访问 temp 目录的足够权限。CodeDom 将使用进程正在使用的用户帐户进行编译,这样,如
- Linux添加管理员权限用户 进程命令
- 以指定用户权限运行一个进程
- 管理员以标准权限运行时
- BAT-把当前用户以管理员权限运行
- 判断当前进程是否以管理员权限运行
- 以指定用户权限运行一个进程
- Windows via C/C++ 学习(11)管理员用户作为标准用户运行
- win7给标准用户授予管理员权限的问题
- System.UnauthorizedAccessException: 拒绝访问 temp 目录。用来运行 XmlSerializer 的标识“NT AUTHORITY\NETWORK SERVICE”没有访问 temp 目录的足够权限。CodeDom 将使用进程正在使用的用户帐户进行编译,这样,如
- BAT-把当前用户以管理员权限运行(用户帐户控制:用于内置管理员帐户的管理员批准模式)
- 判断当前进程是否以管理员权限运行(AllocateAndInitializeSid后,用CheckTokenMembership与AdministratorsGroup进行比较,和Delphi的那个例子还有点不一样)
- vc 判断当前用户是否在管理员组以及是否SYSTEM权限运行
- 管理员权限程序以普通用户的权限运行不需要管理员权限的程序
- 利用ShellExecuteEx手动提升用户特权,以管理员权限来运行程序。win7会有UAC弹窗