public static IntPtr GetTlsPointer(int threadId) { IntPtr threadHandle = IntPtr.Zero; try { threadHandle = OpenThread(ThreadAccess.QUERY_INFORMATION, false, threadId); THREAD_BASIC_INFORMATION threadInfo = new THREAD_BASIC_INFORMATION(); int status = NtQueryInformationThread(threadHandle, 0, &threadInfo, (ulong)sizeof(THREAD_BASIC_INFORMATION), null); if (status != 0) { Rage.Game.LogTrivialDebug($"Thread Invalid Query Status: {status}"); return(IntPtr.Zero); } TEB *teb = (TEB *)threadInfo.TebBaseAddress; return(teb->ThreadLocalStoragePointer); } finally { if (threadHandle != IntPtr.Zero) { CloseHandle(threadHandle); } } }
internal static extern int NtQueryInformationThread( /* HANDLE */ IntPtr thread, THREADINFOCLASS threadInformationClass, /* PVOID */ ref THREAD_BASIC_INFORMATION threadInformation, /* ULONG */ uint threadInformationLength, /* PULONG */ ref uint returnLength );
public static void CopyTlsValues(IntPtr sourceThreadHandle, IntPtr targetThreadHandle, params int[] valuesOffsets) { THREAD_BASIC_INFORMATION sourceThreadInfo = new THREAD_BASIC_INFORMATION(); THREAD_BASIC_INFORMATION targetThreadInfo = new THREAD_BASIC_INFORMATION(); int sourceStatus = NtQueryInformationThread(sourceThreadHandle, 0, &sourceThreadInfo, (ulong)sizeof(THREAD_BASIC_INFORMATION), null); if (sourceStatus != 0) { Rage.Game.LogTrivialDebug($"Source Thread Invalid Query Status: {sourceStatus}"); return; } int targetStatus = NtQueryInformationThread(targetThreadHandle, 0, &targetThreadInfo, (ulong)sizeof(THREAD_BASIC_INFORMATION), null); if (targetStatus != 0) { Rage.Game.LogTrivialDebug($"Target Thread Invalid Query Status: {targetStatus}"); return; } TEB *sourceTeb = (TEB *)sourceThreadInfo.TebBaseAddress; TEB *targetTeb = (TEB *)targetThreadInfo.TebBaseAddress; foreach (int offset in valuesOffsets) { *(long *)(*(byte **)(targetTeb->ThreadLocalStoragePointer) + offset) = *(long *)(*(byte **)(sourceTeb->ThreadLocalStoragePointer) + offset); } }
public static THREAD_BASIC_INFORMATION GetThreadState(IntPtr hThread) { THREAD_BASIC_INFORMATION ts = new THREAD_BASIC_INFORMATION(); IntPtr BuffPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ts)); int RetLen = 0; UInt32 CallResult = NtQueryInformationThread(hThread, 0, BuffPtr, Marshal.SizeOf(ts), ref RetLen); if (CallResult != 0) { return(ts); } // Ptr to struct ts = (THREAD_BASIC_INFORMATION)Marshal.PtrToStructure(BuffPtr, typeof(THREAD_BASIC_INFORMATION)); return(ts); }
public static IntPtr GetWowsMainThread(Process process) { uint THREAD_QUERY_INFORMATION = 0x1F03FF; 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) { IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor; GetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); SetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSidOwner); break; } } } info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32)); morethreads = Thread32Next(snaphandle, ref info); } } CloseHandle(snaphandle); } return(threadhandle); }
/// <summary> /// Fetch /// </summary> /// <returns></returns> public uint GetTLSPointer() { uint tlsPtr = Offsets.INVALID; IntPtr snapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (snapHandle != null) { THREADENTRY32 info = new THREADENTRY32(); info.dwSize = (uint)Marshal.SizeOf(typeof(THREADENTRY32)); bool moreThreads = true; if (Thread32First(snapHandle, ref info)) { while (moreThreads) { if (info.th32OwnerProcessID == D3.ProcessId) { IntPtr threadHandle = OpenThread(THREAD_QUERY_INFORMATION, false, info.th32ThreadID); if (threadHandle != null) { THREAD_BASIC_INFORMATION tbi = new THREAD_BASIC_INFORMATION(); if (NtQueryInformationThread(threadHandle, 0, ref tbi, (uint)Marshal.SizeOf(typeof(THREAD_BASIC_INFORMATION)), IntPtr.Zero) == 0) { uint tlsOffset = (uint)tbi.TebBaseAddress.ToInt32() + Offsets.TLS_OFFSET; uint tlsIndex = ReadUInt(Offsets.TLS_INDEX); tlsPtr = ReadUInt(ReadUInt(ReadUInt(tlsOffset + (tlsIndex * 4)))); CloseHandle(threadHandle); break; } } } info.dwSize = (uint)Marshal.SizeOf(typeof(THREADENTRY32)); moreThreads = Thread32Next(snapHandle, ref info); } } CloseHandle(snapHandle); } return(tlsPtr); }
public static THREAD_BASIC_INFORMATION GetThreadState(IntPtr hThread) { THREAD_BASIC_INFORMATION ts = new THREAD_BASIC_INFORMATION(); IntPtr BuffPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ts)); int RetLen = 0; IntPtr pSysCall = Generic.GetSyscallStub("NtQueryInformationThread"); NtQueryInformationThread fSyscallNtQueryInformationThread = (NtQueryInformationThread)Marshal.GetDelegateForFunctionPointer(pSysCall, typeof(NtQueryInformationThread)); UInt32 CallResult = fSyscallNtQueryInformationThread(hThread, 0, BuffPtr, Marshal.SizeOf(ts), ref RetLen); if (CallResult != 0) { Console.WriteLine("[!] Failed to query thread information.."); return(ts); } ts = (THREAD_BASIC_INFORMATION)Marshal.PtrToStructure(BuffPtr, typeof(THREAD_BASIC_INFORMATION)); return(ts); }
public static void CopyTlsValues(IntPtr sourceThreadHandle, IntPtr targetThreadHandle, params int[] valuesOffsets) { THREAD_BASIC_INFORMATION sourceThreadInfo, targetThreadInfo; if (!threadInformationDictionary.TryGetValue(sourceThreadHandle, out sourceThreadInfo)) { sourceThreadInfo = new THREAD_BASIC_INFORMATION(); int sourceStatus = Win32Native.NtQueryInformationThread(sourceThreadHandle, 0, &sourceThreadInfo, (ulong)sizeof(THREAD_BASIC_INFORMATION), null); if (sourceStatus != 0) { ScriptCore.Logger.Log($"Source Thread Invalid Query Status: {sourceStatus}"); return; } threadInformationDictionary[sourceThreadHandle] = sourceThreadInfo; } if (!threadInformationDictionary.TryGetValue(targetThreadHandle, out targetThreadInfo)) { targetThreadInfo = new THREAD_BASIC_INFORMATION(); int sourceStatus = Win32Native.NtQueryInformationThread(targetThreadHandle, 0, &targetThreadInfo, (ulong)sizeof(THREAD_BASIC_INFORMATION), null); if (sourceStatus != 0) { ScriptCore.Logger.Log($"Source Thread Invalid Query Status: {sourceStatus}"); return; } threadInformationDictionary[targetThreadHandle] = targetThreadInfo; } TEB *sourceTeb = (TEB *)sourceThreadInfo.TebBaseAddress; TEB *targetTeb = (TEB *)targetThreadInfo.TebBaseAddress; foreach (int offset in valuesOffsets) { *(long *)(*(byte **)(targetTeb->ThreadLocalStoragePointer) + offset) = *(long *)(*(byte **)(sourceTeb->ThreadLocalStoragePointer) + offset); } }
private static extern uint NtQueryInformationThread(IntPtr handle, uint infclass, ref THREAD_BASIC_INFORMATION info, uint length, IntPtr bytesread);
public static extern int ZwQueryInformationThread(IntPtr ThreadHandle, ThreadInformationClass ThreadInformationClass, ref THREAD_BASIC_INFORMATION ThreadInformation, int ThreadInformationLength, out int ReturnLength);
public static extern int NtQueryInformationThread(IntPtr threadHandle, ThreadInfoClass threadInformationClass, ref THREAD_BASIC_INFORMATION threadInformation, int threadInformationLength, IntPtr returnLengthPtr);
public static extern int ZwQueryInformationThread(int ThreadHandle, THREAD_INFORMATION_CLASS ThreadInformationClass, ref THREAD_BASIC_INFORMATION ThreadInformation, int ThreadInformationLength, out int ReturnLength);
public unsafe static extern int NtQueryInformationThread(SafeHandle hThread, ThreadInformationClass infoClass, out THREAD_BASIC_INFORMATION info, int size, int *actualSize = null);
public static IntPtr GetWowsMainThread(Process process) { uint THREAD_QUERY_INFORMATION = 0x1F03FF; 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) { IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor; GetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); SetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSidOwner); break; } } } info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32)); morethreads = Thread32Next(snaphandle, ref info); } } CloseHandle(snaphandle); } return threadhandle; }
public static extern int NtQueryInformationThread( IntPtr threadHandle, ThreadInfoClass threadInformationClass, out THREAD_BASIC_INFORMATION threadInformation, ulong threadInformationLength);