Example #1
0
        private void CloseMutex(WS.SYSTEM_HANDLE_INFORMATION handle)
        {
            IntPtr targetHandle;

            // DUPLICATE_CLOSE_SOURCE = 0x1
            // GetCurrentProcess(), out targetHandle ======> Set target process to null for success
            if (!DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, IntPtr.Zero, out targetHandle, 0, false, 0x1))
            {
                MessageBox.Show("Failed to close mutex: " + Marshal.GetLastWin32Error(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            Console.WriteLine("Mutex was killed");
        }
Example #2
0
        // Closes all needed mutant handles in given process
        private void CloseProcessHandles(Process growtopia)           // We need to remove handlers from the last process
        {
            Console.WriteLine("Starting handle magic...");
            statusMessage.Text = "Querying system handle information...";
            int    nLength       = 0;
            IntPtr handlePointer = IntPtr.Zero;
            int    sysInfoLength = 0x10000;          // How much to allocate to returned data
            IntPtr infoPointer   = Marshal.AllocHGlobal(sysInfoLength);
            // 0x10 = SystemHandleInformation, an undocumented SystemInformationClass
            uint result;             // NtQuerySystemInformation won't give us the correct buffer size, so we guess it

            // Assign result of NtQuerySystemInformation to this variable and check if the buffer size is correct
            // If it's incorrect, it returns STATUS_INFO_LENGTH_MISMATCH (0xc0000004)
            while ((result = NtQuerySystemInformation(0x10, infoPointer, sysInfoLength, ref nLength)) == 0xc0000004)
            {
                sysInfoLength = nLength;
                Marshal.FreeHGlobal(infoPointer);
                infoPointer = Marshal.AllocHGlobal(nLength);
            }

            byte[] baTemp = new byte[nLength];
            // Copy the data from unmanaged memory to managed 1-byte uint array
            Marshal.Copy(infoPointer, baTemp, 0, nLength);
            // Do we even need the two statements above??? Look into this later.

            long sysHandleCount = 0;             // How many handles there are total

            if (Is64Bits())
            {
                sysHandleCount = Marshal.ReadInt64(infoPointer);
                handlePointer  = new IntPtr(infoPointer.ToInt64() + 8);                // Points in bits at the start of a handle
            }
            else
            {
                sysHandleCount = Marshal.ReadInt32(infoPointer);
                handlePointer  = new IntPtr(infoPointer.ToInt32() + 4);                // Ignores 4 first bits instead of 8
            }

            statusMessage.Text = "Query received, processing the " + sysHandleCount + " results.";

            WS.SYSTEM_HANDLE_INFORMATION handleInfoStruct;             // The struct to hold info about a single handler

            List <WS.SYSTEM_HANDLE_INFORMATION> handles = new List <WS.SYSTEM_HANDLE_INFORMATION>();

            for (long i = 0; i < sysHandleCount; i++)               // Iterate over handle structs in the handle struct list
            {
                handleInfoStruct = new WS.SYSTEM_HANDLE_INFORMATION();
                if (Is64Bits())
                {
                    handleInfoStruct = (WS.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(handlePointer, handleInfoStruct.GetType()); // Convert to struct
                    handlePointer    = new IntPtr(handlePointer.ToInt64() + Marshal.SizeOf(handleInfoStruct) + 8);                      // point 8 bits forward to the next handle
                }
                else
                {
                    handleInfoStruct = (WS.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(handlePointer, handleInfoStruct.GetType());
                    handlePointer    = new IntPtr(handlePointer.ToInt64() + Marshal.SizeOf(handleInfoStruct));
                }

                if (handleInfoStruct.ProcessID != growtopia.Id) // Check if current handler is from Growtopia
                {
                    continue;                                   // If it's not from Growtopia, just skip it
                }

                string handleName = ViewHandleName(handleInfoStruct, growtopia);
                // TODO: Looks like the mutant session number is different for different PCs
                // Maybe just check if the string contains basenamedobjects/growtopia and starts with sessions?
                if (handleName != null && handleName.StartsWith(@"\Sessions\") && handleName.EndsWith(@"\BaseNamedObjects\Growtopia"))
                {
                    handles.Add(handleInfoStruct);
                    Console.WriteLine("PID {0,7} Pointer {1,12} Type {2,4} Name {3}", handleInfoStruct.ProcessID.ToString(),
                                      handleInfoStruct.Object_Pointer.ToString(),
                                      handleInfoStruct.ObjectTypeNumber.ToString(),
                                      handleName);
                }
                else
                {
                    continue;                     // This is not a handle we're looking for
                }
            }

            Console.WriteLine("Closing mutexes?");
            foreach (WS.SYSTEM_HANDLE_INFORMATION handle in handles)
            {
                CloseMutex(handle);
            }

            statusMessage.Text = "Query finished, " + sysHandleCount + " results processed.";
            Console.WriteLine("Handle closed.");
        }
Example #3
0
        private static string ViewHandleName(WS.SYSTEM_HANDLE_INFORMATION shHandle, Process process)
        {
            // handleInfoStruct is the struct that contains data about our handle
            // targetProcess is the process where the handle resides
            // DUP_HANDLE (0x40) might also work
            IntPtr sourceProcessHandle = OpenProcess(0x1F0FFF, false, process.Id);

            IntPtr targetHandle = IntPtr.Zero;

            // We create a duplicate of the handle so that we can query more information about it
            if (!DuplicateHandle(sourceProcessHandle, shHandle.Handle, GetCurrentProcess(), out targetHandle, 0, false, 0x2))
            {
                return(null);
            }

            // Buffers that the query results get sent to
            IntPtr basicQueryData = IntPtr.Zero;

            // Query result structs
            WS.OBJECT_BASIC_INFORMATION basicInformationStruct = new WS.OBJECT_BASIC_INFORMATION();
            WS.OBJECT_NAME_INFORMATION  nameInformationStruct  = new WS.OBJECT_NAME_INFORMATION();

            basicQueryData = Marshal.AllocHGlobal(Marshal.SizeOf(basicInformationStruct));

            int nameInfoLength = 0;             // Size of information returned to us

            NtQueryObject(targetHandle, 0, basicQueryData, Marshal.SizeOf(basicInformationStruct), ref nameInfoLength);

            // Insert buffer data into a struct and free the buffer
            basicInformationStruct = (WS.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(basicQueryData, basicInformationStruct.GetType());
            Marshal.FreeHGlobal(basicQueryData);

            // The basicInformationStruct contains data about the name's length
            // TODO: We could probably skip querying for OBJECT_BASIC_INFORMATION
            nameInfoLength = basicInformationStruct.NameInformationLength;

            // Allocate buffer for the name now that we know its size
            IntPtr nameQueryData = Marshal.AllocHGlobal(nameInfoLength);

            // Object information class: 1
            // If it's incorrect, it returns STATUS_INFO_LENGTH_MISMATCH (0xc0000004)
            int result;

            while ((uint)(result = NtQueryObject(targetHandle, 1, nameQueryData, nameInfoLength, ref nameInfoLength)) == 0xc0000004)
            {
                Marshal.FreeHGlobal(nameQueryData);
                nameQueryData = Marshal.AllocHGlobal(nameInfoLength);
            }
            nameInformationStruct = (WS.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(nameQueryData, nameInformationStruct.GetType());

            IntPtr handlerName;

            if (Is64Bits())
            {
                handlerName = new IntPtr(Convert.ToInt64(nameInformationStruct.Name.Buffer.ToString(), 10) >> 32);
            }
            else
            {
                handlerName = nameInformationStruct.Name.Buffer;
            }

            if (handlerName != IntPtr.Zero)
            {
                byte[] baTemp2 = new byte[nameInfoLength];
                try {
                    Marshal.Copy(handlerName, baTemp2, 0, nameInfoLength);
                    return(Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(handlerName.ToInt64()) : new IntPtr(handlerName.ToInt32())));
                }
                catch (AccessViolationException) {
                    return(null);
                }
                finally {
                    Marshal.FreeHGlobal(nameQueryData);
                    CloseHandle(targetHandle);
                }
            }
            return(null);
        }