예제 #1
0
            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);
                    }
                }
            }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }