6 votes

C# - AdjustTokenPrivileges ne fonctionne pas sur 32bit

J'essaie d'obtenir un privilège dans mon application C# .NET 4. Ce code fonctionne et le privilège est obtenu avec succès, mais uniquement sur les systèmes 64bit. Lorsque le même code est exécuté sur un système 32 bits, il échoue à AdjustTokenPrivileges avec cette exception :

Accès non valide à l'emplacement de la mémoire. (Exception de HRESULT : 0x800703E6)

J'ai essayé de modifier le code pour résoudre le problème, mais rien ne fonctionne et je suis assez perplexe.

Une idée de la raison pour laquelle ce système échoue sur les systèmes 32bit ? Il échoue à la fois sur Windows Vista et 7 32bit, il s'agit donc d'un problème spécifique aux systèmes 32bit.

Mise à jour avec le code correct en 2022. Le code ci-dessous est maintenant correct et peut être utilisé dans votre application.

La méthode :

public static void EnableDisablePrivilege(string PrivilegeName, bool EnableDisable)
{
    if (!LookupPrivilegeValue(null, PrivilegeName, out var luid)) throw new Exception($"EnableDisablePrivilege: LookupPrivilegeValue failed: {Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");

    if (!OpenProcessToken(Process.GetCurrentProcess().SafeHandle, TokenAccessLevels.AdjustPrivileges, out var tokenHandle)) throw new Exception($"EnableDisablePrivilege: OpenProcessToken failed: {Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");

    var tokenPrivileges = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Privileges = new[] { new LUID_AND_ATTRIBUTES { LUID = luid, Attributes = (uint)(EnableDisable ? 2 : 4) } } };
    if (!AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, 0, IntPtr.Zero, out _))
    {
        tokenHandle.Dispose();
        throw new Exception($"EnableDisablePrivilege: AdjustTokenPrivileges failed: {Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");
    }
    else tokenHandle.Dispose();
}

Mise en œuvre :

EnableDisablePrivilege("SeManageVolumePrivilege", true);

Déclarations PInvoke :

[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
    private uint lowPart;
    private int highPart;

    public uint LowPart { get => lowPart; set => lowPart = value; }

    public int HighPart { get => highPart; set => highPart = value; }
}

[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
    private LUID luid;
    private uint attributes;

    public LUID LUID { get => luid; set => luid = value; }

    public uint Attributes { get => attributes; set => attributes = value; }
}

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
    private uint privilegeCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    private LUID_AND_ATTRIBUTES[] privileges;

    public uint PrivilegeCount { get => privilegeCount; set => privilegeCount = value; }

    public LUID_AND_ATTRIBUTES[] Privileges { get => privileges; set => privileges = value; }
}

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool OpenProcessToken(SafeProcessHandle ProcessHandle, TokenAccessLevels DesiredAccess, out SafeAccessTokenHandle TokenHandle);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AdjustTokenPrivileges(SafeAccessTokenHandle TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, out uint ReturnLength);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);

4voto

Eaton Points 367

Corrigé, il fallait juste mettre un ref avant NewState :

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint Bufferlength, IntPtr PreviousState, IntPtr ReturnLength);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X