Пример #1
0
        /// <summary>
        /// Takes either an array or list of strings containing assembly instructions, a MachineType of I386 or x64,
        /// an instance of the ERC_Core object and returns the associated opcodes.
        /// </summary>
        /// <param name="instructions">The instructions to be assemble=d</param>
        /// <param name="machineType">a ERC.MachineType of either I386 or x64</param>
        /// <returns>Returns an ERC_Result byte array containing the assembled instructions</returns>
        public static ErcResult <byte[]> AssembleOpcodes(List <string> instructions, MachineType machineType)
        {
            ErcResult <byte[]> result    = new ErcResult <byte[]>(new ErcCore());
            List <string>      mnemonics = new List <string>();

            if (machineType == MachineType.I386)
            {
                mnemonics.Add("use32");
            }
            else if (machineType == MachineType.x64)
            {
                mnemonics.Add("use64");
            }

            for (int i = 0; i < instructions.Count; i++)
            {
                mnemonics.Add(instructions[i]);
            }

            var asm = new Assembler();

            try
            {
                result.ReturnValue = asm.Assemble(mnemonics);
                asm.Dispose();
            }
            catch (Exception e)
            {
                result.Error = e;
                result.LogEvent();
                asm.Dispose();
                return(result);
            }
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Takes a string of characters and returns the location of the first character in a pattern created by Pattern_Create.
        /// </summary>
        /// <param name="pattern">The pattern to be searched for.</param>
        /// <param name="core">An ErcCore object</param>
        /// <param name="extended">(Optional) bool specifying whether the extended character set should be used</param>
        /// <returns>Returns an ErcResult int containing the offset of the supplied pattern within the generated pattern</returns>
        public static ErcResult <int> PatternOffset(string pattern, ErcCore core, bool extended = false)
        {
            string digits = "0123456789";
            string patternFull;

            if (extended == true)
            {
                digits     += ": ,.;+=-_!&()#@'({})[]%";
                patternFull = File.ReadAllText(core.PatternExtendedPath);
            }
            else
            {
                patternFull = File.ReadAllText(core.PatternStandardPath);
            }
            ErcResult <int> result = new ErcResult <int>(core);

            if (pattern.Length < 3)
            {
                result.Error = new ERCException("User Input Error: Pattern length must be 3 characters or longer.");
                result.LogEvent();
                return(result);
            }

            if (patternFull.Contains(pattern))
            {
                result.ReturnValue = patternFull.IndexOf(pattern);
                return(result);
            }

            result.Error       = new ERCException("Error: Pattern not found.");
            result.ReturnValue = -1;
            return(result);
        }
Пример #3
0
        internal ErcResult <string> PopulateTEB()
        {
            ErcResult <string> returnString = new ErcResult <string>(ThreadCore);

            var retInt = ErcCore.ZwQueryInformationThread(ThreadHandle, 0,
                                                          ref ThreadBasicInfo, Marshal.SizeOf(typeof(ThreadBasicInformation)), IntPtr.Zero);

            if (retInt != 0)
            {
                Console.WriteLine("NTSTATUS Error was thrown: " + retInt);
                returnString.Error = new ERCException("NTSTATUS Error was thrown: " + retInt);
                return(returnString);
            }

            byte[] tebBytes;
            int    ret = 0;

            if (X64 == MachineType.x64)
            {
                tebBytes = new byte[0x16A0];
                ErcCore.ReadProcessMemory(ThreadProcess.ProcessHandle, ThreadBasicInfo.TebBaseAdress, tebBytes, 0x16A0, out ret);
            }
            else
            {
                tebBytes = new byte[3888];
                ErcCore.ReadProcessMemory(ThreadProcess.ProcessHandle, ThreadBasicInfo.TebBaseAdress, tebBytes, 3888, out ret);
            }


            if (ret == 0)
            {
                ERCException e = new ERCException("System error: An error occured when executing ReadProcessMemory\n Process Handle = 0x"
                                                  + ThreadProcess.ProcessHandle.ToString("X") + " TEB Base Address = 0x" + ThreadBasicInfo.TebBaseAdress.ToString("X") +
                                                  " Return value = " + ret);
                returnString.Error = e;
                return(returnString);
            }

            if (X64 == MachineType.x64)
            {
                PopulateTEBStruct64(tebBytes);
            }
            else
            {
                PopulateTEBStruct32(tebBytes);
            }

            var bSehChain = BuildSehChain();

            if (bSehChain.Error != null)
            {
                returnString.Error = bSehChain.Error;
                return(returnString);
            }

            return(returnString);
        }
Пример #4
0
        /// <summary>
        /// Disassembles opcodes into the associated instructions. Takes a byte array containing opcodes, a MachineType of I386 or x64,
        /// an instance of the ERC_Core object and returns an ERC_Result containing associated instructions.
        /// </summary>
        /// <param name="opcodes">A byte array containing opcodes to be disassembled</param>
        /// <param name="machineType">a ERC.MachineType of either I386 or x64</param>
        /// <returns>Returns an ERC_Result containing associated instructions.</returns>
        public static ErcResult <string> Disassemble(byte[] opcodes, MachineType machineType)
        {
            ErcResult <string> result = new ErcResult <string>(new ErcCore());

            SharpDisasm.Disassembler.Translator.IncludeAddress = true;
            SharpDisasm.Disassembler.Translator.IncludeBinary  = true;
            SharpDisasm.Disassembler     disasm;
            SharpDisasm.ArchitectureMode mode;

            try
            {
                if (machineType == MachineType.I386)
                {
                    mode = SharpDisasm.ArchitectureMode.x86_32;
                }
                else if (machineType == MachineType.x64)
                {
                    mode = SharpDisasm.ArchitectureMode.x86_64;
                }
                else
                {
                    throw new ERCException("User input error: Machine Type is invalid, must be ERC.MachineType.x86_64 or ERC.MachineType.x86_32");
                }
            }
            catch (ERCException e)
            {
                result.Error = e;
                result.LogEvent();
                return(result);
            }

            try
            {
                disasm = new SharpDisasm.Disassembler(
                    HexStringToByteArray(BitConverter.ToString(opcodes).Replace("-", "")),
                    mode, 0, true);
            }
            catch (Exception e)
            {
                result.Error = e;
                result.LogEvent(e);
                return(result);
            }

            foreach (var insn in disasm.Disassemble())
            {
                var mne = insn.ToString().Split(new string[] { "  " }, StringSplitOptions.None);
                result.ReturnValue += mne[mne.Length - 1].Trim() + Environment.NewLine;
            }

            return(result);
        }
Пример #5
0
        /// <summary>
        /// Lists all HeapIDs associated with a process.
        /// </summary>
        /// <returns>Returns an ErcResult<List<ulong>>"</returns>
        public ErcResult <List <ulong> > HeapIDs()
        {
            ErcResult <List <ulong> > result = new ErcResult <List <ulong> >(HeapProcess);

            result.ReturnValue = new List <ulong>();
            foreach (HEAPLIST32 hl in HeapLists)
            {
                result.ReturnValue.Add((ulong)hl.th32HeapID);
            }

            if (result.ReturnValue.Count == 0)
            {
                result.Error = new ERCException("Error: No heap ids found associated with this process.");
            }
            return(result);
        }
Пример #6
0
        /// <summary>
        /// Takes a string of characters and returns the location of the first character in a pattern created by Pattern_Create.
        /// </summary>
        /// <param name="pattern">The pattern to be searched for.</param>
        /// <param name="core">An ErcCore object</param>
        /// <param name="extended">(Optional) bool specifying whether the extended character set should be used</param>
        /// <returns>Returns an ErcResult int containing the offset of the supplied pattern within the generated pattern</returns>
        public static ErcResult <string> PatternOffset(string pattern, ErcCore core, bool extended = false)
        {
            //create string with reversed version of pattern to be searched for.
            char[] reversedChars = pattern.ToCharArray();
            Array.Reverse(reversedChars);
            string reversed = new string(reversedChars);

            //Create pattern to search within. Either extended or normal.
            string digits = "0123456789";
            string patternFull;

            if (extended == true)
            {
                digits     += ": ,.;+=-_!&()#@'*^[]%$?";
                patternFull = File.ReadAllText(core.PatternExtendedPath);
            }
            else
            {
                patternFull = File.ReadAllText(core.PatternStandardPath);
            }
            ErcResult <string> result = new ErcResult <string>(core);

            if (pattern.Length < 3)
            {
                result.Error = new ERCException("User Input Error: Pattern length must be 3 characters or longer.");
                result.LogEvent();
                return(result);
            }

            if (patternFull.Contains(pattern))
            {
                result.ReturnValue = "Value found at postiont " + patternFull.IndexOf(pattern).ToString() + " in pattern.";
                return(result);
            }
            else if (patternFull.Contains(reversed))
            {
                result.ReturnValue = "Value found reversed at postiont " + patternFull.IndexOf(reversed).ToString() + " in pattern.";
                return(result);
            }

            result.Error       = new ERCException("Error: Value not found.");
            result.ReturnValue = "Value not found in pattern.";
            return(result);
        }
Пример #7
0
        internal ThreadInfo(ProcessThread thread, ErcCore core, ProcessInfo process)
        {
            ThreadID      = thread.Id;
            ThreadCurrent = thread;
            ThreadCore    = core;
            ThreadProcess = process;

            if (process.ProcessMachineType == MachineType.x64)
            {
                X64 = MachineType.x64;
            }
            else if (process.ProcessMachineType == MachineType.I386)
            {
                X64 = MachineType.I386;
            }

            try
            {
                ThreadHandle = ErcCore.OpenThread(ThreadAccess.All_ACCESS, false, (uint)thread.Id);
                if (ThreadHandle == null)
                {
                    ThreadFailed = true;

                    throw new ERCException(new Win32Exception(Marshal.GetLastWin32Error()).Message);
                }
            }
            catch (ERCException e)
            {
                ErcResult <Exception> exceptionThrower = new ErcResult <Exception>(ThreadCore)
                {
                    Error = e
                };
                exceptionThrower.LogEvent();
            }

            var errorCheck = PopulateTEB(); //This needs to be revisited.

            if (errorCheck.Error != null && errorCheck.Error.Message != "Error: No SEH chain has been generated yet. An SEH chain will not be generated until a crash occurs.")
            {
                throw errorCheck.Error;
            }
        }
Пример #8
0
        /// <summary>
        /// Searches for a string of bytes within a specific module. Takes a byte array to be searched for.
        /// </summary>
        /// <param name="searchBytes">A byte array to be searched for</param>
        /// <returns>Returns ERC_Result of pointers to the search term</returns>
        public ErcResult <List <IntPtr> > SearchModule(byte[] searchBytes)
        {
            ErcResult <List <IntPtr> > results = new ErcResult <List <IntPtr> >(ModuleCore);
            List <IntPtr> ptrs = new List <IntPtr>();

            IntPtr baseAddress = ModuleBase;

            byte[] buffer    = new byte[ModuleSize];
            int    bytesread = 0;

            ErcCore.ReadProcessMemory(ModuleProcess.Handle, ModuleBase, buffer, buffer.Length, out bytesread);
            List <int> positions = SearchBytePattern(searchBytes, buffer);

            for (int i = 0; i < positions.Count; i++)
            {
                ptrs.Add((IntPtr)(positions[i] + (long)ModuleBase));
            }

            results.ReturnValue = ptrs;
            return(results);
        }
Пример #9
0
        internal ThreadInfo(ProcessThread thread, ErcCore core, ProcessInfo process)
        {
            ThreadID      = thread.Id;
            ThreadCurrent = thread;
            ThreadCore    = core;
            ThreadProcess = process;

            if (process.ProcessMachineType == MachineType.x64)
            {
                X64 = MachineType.x64;
            }
            else if (process.ProcessMachineType == MachineType.I386)
            {
                X64 = MachineType.I386;
            }

            try
            {
                ThreadHandle = ErcCore.OpenThread(ThreadAccess.All_ACCESS, false, (uint)thread.Id);
                if (ThreadHandle == null)
                {
                    ThreadFailed = true;

                    throw new ERCException(new Win32Exception(Marshal.GetLastWin32Error()).Message);
                }
            }
            catch (ERCException e)
            {
                ErcResult <Exception> exceptionThrower = new ErcResult <Exception>(ThreadCore)
                {
                    Error = e
                };
                exceptionThrower.LogEvent();
            }

            PopulateTEB();
        }
Пример #10
0
        /// <summary>
        /// Searches heap entries for a specified pattern. Returns pointers to all instances of the pattern. If heapID and startAddress are both supplied heapID takes precedence.
        /// </summary>
        /// <param name="searchBytes">byte array containing the pattern to search for</param>
        /// <param name="heapID">ID of the heap to be searched(Optional)</param>
        /// <param name="hexStartAddress">Start address of the heap entry to be searched in hexadecimal(Optional)</param>
        /// <returns>Returns an ERCResult of IntPtr containing pointers to all instances of the pattern found.</returns>
        public ErcResult <List <Tuple <IntPtr, IntPtr, IntPtr> > > SearchHeap(byte[] searchBytes, ulong heapID = 0, string hexStartAddress = "")
        {
            ErcResult <List <Tuple <IntPtr, IntPtr, IntPtr> > > result = new ErcResult <List <Tuple <IntPtr, IntPtr, IntPtr> > >(HeapProcess);

            result.ReturnValue = new List <Tuple <IntPtr, IntPtr, IntPtr> >();

            if (hexStartAddress.Contains("0x") || hexStartAddress.Contains("0x") || hexStartAddress.Contains("x") || hexStartAddress.Contains("X"))
            {
                hexStartAddress = hexStartAddress.Replace("0x", "");
                hexStartAddress = hexStartAddress.Replace("0X", "");
                hexStartAddress = hexStartAddress.Replace("X", "");
                hexStartAddress = hexStartAddress.Replace("x", "");
            }

            IntPtr startAddress = IntPtr.Zero;
            IntPtr HeapID       = IntPtr.Zero;

            if (heapID != 0)
            {
                HeapID = (IntPtr)heapID;
            }

            if (HeapProcess.ProcessMachineType == MachineType.I386)
            {
                try
                {
                    startAddress = (IntPtr)Convert.ToInt32(hexStartAddress, 16);
                }
                catch
                {
                }
            }
            else
            {
                try
                {
                    startAddress = (IntPtr)Convert.ToInt64(hexStartAddress, 16);
                }
                catch
                {
                }
            }

            if (searchBytes.Length < 3)
            {
                result.Error       = new ERCException("Search pattern not long enough. Minimum length is 3 bytes");
                result.ReturnValue = null;
                return(result);
            }

            if (heapID != 0)
            {
                foreach (HEAPENTRY32 he in HeapEntries)
                {
                    if (he.th32HeapID == HeapID)
                    {
                        byte[] bytes = HeapProcess.DumpMemoryRegion(he.dwAddress, (int)he.dwBlockSize).ReturnValue;

                        int maxFirstCharSlot = bytes.Length - searchBytes.Length + 1;
                        for (int i = 0; i < maxFirstCharSlot; i++)
                        {
                            if (bytes[i] != searchBytes[0])
                            {
                                continue;
                            }

                            for (int j = searchBytes.Length - 1; j >= 1; j--)
                            {
                                if (bytes[i + j] != searchBytes[j])
                                {
                                    break;
                                }
                                if (j == 1)
                                {
                                    Tuple <IntPtr, IntPtr, IntPtr> element = new Tuple <IntPtr, IntPtr, IntPtr>(he.dwAddress + i, he.th32HeapID, he.dwAddress);
                                    result.ReturnValue.Add(element);
                                }
                            }
                        }
                    }
                }
            }
            else if (startAddress != IntPtr.Zero)
            {
                foreach (HEAPENTRY32 he in HeapEntries)
                {
                    if (he.dwAddress == startAddress)
                    {
                        byte[] bytes = HeapProcess.DumpMemoryRegion((IntPtr)startAddress, (int)he.dwBlockSize).ReturnValue;

                        int maxFirstCharSlot = bytes.Length - searchBytes.Length + 1;
                        for (int i = 0; i < maxFirstCharSlot; i++)
                        {
                            if (bytes[i] != searchBytes[0])
                            {
                                continue;
                            }

                            for (int j = searchBytes.Length - 1; j >= 1; j--)
                            {
                                if (bytes[i + j] != searchBytes[j])
                                {
                                    break;
                                }
                                if (j == 1)
                                {
                                    Tuple <IntPtr, IntPtr, IntPtr> element = new Tuple <IntPtr, IntPtr, IntPtr>(he.dwAddress + i, he.th32HeapID, he.dwAddress);
                                    result.ReturnValue.Add(element);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (HEAPENTRY32 he in HeapEntries)
                {
                    byte[] bytes = HeapProcess.DumpMemoryRegion(he.dwAddress, (int)he.dwBlockSize).ReturnValue;

                    int maxFirstCharSlot = bytes.Length - searchBytes.Length + 1;
                    for (int i = 0; i < maxFirstCharSlot; i++)
                    {
                        if (bytes[i] != searchBytes[0])
                        {
                            continue;
                        }

                        for (int j = searchBytes.Length - 1; j >= 1; j--)
                        {
                            if (bytes[i + j] != searchBytes[j])
                            {
                                break;
                            }
                            if (j == 1)
                            {
                                Tuple <IntPtr, IntPtr, IntPtr> element = new Tuple <IntPtr, IntPtr, IntPtr>(he.dwAddress + i, he.th32HeapID, he.dwAddress);
                                result.ReturnValue.Add(element);
                            }
                        }
                    }
                }
            }
            return(result);
        }
Пример #11
0
        /// <summary>
        /// Returns a collections of stats related to the heap of the current process object. If both heapID and startAddress are specified heapID takes precedence.
        /// </summary>
        /// <param name="extended">display an extended set of </param>
        /// <param name="heapID">The ID of the heap to display stats for. (optional)</param>
        /// <param name="hexStartAddress">The start address of the specific heap block to display stats for in hexadecimal. (optional)</param>
        /// <returns>returns a List<string> object</returns>
        public ErcResult <List <string> > HeapStatistics(bool extended = false, ulong heapID = 0, string hexStartAddress = "")
        {
            ErcResult <List <string> > result = new ErcResult <List <string> >(HeapProcess);

            if (hexStartAddress.Contains("0x") || hexStartAddress.Contains("0x") || hexStartAddress.Contains("x") || hexStartAddress.Contains("X"))
            {
                hexStartAddress = hexStartAddress.Replace("0x", "");
                hexStartAddress = hexStartAddress.Replace("0X", "");
                hexStartAddress = hexStartAddress.Replace("X", "");
                hexStartAddress = hexStartAddress.Replace("x", "");
            }

            ulong startAddress = 0;

            if (HeapProcess.ProcessMachineType == MachineType.I386)
            {
                try
                {
                    startAddress = (uint)Convert.ToInt32(hexStartAddress, 16);
                }
                catch
                {
                }
            }
            else
            {
                try
                {
                    startAddress = (ulong)Convert.ToInt64(hexStartAddress, 16);
                }
                catch
                {
                }
            }

            List <string> heapStats = new List <string>();

            heapStats.Add("ProcessID = " + HeapProcess.ProcessID + Environment.NewLine);
            heapStats.Add("Number of heaps = " + HeapLists.Count + Environment.NewLine);

            if (heapID != 0)
            {
                heapStats.Add("    Heap ID = " + heapID + Environment.NewLine);
            }

            int count = 0;

            foreach (HEAPLIST32 hl in HeapLists)
            {
                count++;
                int heapEnts = 0;
                if (heapID == 0 && startAddress == 0)
                {
                    heapStats.Add("    Heap " + count + " ID = " + hl.th32HeapID + Environment.NewLine);
                }

                foreach (HEAPENTRY32 he in HeapEntries)
                {
                    if (heapID != 0)
                    {
                        if (he.th32HeapID == (IntPtr)heapID && hl.th32HeapID == (IntPtr)heapID)
                        {
                            if (HeapProcess.ProcessMachineType == MachineType.I386)
                            {
                                heapStats.Add("       Heap Start Address = 0x" + he.dwAddress.ToString("X8") + Environment.NewLine);
                                heapStats.Add("       Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("       Heap flags = LF32_FIXED" + Environment.NewLine);
                                    break;

                                case 2:
                                    heapStats.Add("       Heap flags = LF32_FREE" + Environment.NewLine);
                                    break;

                                case 4:
                                    heapStats.Add("       Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    break;

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                heapStats.Add("       Heap Start Address = " + he.dwAddress.ToString("X16") + Environment.NewLine);
                                heapStats.Add("       Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("       Heap flags = LF32_FIXED" + Environment.NewLine);
                                    break;

                                case 2:
                                    heapStats.Add("       Heap flags = LF32_FREE" + Environment.NewLine);
                                    break;

                                case 4:
                                    heapStats.Add("       Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    break;

                                default:
                                    break;
                                }
                            }
                            heapEnts++;
                        }
                    }
                    else if (startAddress != 0)
                    {
                        if (he.dwAddress == (IntPtr)startAddress)
                        {
                            if (HeapProcess.ProcessMachineType == MachineType.I386)
                            {
                                heapStats.Add("    Heap ID = " + hl.th32HeapID + Environment.NewLine);
                                heapStats.Add("    Heap Start Address = " + he.dwAddress.ToString("X8") + Environment.NewLine);
                                heapStats.Add("    Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("    Heap flags = LF32_FIXED" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                case 2:
                                    heapStats.Add("    Heap flags = LF32_FREE" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                case 4:
                                    heapStats.Add("    Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                heapStats.Add("    Heap ID = " + hl.th32HeapID + Environment.NewLine);
                                heapStats.Add("    Heap Start Address = " + he.dwAddress.ToString("X16") + Environment.NewLine);
                                heapStats.Add("    Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("    Heap flags = LF32_FIXED" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                case 2:
                                    heapStats.Add("    Heap flags = LF32_FREE" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                case 4:
                                    heapStats.Add("    Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    result.ReturnValue = heapStats;
                                    return(result);

                                default:
                                    break;
                                }
                            }
                        }
                    }
                    else if (he.th32HeapID == hl.th32HeapID)
                    {
                        if (extended == true)
                        {
                            if (HeapProcess.ProcessMachineType == MachineType.I386)
                            {
                                heapStats.Add("       Heap Start Address = " + he.dwAddress.ToString("X8") + Environment.NewLine);
                                heapStats.Add("       Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("       Heap flags = LF32_FIXED" + Environment.NewLine);
                                    break;

                                case 2:
                                    heapStats.Add("       Heap flags = LF32_FREE" + Environment.NewLine);
                                    break;

                                case 4:
                                    heapStats.Add("       Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    break;

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                heapStats.Add("       Heap Start Address = " + he.dwAddress.ToString("X16") + Environment.NewLine);
                                heapStats.Add("       Heap Entry size = " + he.dwBlockSize.ToString() + Environment.NewLine);
                                switch (he.dwFlags)
                                {
                                case 1:
                                    heapStats.Add("       Heap flags = LF32_FIXED" + Environment.NewLine);
                                    break;

                                case 2:
                                    heapStats.Add("       Heap flags = LF32_FREE" + Environment.NewLine);
                                    break;

                                case 4:
                                    heapStats.Add("       Heap flags = LF32_MOVEABLE" + Environment.NewLine);
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                        heapEnts++;
                    }
                }
                if (heapID != 0 || startAddress != 0)
                {
                    if ((IntPtr)heapID == hl.th32HeapID)
                    {
                        heapStats.Add("        Total number of entries in heap: " + heapEnts + Environment.NewLine);
                    }
                }
                else
                {
                    heapStats.Add("        Total number of entries in heap: " + heapEnts + Environment.NewLine);
                }
            }
            result.ReturnValue = heapStats;
            return(result);
        }
Пример #12
0
        /// <summary>
        /// Gets the register values of a thread and populates the CONTEXT structs. Should only be used on a suspended thread, results on an active thread are unreliable.
        /// </summary>
        /// <returns>Returns an ErcResult, the return value can be ignored, the object should only be checked for error values</returns>
        public ErcResult <string> Get_Context()
        {
            ErcResult <string> result = new ErcResult <string>(ThreadCore);

            if (X64 == MachineType.x64)
            {
                Context64 = new CONTEXT64();
                Context64.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.GetThreadContext64(ThreadHandle, ref Context64);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            else if (Environment.Is64BitOperatingSystem == true && X64 != MachineType.x64)
            {
                Context32 = new CONTEXT32();
                Context32.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.Wow64GetThreadContext(ThreadHandle, ref Context32);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            else
            {
                Context32 = new CONTEXT32();
                Context32.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.GetThreadContext32(ThreadHandle, ref Context32);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            return(result);
        }
Пример #13
0
        /// <summary>
        /// Constructor for the ModuleInfo object. Takes (string)modules filepath (IntPtr)module handle (Process)Process from which the module is loaded
        /// </summary>
        /// <param name="module">Filepath of the module</param>
        /// <param name="ptr">Handle to the module</param>
        /// <param name="process">Process where the module is loaded</param>
        /// <param name="core">An ErcCore object</param>
        internal unsafe ModuleInfo(string module, IntPtr ptr, Process process, ErcCore core)
        {
            try
            {
                ModuleCore    = core;
                ModuleProcess = process;
                ModuleName    = FileVersionInfo.GetVersionInfo(module).InternalName;
                ModulePath    = FileVersionInfo.GetVersionInfo(module).FileName;
                ModuleBase    = ptr;

                FileInfo   fileInfo = new FileInfo(ModulePath);
                FileStream file     = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                PopulateHeaderStructs(file);

                if (!string.IsNullOrEmpty(FileVersionInfo.GetVersionInfo(module).FileVersion))
                {
                    ModuleVersion = FileVersionInfo.GetVersionInfo(module).FileVersion.Split(' ')[0];
                }
                else
                {
                    ModuleVersion = "";
                }

                ModuleProduct = FileVersionInfo.GetVersionInfo(module).ProductName;

                if (ModuleMachineType == MachineType.I386)
                {
                    ModuleEntry     = (IntPtr)ImageOptionalHeader32.AddressOfEntryPoint;
                    ModuleSize      = (int)ImageOptionalHeader32.SizeOfImage;
                    ModuleImageBase = (IntPtr)ImageOptionalHeader32.ImageBase;
                    byte[]   dllByte = BitConverter.GetBytes(ImageOptionalHeader32.DllCharacteristics);
                    BitArray bits    = new BitArray(dllByte);
                    for (int i = 0; i < bits.Count; i++)
                    {
                        if (bits[i] == true && i == 6)
                        {
                            ModuleASLR = true;
                        }
                        else
                        {
                            ModuleASLR = false;
                        }

                        if (bits[i] == true && i == 8)
                        {
                            ModuleNXCompat = true;
                        }
                        else
                        {
                            ModuleNXCompat = false;
                        }
                    }

                    if (ModuleMachineType == MachineType.I386)
                    {
                        PopulateConfigStruct();

                        if (ImageConfigDir32.SEHandlerCount == 0 && ImageConfigDir32.SEHandlerTable == 0)
                        {
                            ModuleSafeSEH = false;
                        }
                        else
                        {
                            ModuleSafeSEH = true;
                        }
                    }
                    else
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else if (ModuleMachineType == MachineType.x64)
                {
                    ModuleEntry     = (IntPtr)ImageOptionalHeader64.AddressOfEntryPoint;
                    ModuleSize      = (int)ImageOptionalHeader64.SizeOfImage;
                    ModuleImageBase = (IntPtr)ImageOptionalHeader64.ImageBase;
                    byte[]   dllByte = BitConverter.GetBytes(ImageOptionalHeader64.DllCharacteristics);
                    BitArray bits    = new BitArray(dllByte);
                    for (int i = 0; i < bits.Count; i++)
                    {
                        if (bits[i] == true && i == 6)
                        {
                            ModuleASLR = true;
                        }
                        else if (bits[i] == false && i == 6)
                        {
                            ModuleASLR = false;
                        }

                        if (bits[i] == true && i == 8)
                        {
                            ModuleNXCompat = true;
                        }
                        else if (bits[i] == false && i == 8)
                        {
                            ModuleNXCompat = false;
                        }
                    }

                    PopulateConfigStruct();

                    if (ImageConfigDir64.SEHandlerCount == 0 && ImageConfigDir64.SEHandlerTable == 0)
                    {
                        ModuleSafeSEH = false;
                    }
                    else
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else
                {
                    ModuleFailed = true;
                    throw new ERCException("Unsupported machine type: " + ModuleMachineType.ToString());
                }

                if (ModuleProduct == "Microsoft® Windows® Operating System")
                {
                    ModuleOsDll = true;
                }
                else
                {
                    ModuleOsDll = false;
                }

                if (ModuleImageBase != ptr)
                {
                    ModuleRebase = true;
                }
                else
                {
                    ModuleRebase = false;
                }
            }
            catch (Exception e)
            {
                ErcResult <Exception> ExceptionLogger = new ErcResult <Exception>(ModuleCore);
                ExceptionLogger.Error = e;
                ExceptionLogger.LogEvent();
                ModuleFailed = true;
            }
        }
Пример #14
0
        /// <summary>
        /// Constructor for the ModuleInfo object. Takes (string)modules filepath (IntPtr)module handle (Process)Process from which the module is loaded
        /// </summary>
        /// <param name="module">Filepath of the module</param>
        /// <param name="ptr">Handle to the module</param>
        /// <param name="process">Process where the module is loaded</param>
        /// <param name="core">An ErcCore object</param>
        internal unsafe ModuleInfo(string module, IntPtr ptr, Process process, ErcCore core)
        {
            try
            {
                ModuleCore    = core;
                ModuleProcess = process;
                ModuleName    = FileVersionInfo.GetVersionInfo(module).InternalName;
                ModulePath    = FileVersionInfo.GetVersionInfo(module).FileName;
                ModuleBase    = ptr;

                FileInfo   fileInfo = new FileInfo(ModulePath);
                FileStream file     = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                PopulateHeaderStructs(file);

                if (!string.IsNullOrEmpty(FileVersionInfo.GetVersionInfo(module).FileVersion))
                {
                    ModuleVersion = FileVersionInfo.GetVersionInfo(module).FileVersion.Split(' ')[0];
                }
                else
                {
                    ModuleVersion = "";
                }

                ModuleProduct = FileVersionInfo.GetVersionInfo(module).ProductName;

                if (ModuleMachineType == MachineType.I386)
                {
                    ModuleEntry     = (IntPtr)ImageOptionalHeader32.AddressOfEntryPoint;
                    ModuleSize      = (int)ImageOptionalHeader32.SizeOfImage;
                    ModuleImageBase = (IntPtr)ImageOptionalHeader32.ImageBase;
                    byte[]   dllByte = BitConverter.GetBytes(ImageOptionalHeader32.DllCharacteristics);
                    BitArray bits    = new BitArray(dllByte);
                    for (int i = 0; i < bits.Count; i++)
                    {
                        if (bits[i] == true && i == 6)
                        {
                            ModuleASLR = true;
                        }
                        else
                        {
                            ModuleASLR = false;
                        }

                        if (bits[i] == true && i == 8)
                        {
                            ModuleNXCompat = true;
                        }
                        else
                        {
                            ModuleNXCompat = false;
                        }
                    }

                    if (ModuleMachineType == MachineType.I386)
                    {
                        PopulateConfigStruct();

                        if (ImageConfigDir32.SEHandlerCount == 0 && ImageConfigDir32.SEHandlerTable == 0)
                        {
                            ModuleSafeSEH = false;
                        }
                        else
                        {
                            ModuleSafeSEH = true;
                        }
                    }
                    else
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else if (ModuleMachineType == MachineType.x64)
                {
                    ModuleEntry     = (IntPtr)ImageOptionalHeader64.AddressOfEntryPoint;
                    ModuleSize      = (int)ImageOptionalHeader64.SizeOfImage;
                    ModuleImageBase = (IntPtr)ImageOptionalHeader64.ImageBase;
                    byte[]   dllByte = BitConverter.GetBytes(ImageOptionalHeader64.DllCharacteristics);
                    BitArray bits    = new BitArray(dllByte);
                    for (int i = 0; i < bits.Count; i++)
                    {
                        if (bits[i] == true && i == 6)
                        {
                            ModuleASLR = true;
                        }
                        else if (bits[i] == false && i == 6)
                        {
                            ModuleASLR = false;
                        }

                        if (bits[i] == true && i == 8)
                        {
                            ModuleNXCompat = true;
                        }
                        else if (bits[i] == false && i == 8)
                        {
                            ModuleNXCompat = false;
                        }
                    }

                    PopulateConfigStruct();

                    if (ImageConfigDir64.SEHandlerCount == 0 && ImageConfigDir64.SEHandlerTable == 0)
                    {
                        ModuleSafeSEH = false;
                    }
                    else
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else
                {
                    ModuleFailed = true;
                    throw new ERCException("Unsupported machine type: " + ModuleMachineType.ToString());
                }

                if (ModuleProduct == "Microsoft® Windows® Operating System")
                {
                    ModuleOsDll = true;
                }
                else
                {
                    ModuleOsDll = false;
                }

                if (ModuleImageBase != ptr)
                {
                    ModuleRebase = true;
                }
                else
                {
                    ModuleRebase = false;
                }

                long MaxAddress = 0x7fffffff;
                long address    = (long)ModuleBase;

                if (!ProcessInfo.Is64Bit(process))
                {
                    List <ERC.Structures.MEMORY_BASIC_INFORMATION32> ProcessMemoryBasicInfo32 = new List <ERC.Structures.MEMORY_BASIC_INFORMATION32>();
                    long oldAddress = 0;
                    do
                    {
                        ERC.Structures.MEMORY_BASIC_INFORMATION32 m;
                        int result = ErcCore.VirtualQueryEx32(ModuleProcess.Handle, (IntPtr)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION32)));
                        if (address == (long)m.BaseAddress + (long)m.RegionSize)
                        {
                            break;
                        }
                        address = (long)m.BaseAddress + (long)m.RegionSize;
                        if (oldAddress > address)
                        {
                            address = long.MaxValue;
                        }
                        oldAddress       = address;
                        ModuleProtection = m.AllocationProtect;
                    } while (address <= MaxAddress);
                }
                else
                {
                    List <ERC.Structures.MEMORY_BASIC_INFORMATION64> ProcessMemoryBasicInfo64 = new List <ERC.Structures.MEMORY_BASIC_INFORMATION64>();
                    long oldAddress = 0;
                    do
                    {
                        ERC.Structures.MEMORY_BASIC_INFORMATION64 m;
                        int result = ErcCore.VirtualQueryEx64(ModuleProcess.Handle, (IntPtr)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));
                        if (address == (long)m.BaseAddress + (long)m.RegionSize)
                        {
                            break;
                        }
                        address = (long)m.BaseAddress + (long)m.RegionSize;
                        if (oldAddress > address)
                        {
                            address = long.MaxValue;
                        }
                        oldAddress       = address;
                        ModuleProtection = m.AllocationProtect;
                    } while (address <= MaxAddress);
                }
            }
            catch (Exception e)
            {
                ErcResult <Exception> ExceptionLogger = new ErcResult <Exception>(ModuleCore);
                ExceptionLogger.Error = e;
                ExceptionLogger.LogEvent();
                ModuleFailed = true;
            }
        }
Пример #15
0
        /// <summary>
        /// Takes a string of characters and returns the location of the first character in a pattern created by Pattern_Create.
        /// </summary>
        /// <param name="pattern">The pattern to be searched for.</param>
        /// <param name="core">An ErcCore object</param>
        /// <param name="extended">(Optional) bool specifying whether the extended character set should be used</param>
        /// <returns>Returns an ErcResult int containing the offset of the supplied pattern within the generated pattern</returns>
        public static ErcResult <string> PatternOffset(string pattern, ErcCore core, bool extended = false)
        {
            //create string with reversed version of pattern to be searched for.
            char[] reversedChars = pattern.ToCharArray();
            Array.Reverse(reversedChars);
            string reversed = new string(reversedChars);

            //Create pattern to search within. Either extended or normal.
            string digits = "0123456789";
            string patternFull;

            if (extended == true)
            {
                digits     += ": ,.;+=-_!&()#@'*^[]%$?";
                patternFull = File.ReadAllText(core.PatternExtendedPath);
            }
            else
            {
                patternFull = File.ReadAllText(core.PatternStandardPath);
            }
            ErcResult <string> result = new ErcResult <string>(core);

            if (pattern.Length < 3)
            {
                result.Error = new ERCException("User Input Error: Pattern length must be 3 characters or longer.");
                result.LogEvent();
                return(result);
            }

            if (patternFull.Contains(pattern))
            {
                result.ReturnValue = "Value found at postiont " + patternFull.IndexOf(pattern).ToString() + " in pattern.";
                return(result);
            }
            else if (patternFull.Contains(reversed))
            {
                result.ReturnValue = "Value found reversed at postiont " + patternFull.IndexOf(reversed).ToString() + " in pattern.";
                return(result);
            }

            bool validHexString = true;

            foreach (char c in pattern)
            {
                if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
                {
                    validHexString = false;
                }
            }

            if (validHexString == true)
            {
                byte[] patternBytes         = ERC.Utilities.Convert.HexToBytes(pattern);
                byte[] patternBytesReversed = ERC.Utilities.Convert.HexToBytes(reversed);
                byte[] patternFullBytes     = Encoding.ASCII.GetBytes(patternFull);

                string hexString         = BitConverter.ToString(patternBytes).Replace("-", "");
                string hexStringReversed = BitConverter.ToString(patternBytesReversed).Replace("-", "");
                string hexPatternFull    = BitConverter.ToString(patternFullBytes).Replace("-", "");

                if (hexPatternFull.Contains(hexString))
                {
                    result.ReturnValue = "Value found at postiont " + (hexPatternFull.IndexOf(hexString) / 2).ToString() + " in pattern.";
                    return(result);
                }
                else if (hexPatternFull.Contains(hexStringReversed))
                {
                    result.ReturnValue = "Value found reversed at postiont " + (hexPatternFull.IndexOf(hexStringReversed) / 2).ToString() + " in pattern.";
                    return(result);
                }
            }

            result.Error       = new ERCException("Error: Value not found.");
            result.ReturnValue = "Value not found in pattern.";
            return(result);
        }
Пример #16
0
        /// <summary>
        /// Creates a string of non repeating characters.
        /// </summary>
        /// <param name="length">The length of the pattern to be created as integer</param>
        /// <param name="core">An ErcCore object</param>
        /// <param name="extended">(Optional) bool specifying whether the extended character set should be used</param>
        /// <returns>Returns an ErcResult string containing the generated pattern</returns>
        public static ErcResult <string> PatternCreate(int length, ErcCore core, bool extended = false)
        {
            string             digits = "0123456789";
            ErcResult <string> result = new ErcResult <string>(core);

            if (extended == true)
            {
                digits += ": ,.;+=-_!&()#@'*^[]%$?";
                if (length > 66923)
                {
                    result.Error = new ERCException("User input error: Pattern length must be less that 66923");
                    result.LogEvent();
                    return(result);
                }
            }
            else
            {
                if (length > 20277)
                {
                    result.Error = new ERCException("User input error: Pattern length must be less that 20277. Add the extended flag to create larger strings.");
                    result.LogEvent();
                    return(result);
                }
            }

            result.ReturnValue = "";

            if (length < 1)
            {
                result.Error = new ERCException("User Input Error: Pattern length must be greate than 0.");
                result.LogEvent();
                return(result);
            }

            for (int i = 0; i < uppercase.Length; i++)
            {
                for (int j = 0; j < lowercase.Length; j++)
                {
                    for (int k = 0; k < digits.Length; k++)
                    {
                        char pos1 = uppercase[i];
                        char pos2 = lowercase[j];
                        char pos3 = digits[k];

                        if (result.ReturnValue.Length > length)
                        {
                            result.Error       = new ERCException("Procedural Error: Pattern string has exceeded the length supplied");
                            result.ReturnValue = "";
                            return(result);
                        }

                        if (result.ReturnValue.Length == length)
                        {
                            return(result);
                        }

                        if (result.ReturnValue.Length < length - 2)
                        {
                            result.ReturnValue += pos1;
                            result.ReturnValue += pos2;
                            result.ReturnValue += pos3;
                            if (result.ReturnValue.Length == length)
                            {
                                return(result);
                            }
                        }
                        else if (result.ReturnValue.Length < length - 1)
                        {
                            result.ReturnValue += pos1;
                            result.ReturnValue += pos2;
                            if (result.ReturnValue.Length == length)
                            {
                                return(result);
                            }
                        }
                        else if (result.ReturnValue.Length < length)
                        {
                            result.ReturnValue += pos1;
                            if (result.ReturnValue.Length == length)
                            {
                                return(result);
                            }
                        }
                    }
                }
            }
            result.Error = new ERCException("An unknown error has occured. Function exited incorrectly. Function: ERC.Pattern_Tools.Pattern_Create");
            result.LogEvent();
            return(result);
        }
Пример #17
0
        internal ErcResult <List <Tuple <byte[], byte[]> > > BuildSehChain()
        {
            ErcResult <List <Tuple <byte[], byte[]> > > sehList = new ErcResult <List <Tuple <byte[], byte[]> > >(ThreadCore);

            sehList.ReturnValue = new List <Tuple <byte[], byte[]> >();

            if (Teb.Equals(default(TEB)))
            {
                sehList.Error = new Exception("Error: TEB structure for this thread has not yet been populated. Call PopulateTEB first");
                return(sehList);
            }

            if (Teb.CurrentSehFrame == IntPtr.Zero)
            {
                sehList.Error = new Exception("Error: No SEH chain has been generated yet. An SEH chain will not be generated until a crash occurs.");
                return(sehList);
            }

            byte[] sehEntry;
            byte[] sehFinal;

            int arraySize = 0;

            if (X64 == MachineType.x64)
            {
                arraySize = 8;
                sehEntry  = new byte[arraySize];
                sehFinal  = new byte[arraySize];
                sehEntry  = BitConverter.GetBytes((long)Teb.CurrentSehFrame);
            }
            else
            {
                arraySize = 4;
                sehEntry  = new byte[arraySize];
                sehFinal  = new byte[arraySize];
                sehEntry  = BitConverter.GetBytes((int)Teb.CurrentSehFrame);
            }

            for (int i = 0; i < sehFinal.Length; i++)
            {
                sehFinal[i] = 0xFF;
            }

            byte[] prevSEH          = new byte[] { 0xFF };
            string pattern_standard = File.ReadAllText(ThreadCore.PatternStandardPath);
            string pattern_extended = File.ReadAllText(ThreadCore.PatternExtendedPath);

            while (!sehEntry.SequenceEqual(sehFinal))
            {
                byte[] reversedSehEntry = new byte[arraySize];
                byte[] nSeh             = new byte[arraySize];
                byte[] sehHolder        = new byte[arraySize * 2];

                int ret = 0;

                if (X64 == MachineType.x64)
                {
                    ret = ErcCore.ReadProcessMemory(ThreadProcess.ProcessHandle, (IntPtr)BitConverter.ToInt64(sehEntry, 0), sehHolder, arraySize * 2, out int retInt);
                    Array.Copy(sehHolder, 0, sehEntry, 0, arraySize);
                    Array.Copy(sehHolder, arraySize, nSeh, 0, arraySize);
                }
                else
                {
                    ret = ErcCore.ReadProcessMemory(ThreadProcess.ProcessHandle, (IntPtr)BitConverter.ToInt32(sehEntry, 0), sehHolder, arraySize * 2, out int retInt);
                    Array.Copy(sehHolder, 0, sehEntry, 0, arraySize);
                    Array.Copy(sehHolder, arraySize, nSeh, 0, arraySize);
                }

                if (ret != 0 && ret != 1)
                {
                    ERCException e = new ERCException("System error: An error occured when executing ReadProcessMemory\n Process Handle = 0x"
                                                      + ThreadProcess.ProcessHandle.ToString("X") + " TEB Current Seh = 0x" + Teb.CurrentSehFrame.ToString("X") +
                                                      " Return value = " + ret + Environment.NewLine + "Win32Exception: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    sehList.Error = e;
                    sehList.LogEvent();
                    return(sehList);
                }

                Array.Reverse(nSeh);

                for (int i = 0; i < sehEntry.Length; i++)
                {
                    reversedSehEntry[i] = sehEntry[i];
                }

                Array.Reverse(reversedSehEntry, 0, reversedSehEntry.Length);
                if (prevSEH.SequenceEqual(reversedSehEntry))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }
                else if (!sehEntry.SequenceEqual(sehFinal) && !sehList.ReturnValue.Any(e => e.Item1.SequenceEqual(reversedSehEntry)))
                {
                    Tuple <byte[], byte[]> tuple = new Tuple <byte[], byte[]>(reversedSehEntry, nSeh);
                    sehList.ReturnValue.Add(tuple);
                }

                if (pattern_standard.Contains(Encoding.Unicode.GetString(reversedSehEntry)) ||
                    pattern_extended.Contains(Encoding.Unicode.GetString(reversedSehEntry)))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }

                if (pattern_standard.Contains(Encoding.ASCII.GetString(reversedSehEntry)) ||
                    pattern_extended.Contains(Encoding.ASCII.GetString(reversedSehEntry)))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }

                if (pattern_standard.Contains(Encoding.UTF32.GetString(reversedSehEntry)) ||
                    pattern_extended.Contains(Encoding.UTF32.GetString(reversedSehEntry)))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }

                if (pattern_standard.Contains(Encoding.UTF7.GetString(reversedSehEntry)) ||
                    pattern_extended.Contains(Encoding.UTF7.GetString(reversedSehEntry)))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }

                if (pattern_standard.Contains(Encoding.UTF8.GetString(reversedSehEntry)) ||
                    pattern_extended.Contains(Encoding.UTF8.GetString(reversedSehEntry)))
                {
                    sehEntry = new byte[sehFinal.Length];
                    Array.Copy(sehFinal, 0, sehEntry, 0, sehFinal.Length);
                }

                prevSEH = new byte[reversedSehEntry.Length];
                Array.Copy(reversedSehEntry, 0, prevSEH, 0, reversedSehEntry.Length);
            }

            SehChain = new List <Tuple <byte[], byte[]> >(sehList.ReturnValue);
            return(sehList);
        }