Skip to content

Commit 17b49be

Browse files
committed
fix buffer size overflow in CreateProcessAsTrustedInstaller (#127)
1 parent 9aac486 commit 17b49be

1 file changed

Lines changed: 27 additions & 24 deletions

File tree

.Source/GTweak/Utilities/Helpers/TrustedInstaller.cs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ internal sealed class TrustedInstaller
4444

4545
[DllImport("kernel32.dll", SetLastError = true)]
4646
[return: MarshalAs(UnmanagedType.Bool)]
47-
private static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
47+
private static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, UIntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
4848

4949
[DllImport("kernel32.dll", SetLastError = true)]
5050
[return: MarshalAs(UnmanagedType.Bool)]
51-
private static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
51+
private static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref UIntPtr lpSize);
5252

5353
[DllImport("kernel32.dll", SetLastError = true)]
5454
private static extern void DeleteProcThreadAttributeList(IntPtr lpAttributeList);
@@ -63,7 +63,7 @@ internal sealed class TrustedInstaller
6363
private const int SC_STATUS_PROCESS_INFO = 0;
6464
private const string ServicesActiveDatabase = "ServicesActive";
6565

66-
private const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
66+
private const uint PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
6767
private const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
6868

6969
[StructLayout(LayoutKind.Sequential)]
@@ -244,15 +244,18 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
244244
Exception lastException = null;
245245
bool impersonated = false;
246246

247+
UIntPtr lpSize = UIntPtr.Zero;
248+
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
249+
if (lpSize == UIntPtr.Zero)
250+
{
251+
throw new Win32Exception("InitializeProcThreadAttributeList returned zero size");
252+
}
253+
247254
for (int attempt = 0; attempt < 3; attempt++)
248255
{
249-
STARTUPINFOEX siEx = new STARTUPINFOEX();
250-
IntPtr lpSize = IntPtr.Zero;
251256
IntPtr lpValueProc = IntPtr.Zero;
252257
IntPtr parentHandle = IntPtr.Zero;
253-
254-
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
255-
siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
258+
IntPtr attributeList = IntPtr.Zero;
256259

257260
try
258261
{
@@ -266,12 +269,15 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
266269
throw new Win32Exception("Failed to impersonate SYSTEM identity");
267270
}
268271

269-
if (!InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, ref lpSize))
272+
attributeList = Marshal.AllocHGlobal((IntPtr)(long)lpSize);
273+
274+
if (!InitializeProcThreadAttributeList(attributeList, 1, 0, ref lpSize))
270275
{
271276
throw new Win32Exception(Marshal.GetLastWin32Error());
272277
}
273278

274-
parentHandle = OpenProcess(ProcessAccessFlags.CreateProcess | ProcessAccessFlags.DuplicateHandle, false, parentProcessId);
279+
parentHandle = OpenProcess(ProcessAccessFlags.CreateProcess | ProcessAccessFlags.DuplicateHandle | ProcessAccessFlags.Synchronize, false, parentProcessId);
280+
275281
if (parentHandle == IntPtr.Zero)
276282
{
277283
throw new Win32Exception(Marshal.GetLastWin32Error());
@@ -280,22 +286,19 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
280286
lpValueProc = Marshal.AllocHGlobal(IntPtr.Size);
281287
Marshal.WriteIntPtr(lpValueProc, parentHandle);
282288

283-
if (!UpdateProcThreadAttribute(siEx.lpAttributeList, 0, (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, lpValueProc, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero))
289+
if (!UpdateProcThreadAttribute(attributeList, 0, new IntPtr(unchecked(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS)), lpValueProc, new UIntPtr((uint)IntPtr.Size), IntPtr.Zero, IntPtr.Zero))
284290
{
285291
throw new Win32Exception(Marshal.GetLastWin32Error());
286292
}
287293

288-
SECURITY_ATTRIBUTES ps = new SECURITY_ATTRIBUTES();
289-
SECURITY_ATTRIBUTES ts = new SECURITY_ATTRIBUTES();
290-
ps.nLength = Marshal.SizeOf(ps);
291-
ts.nLength = Marshal.SizeOf(ts);
294+
STARTUPINFOEX siEx = new STARTUPINFOEX();
295+
siEx.StartupInfo.cb = Marshal.SizeOf(typeof(STARTUPINFOEX));
296+
siEx.StartupInfo.dwFlags = 0x00000001;
297+
siEx.StartupInfo.wShowWindow = showWindow ? (short)5 : (short)0;
298+
siEx.lpAttributeList = attributeList;
292299

293-
siEx.StartupInfo = new STARTUPINFO
294-
{
295-
cb = Marshal.SizeOf(typeof(STARTUPINFO)),
296-
dwFlags = 0x00000001,
297-
wShowWindow = showWindow ? (short)5 : (short)0
298-
};
300+
SECURITY_ATTRIBUTES ps = new SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) };
301+
SECURITY_ATTRIBUTES ts = new SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) };
299302

300303
if (!CreateProcess(null, binaryPath, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref siEx, out PROCESS_INFORMATION pInfo))
301304
{
@@ -322,10 +325,10 @@ internal static void CreateProcessAsTrustedInstaller(int parentProcessId, string
322325
CloseHandle(parentHandle);
323326
}
324327

325-
if (siEx.lpAttributeList != IntPtr.Zero)
328+
if (attributeList != IntPtr.Zero)
326329
{
327-
DeleteProcThreadAttributeList(siEx.lpAttributeList);
328-
Marshal.FreeHGlobal(siEx.lpAttributeList);
330+
DeleteProcThreadAttributeList(attributeList);
331+
Marshal.FreeHGlobal(attributeList);
329332
}
330333
}
331334
}

0 commit comments

Comments
 (0)