public void OnCreatePacketReceived(dm_NotifyHdr notificationHeader, dm_CreateNotifyParams createParams, string pipeName)
        {
            UInt64 pipeFileIdentifier = createParams.fileIdentifier;

            List <NamedPipeInfo> matchingPipes = namedPipeFiles.Values.Where((x) => x.FileObjects.Contains(pipeFileIdentifier)).ToList();

            if (matchingPipes.Count >= 1)
            {
                // Opening a new file with an already-existing file object? The previous file object must be dead.
                namedPipeFiles.Remove(matchingPipes[0].PipeFileName);
            }

            if (!namedPipeFiles.ContainsKey(pipeName))
            {
                // Create a new pipe
                namedPipeFiles[pipeName] = new NamedPipeInfo(pipeFileIdentifier, pipeName, notificationHeader.processId);

                chromeMonitor.UpdateRunningProcessesCache();
            }
            else
            {
                // We already know this pipe, it must be another process that opens a new handle to it
                namedPipeFiles[pipeName].AddFileObjectIfNeeded(pipeFileIdentifier);
                namedPipeFiles[pipeName].AddProcessIfNeeded(notificationHeader.processId);
            }
        }
        public NamedPipeInfo DeterminePipeFromPacket(dm_NotifyHdr notificationHeader, dm_ReadWriteNotifyParams writeParams)
        {
            UInt64 fileObject = writeParams.fileIdentifier;

            // Search for the pipe by the file object
            List <NamedPipeInfo> matchingPipes = namedPipeFiles.Values.Where((x) => x.FileObjects.Contains(fileObject)).ToList();

            if (matchingPipes.Count == 1)
            {
                return(matchingPipes[0]);
            }

            if (destoryedNamedPipes.Contains(fileObject.ToString("X")))
            {
                return(null);
            }

            if (matchingPipes.Count == 0)
            {
                // We didn't see this file object before.

                if (this.recordingOnlyNewMojoPipes)
                {
                    // are we missing create packets?
                    // we probably do, because we can't read fast enough.
                    throw new Exception("I will not suffer inconsistencies.");
                }

                //
                // Try to get the pipe name from the file object
                //
                string pipeName = HandlesUtility.GetFilePathFromFileObject(new IntPtr((long)fileObject));
                if (pipeName != null && pipeName.Contains(@"\Device\NamedPipe"))
                {
                    pipeName = pipeName.Substring(@"\Device\NamedPipe".Length);

                    if (!namedPipeFiles.ContainsKey(pipeName))
                    {
                        // We don't know this pipe
                        // create it then

                        namedPipeFiles[pipeName] = new NamedPipeInfo(fileObject, pipeName, notificationHeader.processId);
                    }

                    return(namedPipeFiles[pipeName]);
                }
                else
                {
                    // either the pipe does not exist anymore, or its handle was closed, or NtQueryObject got hang
                }
            }
            else
            {
                // this file object must be dead, because it's used in two pipes
                throw new Exception("I will not suffer inconsistencies.");
            }

            //Console.WriteLine("[-] Could not find pipe name for " + fileObject.ToString("X"));
            destoryedNamedPipes.Add(fileObject.ToString("X"));
            return(null);
        }
        public void OnReadWritePacketReceived(dm_NotifyHdr notificationHeader, dm_ReadWriteNotifyParams writeParams, byte[] data, bool isWriting)
        {
            UInt64 fileObject = writeParams.fileIdentifier;
            UInt32 processId  = notificationHeader.processId;

            if (!chromeMonitor.IsChromeProcess(processId))
            {
                return;
            }

            // Find out on which pipe this packet was sent
            NamedPipeInfo pipe     = DeterminePipeFromPacket(notificationHeader, writeParams);
            string        pipeName = pipe != null ? pipe.PipeFileName : "<Unknown " + fileObject.ToString("X") + ">";

            if (pipe != null)
            {
                // Update this pipe's information
                namedPipeFiles[pipeName].AddProcessIfNeeded(processId);
                namedPipeFiles[pipeName].AddFileObjectIfNeeded(fileObject);
            }

            if (!pipeName.Contains(this.pipeNameFilter))
            {
                return;
            }

            //
            // Find out what is the destination process of this packet
            //
            UInt32 destinationPID = 0;

            if (pipe != null)
            {
                if (pipe.InvolvedProcesses.Count < 2 && !destoryedNamedPipes.Contains(pipe.PipeFileName))
                {
                    //
                    // try to find the destination process using Windows handle query
                    //

                    List <int> legalPIDs    = ChromeMonitor.GetRunningChromeProcesses().Select(process => process.Id).ToList();
                    string     fullPipePath = @"\Device\NamedPipe" + pipe.PipeFileName;
                    namedPipeFiles[pipeName].InvolvedProcesses = HandlesUtility.GetProcessesUsingFile(fullPipePath, legalPIDs);
                    if (namedPipeFiles[pipeName].InvolvedProcesses.Count < 2)
                    {
                        // TODO: because we are doing heavy caching on the handle information,
                        // it happens sometimes that we reach here but the pipe actually is in fact valid.
                        //Console.WriteLine("[-] Could not find destination PID for " + pipeName);
                        destoryedNamedPipes.Add(pipe.PipeFileName);
                    }
                }

                if (pipe.InvolvedProcesses.Count >= 2)
                {
                    List <uint> involvedProcesses = pipe.InvolvedProcesses.ToList();
                    involvedProcesses.Remove(notificationHeader.processId);
                    destinationPID = involvedProcesses.Last();
                }
            }

            if (!isWriting)
            {
                return;
            }
            if (data.Length == 0)
            {
                return;
            }

            //
            // Send it off
            //
            this.numPacketsProcessed++;
            byte[] wiresharkPacket = GenerateWiresharkPacket(notificationHeader, writeParams, pipeName, destinationPID, data);
            wiresharkSender.SendToWiresharkAsEthernet(wiresharkPacket, 0);
        }