我试图通过使用C#代码将内存地址解析为权限,将以下X64位编译为X64位。
namespace ConsoleApp2
{
public class Program
{
//Open Process Token Starts Here
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
public const UInt32 TOKEN_DUPLICATE = 0x0002;
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
public const UInt32 TOKEN_QUERY = 0x0008;
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle);
//Open Prcoess Token Ends Here
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public uint HighPart;
}
public struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public LUID_AND_ATTRIBUTES[] Privileges;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public UInt32 Attributes;
}
//Token Privileges
//GetTokenInformation Starts Here
enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
TokenIsAppContainer,
TokenCapabilities,
TokenAppContainerSid,
TokenAppContainerNumber,
TokenUserClaimAttributes,
TokenDeviceClaimAttributes,
TokenRestrictedUserClaimAttributes,
TokenRestrictedDeviceClaimAttributes,
TokenDeviceGroups,
TokenRestrictedDeviceGroups,
TokenSecurityAttributes,
TokenIsRestricted,
TokenProcessTrustLevel,
TokenPrivateNameSpace,
TokenSingletonAttributes,
TokenBnoIsolation,
TokenChildProcessFlags,
TokenIsLessPrivilegedAppContainer,
TokenIsSandboxed,
TokenIsAppSilo,
MaxTokenInfoClass
}
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, long TokenInformationLength, ref long ReturnLength);
//GetTokenInformation Ends Here
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LookupPrivilegeName(
string lpSystemName,
IntPtr lpLuid,
[param: MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpName,
ref long cchName);
public static void Main()
{
IntPtr hwnd = Process.GetCurrentProcess().Handle;
IntPtr TokenHandle = IntPtr.Zero;
OpenProcessToken(hwnd, TOKEN_READ, ref TokenHandle);
long ReturnLength = 0;
GetTokenInformation(TokenHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, 0, ref ReturnLength);
IntPtr elevationptr = Marshal.AllocHGlobal(64);
long TokenInformationLength = 64;
GetTokenInformation(TokenHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, elevationptr, TokenInformationLength, ref TokenInformationLength);
TOKEN_PRIVILEGES tp = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(elevationptr, typeof(TOKEN_PRIVILEGES));
IntPtr startingptr = new IntPtr(elevationptr.ToInt64() + sizeof(uint));
for (int i = 0; i < tp.PrivilegeCount; i++)
{
IntPtr tempptr = new IntPtr(startingptr.ToInt64() + i * Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)));
LUID_AND_ATTRIBUTES laa = (LUID_AND_ATTRIBUTES)Marshal.PtrToStructure(tempptr, typeof(LUID_AND_ATTRIBUTES));
IntPtr luidptr = Marshal.AllocHGlobal(Marshal.SizeOf(laa.Luid));
Marshal.StructureToPtr(laa.Luid, luidptr, true);
StringBuilder sb = new StringBuilder(50);
long cchname = 50;
// Console.WriteLine("[1]LUIDPTR: {0}", luidptr);
LookupPrivilegeName(null, luidptr, sb, ref cchname);
//Console.WriteLine("[2]cchname: {0}", cchname);
Console.WriteLine(sb);
Marshal.FreeHGlobal(luidptr);
}
Console.Read();
}
}
}
虽然"tp.PrivilegeCount“是5,但是程序在第三循环中崩溃。
通过使用断点进行调试,发现LookupPrivilegeName试图访问"luidptr“内存地址,但由于以下错误而被阻塞-
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
这显然是内存分配问题,但我不知道我遗漏了什么。
编辑:--我已经更新了程序在X64 arch上工作的代码,但是一旦尝试,它就会崩溃/打印所有特权/不打印任何内容。
发布于 2022-07-24 04:55:30
您需要为SizeParamIndex
声明StringBuilder
。您可以将lpLuid
作为in
参数传递。
cchName
应该是ref int
。SafeProcessHandle
表示OpenProcessToken
。using
和try
finally
,也需要把Marshal.GetLastWin32Error()
扔到需要的地方。64
代替ReturnLength
TOKEN_PRIVILEGES
结构是浪费时间的,因为它是动态大小的。由于您正在手动编组它,您还可以使用ReadInt32
。PtrToStructure
的泛型形式。[DllImport("advapi32.dll", SetLastError = true)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out SafeProcessHandle TokenHandle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool LookupPrivilegeName(
[MarshalAs(UnmanagedType.LPTStr)] string lpSystemName,
in LUID lpLuid,
[Out, MarshalAs(UnmanagedType.LPTStr, SizeParamIndex = 3)] StringBuilder lpName,
ref int cchName);
以下是更新的代码:
public static void Main()
{
IntPtr hwnd = Process.GetCurrentProcess().Handle;
SafeProcessHandle TokenHandle;
OpenProcessToken(hwnd, TOKEN_READ, out TokenHandle);
if(TokenHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
using(TokenHandle)
{
if(!GetTokenInformation(TokenHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, 0, out var ReturnLength))
throw new Win32Exception(Marshal.GetLastWin32Error());
IntPtr elevationptr = IntPtr.Zero;
try
{
elevationptr = Marshal.AllocHGlobal(ReturnLength);
if(!GetTokenInformation(TokenHandle, TOKEN_INFORMATION_CLASS.TokenPrivileges, elevationptr, ReturnLength, out var ReturnLength))
throw new Win32Exception(Marshal.GetLastWin32Error());
var startingptr = new IntPtr(elevationptr.ToInt64() + sizeof(uint));
var count = Marshal.ReadInt32(elevationptr);
for (int i = 0; i < count; i++)
{
var tempptr = new IntPtr(startingptr.ToInt64() + i * Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)));
var laa = Marshal.PtrToStructure<LUID_AND_ATTRIBUTES>(tempptr);
var sb = new StringBuilder(50);
int cchname = sb.Length;
// Console.WriteLine("[1]LUIDPTR: {0}", luidptr);
if(!LookupPrivilegeName(null, in luidptr, sb, ref cchname))
throw new Win32Exception(Marshal.GetLastWin32Error());
//Console.WriteLine("[2]cchname: {0}", cchname);
Console.WriteLine(sb);
}
}
finally
{
Marshal.FreeHGlobal(elevationptr);
}
}
Console.Read();
}
https://stackoverflow.com/questions/73086803
复制相似问题