Пример #1
0
        private void PopulateConfigStruct()
        {
            string path = Path.GetDirectoryName(ModulePath);
            string name = Path.GetFileName(ModulePath);

            bool dll = true;


            if (Path.GetExtension(ModulePath) != ".dll" && Path.GetExtension(ModulePath) != ".DLL")
            {
                dll = false;
            }

            var MaLRet = ErcCore.MapAndLoad(name, path, out loadedImage, dll, true);
            var modPtr = ErcCore.ImageLoad(name, path);

            if (ModuleMachineType == MachineType.I386)
            {
                IMAGE_LOAD_CONFIG_DIRECTORY32 ImageConfigDir = new IMAGE_LOAD_CONFIG_DIRECTORY32();
                var check = ErcCore.GetImageConfigInformation32(ref loadedImage, ref ImageConfigDir);
            }
            else if (ModuleMachineType == MachineType.x64)
            {
                IMAGE_LOAD_CONFIG_DIRECTORY64 ImageConfigDir = new IMAGE_LOAD_CONFIG_DIRECTORY64();
                var check = ErcCore.GetImageConfigInformation64(ref loadedImage, ref ImageConfigDir);
            }
        }
Пример #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>
 /// Compares a byte array with an area in memory of equal size. This method should be used in conjunction with the ByteArrayConstructor to identify
 /// bytes which can not be passed into a program without corrupting the input.
 /// </summary>
 /// <param name="info">The process to compare memory from</param>
 /// <param name="startAddress">The address at which to start the comparison</param>
 /// <param name="bytes">The byte array containing the bytes to be compared</param>
 /// <returns>Returns a Tuple containing a bool which is true if the comparison was identical and false if it was not, a byte array containing
 /// the bytes provided and a byte array containing the bytes read from process memory</returns>
 public static Tuple <bool, byte[], byte[]> ByteCompare(ProcessInfo info, IntPtr startAddress, byte[] bytes)
 {
     byte[] memoryBytes = new byte[bytes.Length];
     ErcCore.ReadProcessMemory(info.ProcessHandle, startAddress, bytes, bytes.Length, out int bytesRead);
     for (int i = 0; i < bytes.Length; i++)
     {
         if (bytes[i] != memoryBytes[i])
         {
             return(Tuple.Create(false, bytes, memoryBytes));
         }
     }
     return(Tuple.Create(true, bytes, memoryBytes));
 }
Пример #5
0
        public HeapInfo(ProcessInfo info)
        {
            HeapProcess = info;
            HEAPLIST32 firstHeapList = new HEAPLIST32();

            firstHeapList.dwSize = (IntPtr)Marshal.SizeOf(typeof(HEAPLIST32));
            IntPtr Handle = ErcCore.CreateToolhelp32Snapshot(SnapshotFlags.HeapList, (uint)info.ProcessID);

            if ((int)Handle == -1)
            {
                throw new ERCException("CreateToolhelp32Snapshot returned an invalid handle value (-1)");
            }

            if (ErcCore.Heap32ListFirst(Handle, ref firstHeapList))
            {
                HeapLists.Add(firstHeapList);
                bool moreHeaps = false;
                do
                {
                    HEAPLIST32 currentHeap = new HEAPLIST32();
                    currentHeap.dwSize = (IntPtr)Marshal.SizeOf(typeof(HEAPLIST32));
                    moreHeaps          = ErcCore.Heap32ListNext(Handle, ref currentHeap);
                    if (HeapEntries.Count == 0)
                    {
                        currentHeap = firstHeapList;
                    }

                    if (moreHeaps)
                    {
                        HeapLists.Add(currentHeap);
                        HEAPENTRY32 heapentry32 = new HEAPENTRY32();
                        heapentry32.dwSize = (IntPtr)Marshal.SizeOf(typeof(HEAPENTRY32));

                        if (ErcCore.Heap32First(ref heapentry32, (uint)HeapProcess.ProcessID, currentHeap.th32HeapID))
                        {
                            bool moreheapblocks = false;
                            do
                            {
                                HeapEntries.Add(heapentry32);
                                moreheapblocks = ErcCore.Heap32Next(ref heapentry32);
                            }while (moreheapblocks);
                        }
                    }
                }while (moreHeaps);
            }
            else
            {
                throw new ERCException("Heap32ListFirst returned an invalid response. Error: " + Utilities.Win32Errors.GetLastWin32Error());
            }
        }
