Пример #1
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);
        }
Пример #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
        /// <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);
        }
Пример #4
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);
        }
Пример #5
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;
            }
        }
Пример #6
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();
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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;
            }
        }
Пример #11
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;
            }
        }
Пример #12
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);
        }