ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-GetTokenInformation返回的TOKEN_PRIVILEGES.LUID_AND_ATTRIBUTES数组的设置大小

2019-11-05 17:07:01  阅读:1963  来源: 互联网

标签:impersonation windows-xp marshalling privileges c


我正在尝试检索特权和它们与C#中的令牌相关联的当前状态,但我不知道如何调整返回的LUID_AND_ATTRIBUTES数组的大小以适合元素的实际数量.

MSDN

When MarshalAsAttribute.Value is set to ByValArray, the SizeConst must be set to indicate the number of elements in the array.

在调用GetTokenInformation之后,我能够查看TOKEN_PRIVILEGES.PrivilegeCount属性,并看到我正在使用的令牌具有Privilege Constants参考页面上列出的35个特权中的24个.更改SizeConst = 24将使我能够看到所有这些,而不仅仅是第一个
(根据PInvoke的用法示例,我最初设置SizeConst = 1)

有没有一种方法可以在创建传入数组时指定传入数组的深度,或者在编写代码之前我是否需要知道将要拥有多少特权?

代码段

[DllImport("advapi32.dll", SetLastError = true)]
protected static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)][return: MarshalAs(UnmanagedType.Bool)]
protected static extern bool LookupPrivilegeName(string lpSystemName, IntPtr lpLuid,System.Text.StringBuilder lpName, ref int cchName);

protected struct TOKEN_PRIVILEGES {
  public UInt32 PrivilegeCount;
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
  public LUID_AND_ATTRIBUTES[] Privileges;
}//TOKEN_PRIVILEGES

[StructLayout(LayoutKind.Sequential)]
protected struct LUID_AND_ATTRIBUTES {
  public LUID Luid;
  public UInt32 Attributes;
}//LUID_AND_ATTRIBUTES

[StructLayout(LayoutKind.Sequential)]
protected struct LUID {
  public uint LowPart;
  public int HighPart;
}//LUID

int TokenInfLength = 0;
IntPtr ThisHandle = WindowsIdentity.GetCurrent().Token;
GetTokenInformation(ThisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, TokenInfLength, ref TokenInfLength); //Get the TokenInformation length (returns false)
IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
if(GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenPrivileges, TokenInformation, TokenInfLength, ref TokenInfLength)){
  TOKEN_PRIVILEGES ThisPrivilegeSet = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_PRIVILEGES));
  //ThisPrivilegeSet now holds all of the LUID's i need to check out
  foreach(LUID_AND_ATTRIBUTES laa in ThisPrivilegeSet.Privileges){ //ThisPrivilegeSet.Privileges is only as deep as SizeConst will allow
    System.Text.StringBuilder StrBuilder = new System.Text.StringBuilder();
    int LuidNameLen = 0;
    IntPtr LuidPointer = Marshal.AllocHGlobal(Marshal.SizeOf(laa.Luid));
    Marshal.StructureToPtr(laa.Luid, LuidPointer, true);
    LookupPrivilegeName(null, LuidPointer, null, ref LuidNameLen); //Get the PrivilageName length (returns false)
    StrBuilder.EnsureCapacity(LuidNameLen + 1);
    if(LookupPrivilegeName(null, LuidPointer, StrBuilder, ref LuidNameLen)){ //StrBuilder gets the name this time
      Console.WriteLine("[{0}] : {1}", laa.Attributes.ToString(), StrBuilder.ToString());
    }//end if
    Marshal.FreeHGlobal(LuidPointer);
  }//next
}//end if

这是我的第一篇文章,对不起,如果我做错了,请向TIA寻求帮助

解决方法:

您将无法在运行时更改SizeConst,所以我认为最好的选择是检索尽可能多的内容,并仅使用所需的内容.这样,如果您需要其他信息,则以后无需更改代码.

因此,例如,如果最大特权数量为35,则将SizeConst设置为35.然后将foreach循环更改为for循环,并从i = 0转到ThisPrivilegeSet.PrivilegeCount.

这是一个示例(为此,我将SizeConst设置为8000):

  public void RunPrivileges()
  {
     int TokenInfLength = 0;
     IntPtr ThisHandle = WindowsIdentity.GetCurrent().Token;
     GetTokenInformation(ThisHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, TokenInfLength, ref TokenInfLength);
     IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
     if (GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenPrivileges, TokenInformation, TokenInfLength, ref TokenInfLength))
     {
        TOKEN_PRIVILEGES ThisPrivilegeSet = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_PRIVILEGES));
        for (int index = 0; index < ThisPrivilegeSet.PrivilegeCount; index++ )
        { 
           LUID_AND_ATTRIBUTES laa = ThisPrivilegeSet.Privileges[index];
           System.Text.StringBuilder StrBuilder = new System.Text.StringBuilder();
           int LuidNameLen = 0;
           IntPtr LuidPointer = Marshal.AllocHGlobal(Marshal.SizeOf(laa.Luid));
           Marshal.StructureToPtr(laa.Luid, LuidPointer, true);
           LookupPrivilegeName(null, LuidPointer, null, ref LuidNameLen);
           StrBuilder.EnsureCapacity(LuidNameLen + 1);
           if (LookupPrivilegeName(null, LuidPointer, StrBuilder, ref LuidNameLen))
           {
              Console.WriteLine("[{0}] : {1}", laa.Attributes.ToString(), StrBuilder.ToString());
           }
           Marshal.FreeHGlobal(LuidPointer);
        }
     }
  }

标签:impersonation,windows-xp,marshalling,privileges,c
来源: https://codeday.me/bug/20191105/1996477.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有