Пример #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
 /// <summary>
 /// Compares a byte array with an area in memory of equal size. This method should be used in conjunction with the ByteArrayConstructor to identify
 /// bytes which can not be passed into a program without corrupting the input.
 /// </summary>
 /// <param name="info">The process to compare memory from</param>
 /// <param name="startAddress">The address at which to start the comparison</param>
 /// <param name="byteFilePath">The path to a file containing the bytes to be compared</param>
 /// <returns>Returns a Tuple containing a bool which is true if the comparison was identical and false if it was not, a byte array containing
 /// the bytes provided and a byte array containing the bytes read from process memory</returns>
 public static Tuple <bool, byte[], byte[]> ByteCompare(ProcessInfo info, IntPtr startAddress, string byteFilePath)
 {
     if (File.Exists(byteFilePath))
     {
         byte[] bytes       = File.ReadAllBytes(byteFilePath);
         byte[] memoryBytes = new byte[bytes.Length];
         ErcCore.ReadProcessMemory(info.ProcessHandle, startAddress, bytes, bytes.Length, out int bytesRead);
         for (int i = 0; i < bytes.Length; i++)
         {
             if (bytes[i] != memoryBytes[i])
             {
                 return(Tuple.Create(false, bytes, memoryBytes));
             }
         }
         return(Tuple.Create(true, bytes, memoryBytes));
     }
     else
     {
         throw new FileNotFoundException(byteFilePath);
     }
 }
Пример #10
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();
        }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
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);
        }
Пример #14
0
        private unsafe void PopulateHeaderStructs(FileStream fin)
        {
            byte[] Data  = new byte[4096];
            int    iRead = fin.Read(Data, 0, 4096);

            fin.Flush();
            fin.Close();

            fixed(byte *p_Data = Data)
            {
                IMAGE_DOS_HEADER *  idh  = (IMAGE_DOS_HEADER *)p_Data;
                IMAGE_NT_HEADERS32 *inhs = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data);

                ModuleMachineType = (MachineType)inhs->FileHeader.Machine;

                if (ModuleMachineType == MachineType.I386)
                {
                    IMAGE_NT_HEADERS32 *inhs32 = (IMAGE_NT_HEADERS32 *)(idh->nt_head_ptr + p_Data);
                    ImageFileHeader       = inhs32->FileHeader;
                    ModuleMachineType     = (MachineType)inhs32->FileHeader.Machine;
                    ImageOptionalHeader32 = inhs32->OptionalHeader;
                    ModuleImageBase       = (IntPtr)inhs32->OptionalHeader.ImageBase;

                    ImageNTHeaders32 = new IMAGE_NT_HEADERS32
                    {
                        Signature      = inhs32->Signature,
                        FileHeader     = inhs32->FileHeader,
                        OptionalHeader = inhs32->OptionalHeader
                    };

                    byte[] bytes = new byte[256];
                    var    ret   = ErcCore.ReadProcessMemory(ModuleProcess.Handle,
                                                             (IntPtr)((uint)ModuleBase + ImageOptionalHeader32.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead);
                    if (BitConverter.ToUInt32(bytes, 58) > 0 || BitConverter.ToUInt32(bytes, 62) > 0)
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else if (ModuleMachineType == MachineType.x64)
                {
                    IMAGE_NT_HEADERS64 *inhs64 = (IMAGE_NT_HEADERS64 *)(idh->nt_head_ptr + p_Data);
                    ImageFileHeader       = inhs64->FileHeader;
                    ImageOptionalHeader64 = inhs64->OptionalHeader;
                    ModuleImageBase       = (IntPtr)inhs64->OptionalHeader.ImageBase;

                    ImageNTHeaders64 = new IMAGE_NT_HEADERS64
                    {
                        Signature      = inhs64->Signature,
                        FileHeader     = inhs64->FileHeader,
                        OptionalHeader = inhs64->OptionalHeader
                    };

                    byte[] bytes = new byte[256];
                    var    ret   = ErcCore.ReadProcessMemory(ModuleProcess.Handle,
                                                             (IntPtr)((long)ModuleBase + (long)ImageOptionalHeader64.LoadConfigTable.VirtualAddress), bytes, 256, out int BytesRead);
                    if (BitConverter.ToUInt64(bytes, 88) > 0 || BitConverter.ToUInt64(bytes, 96) > 0)
                    {
                        ModuleSafeSEH = true;
                    }
                }
                else
                {
                    ModuleFailed = true;
                }
            }
        }
Пример #15
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;
            }
        }
Пример #16
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;
            }
        }
Пример #17
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);
        }