/////////////////////////////////////////////////////
            //                                                 //
            // IsProcessPidInZwqKMList()                       //
            //                                                 //
            /////////////////////////////////////////////////////
            //Description:  Determines whether or not the given pid
            //              exists in the process list obtained from
            //              the ZwQuerySystemInformation() in kernel mode.
            //
            //Returns:      true if it was found in the list
            /////////////////////////////////////////////////////
            internal static bool IsProcessPidInZwqKMList(uint pid)
            {
                CwStructures.PROCESS_LISTING_ZWQ ZwQueryKmList = new CwStructures.PROCESS_LISTING_ZWQ();
                try
                {
                    ZwQueryKmList = HeuristicsUserModeHelper.GetKernelModeProcessListingZwq();
                }
                catch (Exception ex)
                {
                    AgentScanLog.AppendLine("SCAN:  Failed to get process list using ZwQuerySystemInformation() from kernel mode:  " + ex.Message);
                }

                for (int i = 0; i < ZwQueryKmList.numProcesses; i++)
                {
                    CwStructures.CW_PROCESS_ENTRY process = ZwQueryKmList.ProcessList[i];
                    if (pid == process.UniqueProcessId)
                    {
                        return(true);
                    }
                }
                return(false);
            }
            /////////////////////////////////////////////////////
            //                                                 //
            // CrossViewAnalysisWithTrustedProcessList()       //
            //                                                 //
            /////////////////////////////////////////////////////
            //Description:  This cross-view analysis approach uses
            //              a "trusted list" it obtains from PspCidTable
            //              and diffs that across the 3 user mode
            //              methods.
            //
            //Returns:      an array of CWPROCESS_RECORD structs
            /////////////////////////////////////////////////////

            /*internal static CwStructures.CWPROCESS_RECORD[] CrossViewAnalysisWithTrustedProcessList()
             * {
             *  //
             *  //
             *  //  TODO:  THIS FUNCTION IS INCOMPLETE!
             *  //
             *  //
             *  //
             *
             *  //1.  GET TRUSTED PROCESS LIST
             *  //
             *  //we will get a listing of processes from kernel mode using the PspCidTable
             *  uint[] trustedPidList = new uint[256];
             *
             *  try
             *  {
             *      trustedPidList = HeuristicsUserModeHelper.GetKernelModeProcessListingPspCidTable();
             *  }
             *  catch (Exception ex)
             *  {
             *      AgentHeuristicMatches.UserModeMatches.ProcessListing = new CwStructures.CWPROCESS_RECORD[0];
             *      AgentScanLog.AppendLine("Failed to get trusted process listing using PspCidTable:  " + ex.Message);
             *      return false;
             *  }
             *
             *  //build a CWPROCESS_RECORD array for storing hidden processes
             *  CwStructures.CWPROCESS_RECORD[] hiddenProcesses = new CwStructures.CWPROCESS_RECORD[trustedPidList.Length];
             *
             *  //take the "trusted" listing and create a process entry for each process
             *  //we will shortly enumerate processes from user mode in 3 ways and then fill
             *  //the boolean field of each process in this structure
             *  for (int i = 0; i < trustedPidList.Length; i++)
             *  {
             *      hiddenProcesses[i] = new CwStructures.CWPROCESS_RECORD();
             *      hiddenProcesses[i].pid = trustedPidList[i];
             *      hiddenProcesses[i].IsInUserModePsapiList = false;
             *      hiddenProcesses[i].IsInUserModeToolhelp32List = false;
             *      hiddenProcesses[i].IsInUserModeZwqList = false;
             *  }
             * }*/

            /////////////////////////////////////////////////////
            //                                                 //
            // CrossViewAnalysis()                             //
            //                                                 //
            /////////////////////////////////////////////////////
            //Description:  This cross-view analysis approach creates
            //              four different process listings using
            //              various process enumeration methods and then
            //              diffs all those lists to see if there are
            //              any discrepancies.
            //
            //Returns:      an array of CWPROCESS_RECORD structs
            /////////////////////////////////////////////////////
            internal static CwStructures.CWPROCESS_RECORD[] CrossViewAnalysis()
            {
                //*************************************
                //Cross-view analysis
                //*************************************
                //user mode enumeration methods:
                //  (1)PSAPI
                //  (2)Toolhelp32
                //  (3)ZwQuerySystemInformation
                //
                //kernel mode enumeration methods:
                //  (1)PspCidTable (TODO)
                //  (2)ZwQuerySystemInformation
                //
                //*************************************
                //           GET DATA POINTS
                //*************************************
                //1.  PSAPI
                Process[] PsapiList = Process.GetProcesses();
                //
                //2.  TOOLHELP32
                ArrayList Toolhelp32List = HeuristicsUserModeHelper.GetUserModeProcessListingToolHelp32();

                //3.  ZWQUERYSYSTEMINFORMATION (KERNEL MODE)
                CwStructures.PROCESS_LISTING_ZWQ ZwQueryKmList = new CwStructures.PROCESS_LISTING_ZWQ();
                try
                {
                    ZwQueryKmList = HeuristicsUserModeHelper.GetKernelModeProcessListingZwq();
                }
                catch (Exception ex)
                {
                    AgentScanLog.AppendLine("SCAN:  Failed to get process list using ZwQuerySystemInformation() from kernel mode:  " + ex.Message);
                }
                //4.  ZWQUERYSYSTEMINFORMATION (USER MODE)
                Win32Helper.SYSTEM_PROCESS_INFORMATION[] ZwQueryUmList = new Win32Helper.SYSTEM_PROCESS_INFORMATION[0];
                try
                {
                    ZwQueryUmList = Win32Helper.GetActiveProcessList();
                }
                catch (Exception ex)
                {
                    AgentScanLog.AppendLine("SCAN:  Failed to get process list using ZwQuerySystemInformation from user mode:  " + ex.Message);
                }

                //prepare return structure - initialize our list of processes to the obvious ones
                //in the psapi library (using .NET's Process class)
                ArrayList hiddenProcesses = new ArrayList();

                foreach (Process p in Process.GetProcesses())
                {
                    string pname = "";
                    try
                    {
                        pname = p.MainModule.ModuleName;
                    }
                    catch (Exception) { }

                    AddPidToList(ref hiddenProcesses, (uint)p.Id, GetPsapiParentProcessId(p.ProcessName), pname, "");
                }

                //*************************************
                //  DIFF EACH LIST AGAINST ALL LISTS
                //*************************************
                //
                //1.  PSAPI
                foreach (Process p in PsapiList)
                {
                    if (p.Id == 0)
                    {
                        continue;
                    }

                    string pname = "";
                    try
                    {
                        pname = p.MainModule.ModuleName;
                    }
                    catch (Exception) { }

                    if (Toolhelp32List != null)
                    {
                        if (!HeuristicsUserModeHelper.IsProcessPidInToolhelp32List((uint)p.Id))
                        {
                            AddPidToList(ref hiddenProcesses, (uint)p.Id, GetPsapiParentProcessId(p.ProcessName), pname, "Toolhelp32");
                        }
                    }
                    if (ZwQueryKmList.numProcesses > 0)
                    {
                        if (!HeuristicsUserModeHelper.IsProcessPidInZwqKMList((uint)p.Id))
                        {
                            AddPidToList(ref hiddenProcesses, (uint)p.Id, GetPsapiParentProcessId(p.ProcessName), pname, "ZwQueryUM");
                        }
                    }
                    if (ZwQueryUmList.Length > GetPsapiParentProcessId(p.ProcessName))
                    {
                        if (!HeuristicsUserModeHelper.IsProcessPidInZwqUMList((uint)p.Id))
                        {
                            AddPidToList(ref hiddenProcesses, (uint)p.Id, GetPsapiParentProcessId(p.ProcessName), pname, "ZwQueryKM");
                        }
                    }
                }
                //2.  Toolhelp32
                if (Toolhelp32List != null)
                {
                    foreach (Win32Helper.PROCESSENTRY32 process in (Win32Helper.PROCESSENTRY32[])Toolhelp32List.ToArray(typeof(Win32Helper.PROCESSENTRY32)))
                    {
                        if (process.th32ProcessID == 0)
                        {
                            continue;
                        }

                        if (PsapiList != null)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInPsapiList(process.th32ProcessID))
                            {
                                AddPidToList(ref hiddenProcesses, process.th32ProcessID, process.th32ParentProcessID, process.szExeFile, "Psapi");
                            }
                        }
                        if (ZwQueryKmList.numProcesses > 0)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInZwqKMList(process.th32ProcessID))
                            {
                                AddPidToList(ref hiddenProcesses, process.th32ProcessID, process.th32ParentProcessID, process.szExeFile, "ZwQueryUM");
                            }
                        }
                        if (ZwQueryUmList.Length > 0)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInZwqUMList(process.th32ProcessID))
                            {
                                AddPidToList(ref hiddenProcesses, process.th32ProcessID, process.th32ParentProcessID, process.szExeFile, "ZwQueryKM");
                            }
                        }
                    }
                }
                //3.  ZwQuerySystemInformation USER MODE
                if (ZwQueryUmList != null)
                {
                    foreach (Win32Helper.SYSTEM_PROCESS_INFORMATION process in ZwQueryUmList)
                    {
                        if (process.UniqueProcessId == 0)
                        {
                            continue;
                        }

                        if (PsapiList != null)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInPsapiList(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName.Buffer, "Psapi");
                            }
                        }
                        if (Toolhelp32List != null)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInToolhelp32List(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName.Buffer, "Toolhelp32");
                            }
                        }
                        if (ZwQueryKmList.numProcesses > 0)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInZwqKMList(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName.Buffer, "ZwQueryKM");
                            }
                        }
                    }
                }
                //4.  ZwQuerySystemInformation KERNEL MODE
                if (ZwQueryKmList.numProcesses > 0)
                {
                    for (int i = 0; i < ZwQueryKmList.numProcesses; i++)
                    {
                        CwStructures.CW_PROCESS_ENTRY process = ZwQueryKmList.ProcessList[i];

                        if (process.UniqueProcessId == 0)
                        {
                            continue;
                        }

                        if (PsapiList != null)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInPsapiList(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName, "Psapi");
                            }
                        }
                        if (Toolhelp32List != null)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInToolhelp32List(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName, "Toolhelp32");
                            }
                        }
                        if (ZwQueryUmList != null && ZwQueryUmList.Length > 0)
                        {
                            if (!HeuristicsUserModeHelper.IsProcessPidInZwqUMList(process.UniqueProcessId))
                            {
                                AddPidToList(ref hiddenProcesses, process.UniqueProcessId, process.InheritedFromUniqueProcessId, process.ImageName, "ZwQueryUM");
                            }
                        }
                    }
                }

                return((CwStructures.CWPROCESS_RECORD[])hiddenProcesses.ToArray(typeof(CwStructures.CWPROCESS_RECORD)));
            }