更改正在运行的进程所有者C#

更改正在运行的进程所有者C#,c#,windows,process,C#,Windows,Process,是否可以更改已经启动的进程的所有者,最好在必要时使用C#/PInvoke 看起来SetSecurityInfo允许我这样做,但是每次调用函数都返回错误code 1307: 错误\u无效\u所有者 1307 (0x51B) This security ID may not be assigned as the owner of this object. 我不知道为什么我会收到这个,因为原始帐户和新所有者都是管理员帐户。UAC已禁用 我在谷歌的冒险经历让我相信我需要设置特权,但这似乎没有改变任何

是否可以更改已经启动的进程的所有者,最好在必要时使用
C#/PInvoke

看起来
SetSecurityInfo
允许我这样做,但是每次调用函数都返回错误
code 1307

错误\u无效\u所有者

1307 (0x51B)

This security ID may not be assigned as the owner of this object.
我不知道为什么我会收到这个,因为原始帐户和新所有者都是管理员帐户。UAC已禁用

我在谷歌的冒险经历让我相信我需要设置特权,但这似乎没有改变任何事情。以下是我迄今为止尝试过的代码:

SecurityIdentifier userSid = getUserSid("Test");

Process proc = Process.GetCurrentProcess();
IntPtr procHandle = proc.Handle;

byte[] bytes = new byte[userSid.BinaryLength];
userSid.GetBinaryForm(bytes, 0);

GCHandle pinnedArray = GCHandle.Alloc(bytes, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();

SetPrivilege("SeTakeOwnershipPrivilege");
SetPrivilege("SeRestorePrivilege");

uint result = SetSecurityInfo(procHandle, SE_OBJECT_TYPE.SE_KERNEL_OBJECT, SECURITY_INFORMATION.Owner, pointer, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

pinnedArray.Free();
getUserSid():

SetPrivilege():

private静态void SetPrivilege(字符串特权)
{
int i1=0;
var luid=新的luid();
var token_PRIVILEGES=新的token_PRIVILEGES();
int i2=OpenProcessToken(GetCurrentProcess(),40,参考i1);
如果(i2==0)
抛出新异常(“特权的OpenProcessToken失败”);
i2=LookupPrivilegeValue(null,privilege,ref-luid);
如果(i2==0)
抛出新异常(“LookupPrivilegeValue For Privilege失败”);
token_PRIVILEGES.PrivilegeCount=1;
token_PRIVILEGES.Attributes=2;
token_PRIVILEGES.Luid=Luid;
i2=AdjustTokenPrivileges(i1,0,ref-token_PRIVILEGES,1024,0,0);
如果(i2==0)
抛出新异常(“AdjustTokenPrivileges For Privilege Failed”);
}

我已经验证了调试过程中使用的SID是否符合预期。我还尝试了
handle.MainWindowHandle
,但这实际上导致了错误代码6(无效的窗口句柄)。我不太确定Pinnedaray代码。它似乎按预期工作。

尝试启用备份权限和还原权限。并检查特权是否已实际启用(如果令牌中不存在特权,则AdjustTokenPrivileges不会返回错误代码)。但也有可能您根本无法更改流程对象的所有权。这有什么用处?我想知道流程是否由系统帐户启动,是否可以分配给真正的用户。作为替代方案,进程启动时的模拟情况如何?似乎
proc.Handle
是当前进程伪句柄,这对SetSecurityInfo无效。你可以通过复制它来获得真正的控制。PS-您可以通过设置简单对象(如文件)的所有权来测试固定数组代码。
private SecurityIdentifier getUserSid(string userName)
{
    // set up machine context
    PrincipalContext ctx = new PrincipalContext(ContextType.Machine);

    // find a user
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "Test");

    if (user != null)
    {
        return user.Sid;
    }
    return null;
}
private static void SetPrivilege(string privilege)
{
    int i1 = 0;
    var luid = new LUID();
    var token_PRIVILEGES = new TOKEN_PRIVILEGES();
    int i2 = OpenProcessToken(GetCurrentProcess(), 40, ref i1);
    if (i2 == 0)
        throw new Exception("OpenProcessToken For Privilege <" + privilege + "> Failed");
    i2 = LookupPrivilegeValue(null, privilege, ref luid);
    if (i2 == 0)
        throw new Exception("LookupPrivilegeValue For Privilege <" + privilege + "> Failed");
    token_PRIVILEGES.PrivilegeCount = 1;
    token_PRIVILEGES.Attributes = 2;
    token_PRIVILEGES.Luid = luid;
    i2 = AdjustTokenPrivileges(i1, 0, ref token_PRIVILEGES, 1024, 0, 0);
    if (i2 == 0)
        throw new Exception("AdjustTokenPrivileges For Privilege <" + privilege + "> Failed");
}