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); }