如何使用Win32 API模拟现有过程?

时间:2019-06-18 17:02:52

标签: authentication winapi process win32-process

我希望使用每个登录用户的凭据在不同的进程中运行应用程序,而不用Win32 API CreateProcessAsUserA()创建全新的进程,因为启动该应用程序大约需要一分钟的时间,因此这是不可接受的性能。

  • 计划A::在用户请求进入之前,先启动一些站立流程。使用给定的用户凭据模拟现有流程。
    该怎么做?

  • 计划B:我愿意听到其他想法。

2 个答案:

答案 0 :(得分:0)

没有记录/未记录的方法来实现您的要求。有一种破解方法,但是会严重危害安全性。

如果您有权模拟其他用户,则意味着您的进程在Windows中以最高特权运行。您可以做的是

  1. 流程A创建具有与流程A相同权限的流程B(需要花费一些时间启动)的多个副本。因此,流程B本质上也具有模拟权限。
  2. 进程B将建立进程A可以写入的LPC机制(管道/套接字/其他)。进程B将无限期等待,直到它接收到来自进程A的请求。
  3. 请求进入时,进程A将获取用户信息,并使用LPC机制将其传递给进程B。
  4. 然后,流程B将模拟用户并执行任务并终止。

在任何情况下,都不应在零售产品中使用此方法,因为这是一种hack,可以根据流程B的执行情况轻易加以利用。如果您打算使用这种黑客工具来运送产品,请告诉我们名称,以便我们不要使用它。

答案 1 :(得分:0)

如果您的进程只有一个线程或没有很多线程,则可以使用SetThreadToken

  • 首先,使用LogonUserA或其他一些功能来获取用户令牌。
  • 然后,DuplicateToken将其转换为模拟令牌。
  • 获取线程句柄,最后调用SetThreadToken

这是一个简单的示例。(已经删除了为简洁起见而进行的错误检查)

现有过程:

#include <windows.h>
#include <iostream>
using namespace std;
int main(void)
{
    cout << GetCurrentThreadId() << endl;//For example: I get currentthreadid = 17608 this time.
    getchar();
    char user[100] = { 0 };
    DWORD size = 100;
    GetUserNameA(user, &size);
    cout << user << endl;
    getchar();
    return 0;
}

SetThreadToken.cpp:

#include <windows.h>
#include <iostream>
using namespace std;
int main(void)
{
    HANDLE hToken, DToken;
    BOOL i = LogonUserA("user","domain","password", LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT,&hToken);
    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,false,17608);
    DuplicateToken(hToken, SecurityImpersonation,&DToken);
    SetThreadToken(&hThread, DToken);
    getchar();
    return 0;
}

如果要为该进程设置令牌,则NtSetInformationProcess中有未记录的方法ntdll.dll,请尝试this question中的答案来设置进程访问令牌。