private void Reset() { m_header = null; m_sections = null; m_clrHeader = null; }
private void ParseClrHeader(Stream s) { s.AssumeNotNull(); m_sections.AssumeNotNull(); m_header.AssumeNotNull(); var sectionIndex = (int) DataDirectoryName.CLRRuntimeHeader; if ( m_header.DataDirectories != null && sectionIndex < m_header.DataDirectories.Count && sectionIndex >=0 ) { var dd = m_header.DataDirectories[sectionIndex]; //find the section containing the RVA of the data directory. //For C# code this will almost always end up being the //".rdata" section, but the CLR Ecma spec does not require //this, and we are likely to find our selfs dissasembling //mixed-mode assemblies at some point in time anyways //(which can do arbitrarily weird things with executable //layout). This also makes us somewhat future proof. var section = m_sections[dd.RVA]; if (section == null || dd.Size <= 0 || dd.RVA <= 0) { return; } if (!section.IsInitializedData(dd)) { //If we reach here, it means that the CIL header is (at //least partially) located in uinitialized data, or crosses //section boundaries. Neither is likely to happen in //practice. The Ecma-335 spec (4th edition) //says that the CIL header should be in a "read only, //shared section of the image". // //If we see something like this, chances are we //screwed up somewhere along the way during parsing, or //the image we are reading is bad. However, it is also //possible that someone is trying to do something clever, //by initializing CLR meta-data in native code before //invoking the CLR's native entry point (_CorExeMain / // _CorDllMain). In either case, this means we can't //dissasemble this managed executable (because we don't //know what the meta-data is), so we throw an exception. // //It is technically possible to handle the cross-section //case, if the initialized data from the first section //terminates neatly on a page boundary (or the presence //of zero padding still yields a valid header), and the //"second" section contains initialized data. However, //such cases are not likely to be produced by a real //compiler, and likely come from either a bad image, //from a hand crafted edge case, or from a user with //malicious intent. In any case, it's best to throw here. throw new InternalErrorException( "Refusing to read non standard clr header." ); } s.Seek( section.PointerToRawData + (dd.RVA - section.SectionRVA).AssumeGte(0) ); m_clrHeader = new ClrHeader(); m_clrHeader.Load(s); } }