Code:
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint ResumeThread(IntPtr hThread);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll")]
private static extern bool Thread32First(IntPtr hSnapshot, ref THREADENTRY32 lppe);
[DllImport("kernel32.dll")]
private static extern bool Thread32Next(IntPtr hSnapshot, ref THREADENTRY32 lppe);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("ntdll.dll")]
private static extern uint NtQueryInformationThread(IntPtr handle, uint infclass, ref THREAD_BASIC_INFORMATION info, uint length, IntPtr bytesread);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint GetSecurityInfo(
IntPtr handle,
_SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
out IntPtr pSidOwner,
out IntPtr pSidGroup,
out IntPtr pDacl,
out IntPtr pSacl,
out IntPtr pSecurityDescriptor);
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint SetSecurityInfo(
IntPtr handle,
_SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
out IntPtr pSidOwner,
out IntPtr pSidGroup,
out IntPtr pDacl,
out IntPtr pSacl,
out IntPtr pSecurityDescriptor);
enum SECURITY_INFORMATION
{
DACL_SECURITY_INFORMATION,
LABEL_SECURITY_INFORMATION,
GROUP_SECURITY_INFORMATION,
OWNER_SECURITY_INFORMATION,
PROTECTED_DACL_SECURITY_INFORMATION,
PROTECTED_SACL_SECURITY_INFORMATION,
SACL_SECURITY_INFORMATION,
UNPROTECTED_DACL_SECURITY_INFORMATION,
UNPROTECTED_SACL_SECURITY_INFORMATION
};
enum _SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY ,
SE_OBJECT_TYPE,
};
[StructLayout(LayoutKind.Sequential)]
private struct THREADENTRY32
{
public UInt32 dwSize;
public UInt32 cntUsage;
public UInt32 th32ThreadID;
public UInt32 th32OwnerProcessID;
public Int32 tpBasePri;
public Int32 tpDeltaPri;
public UInt32 dwFlags;
}
[StructLayout(LayoutKind.Sequential)]
private struct THREAD_BASIC_INFORMATION
{
public bool ExitStatus;
public IntPtr TebBaseAddress;
public uint processid;
public uint threadid;
public uint AffinityMask;
public uint Priority;
public uint BasePriority;
}
private const uint TH32CS_SNAPTHREAD = 0x00000004;
private const uint THREAD_SUSPEND_RESUME = 0x0002;
private IntPtr GetWowsMainThread(Process process)
{
uint THREAD_QUERY_INFORMATION = 0x40;
IntPtr snaphandle = IntPtr.Zero;
IntPtr threadhandle = IntPtr.Zero;
snaphandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snaphandle != null)
{
THREADENTRY32 info = new THREADENTRY32();
info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32));
bool morethreads = true;
bool found = false;
if (Thread32First(snaphandle, ref info))
{
while (morethreads && !found)
{
if (info.th32OwnerProcessID == process.Id)
{
threadhandle = OpenThread(THREAD_QUERY_INFORMATION, false, info.th32ThreadID);
if (threadhandle != null)
{
THREAD_BASIC_INFORMATION tbi = new THREAD_BASIC_INFORMATION();
NtQueryInformationThread(threadhandle, 0, ref tbi, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREAD_BASIC_INFORMATION)), IntPtr.Zero);
if (tbi.processid == process.Id)
{
SetSecurityInfo(
threadhandle,
Console.WriteLine("TBI");
Console.WriteLine("0x{0:X08}", tbi.threadid);
Console.WriteLine("hThread:0x{0:X04}", threadhandle);
Console.WriteLine("Trying to suspend");
Console.WriteLine("Result:0x{0:X08}", SuspendThread(threadhandle) );
CloseHandle(threadhandle);
break;
}
}
}
info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32));
morethreads = Thread32Next(snaphandle, ref info);
}
}
CloseHandle(snaphandle);
}
return threadhandle;
}
I figured you need to set the Security Information on wow's main thread to