public unsafe bool Initialize(BinaryReader reader) { if (reader == null) { return(false); } binary_reader = reader; reader.BaseStream.Position = 0; byte[] buffer; IntPtr pointer; long NewPos; try { buffer = reader.ReadBytes(sizeof(IMAGE_DOS_HEADER)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } idh = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pointer, typeof(IMAGE_DOS_HEADER)); if (idh.e_magic != 0x5A4D) { return(false); } reader.BaseStream.Position = idh.e_lfanew; buffer = reader.ReadBytes(sizeof(IMAGE_NT_HEADERS)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } inh = (IMAGE_NT_HEADERS)Marshal.PtrToStructure(pointer, typeof(IMAGE_NT_HEADERS)); if (inh.Signature != 0x4550) { return(false); } reader.BaseStream.Position = idh.e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER) + inh.ifh.SizeOfOptionalHeader; sections = new image_section_header[inh.ifh.NumberOfSections]; buffer = reader.ReadBytes(sizeof(image_section_header) * inh.ifh.NumberOfSections); fixed(byte *p = buffer) { pointer = (IntPtr)p; } for (int i = 0; i < sections.Length; i++) { sections[i] = (image_section_header)Marshal.PtrToStructure(pointer, typeof(image_section_header)); pointer = (IntPtr)(pointer.ToInt32() + Marshal.SizeOf(typeof(image_section_header))); } // NET Directory if (inh.ioh.MetaDataDirectory.RVA == 0) { return(false); } NewPos = (long)Rva2Offset(inh.ioh.MetaDataDirectory.RVA); if (NewPos == 0) { return(false); } reader.BaseStream.Position = NewPos; buffer = reader.ReadBytes(sizeof(NETDirectory)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } // After .NET Directory comes body of methods! netdir = (NETDirectory)Marshal.PtrToStructure(pointer, typeof(NETDirectory)); reader.BaseStream.Position = (long)Rva2Offset(netdir.MetaDataRVA); mh = new MetadataReader.MetaDataHeader(); mh.Signature = reader.ReadInt32(); mh.MajorVersion = reader.ReadInt16(); mh.MinorVersion = reader.ReadInt16(); mh.Reserved = reader.ReadInt32(); mh.VersionLenght = reader.ReadInt32(); mh.VersionString = reader.ReadBytes(mh.VersionLenght); mh.Flags = reader.ReadInt16(); mh.NumberOfStreams = reader.ReadInt16(); streams = new MetaDataStream[mh.NumberOfStreams]; for (int i = 0; i < mh.NumberOfStreams; ++i) { streams[i].Offset = reader.ReadInt32(); streams[i].Size = reader.ReadInt32(); char[] chars = new char[32]; int index = 0; byte character = 0; while ((character = reader.ReadByte()) != 0) { chars[index++] = (char)character; } index++; int padding = ((index % 4) != 0) ? (4 - (index % 4)) : 0; reader.ReadBytes(padding); streams[i].Name = new String(chars).Trim(new Char[] { '\0' }); if (streams[i].Name == "#~" || streams[i].Name == "#-") { MetadataRoot.Name = streams[i].Name; MetadataRoot.Offset = streams[i].Offset; MetadataRoot.Size = streams[i].Size; long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); TablesBytes = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#Strings") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); StringOffset = reader.BaseStream.Position; Strings = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#US") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); US = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#Blob") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); BlobOffset = reader.BaseStream.Position; Blob = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } if (streams[i].Name == "#GUID") { long savepoz = reader.BaseStream.Position; reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + streams[i].Offset); GUID = reader.ReadBytes(streams[i].Size); reader.BaseStream.Position = savepoz; } } reader.BaseStream.Position = (long)(Rva2Offset(netdir.MetaDataRVA) + MetadataRoot.Offset); tablestart = reader.BaseStream.Position; buffer = reader.ReadBytes(sizeof(TableHeader)); fixed(byte *p = buffer) { pointer = (IntPtr)p; } tableheader = (TableHeader)Marshal.PtrToStructure(pointer, typeof(TableHeader)); TableLengths = new int[64]; //read as many uints as there are bits set in maskvalid for (int i = 0; i < 64; i++) { int count = (((tableheader.MaskValid >> i) & 1) == 0) ? 0 : reader.ReadInt32(); TableLengths[i] = count; } TablesOffset = reader.BaseStream.Position; InitTablesInfo(); // Get Table sizes and all Tables tablesize = new TableSize[0x2D]; tables = new Table[0x2D]; for (int i = 0; i < tablesize.Length; i++) { tablesize[i].Sizes = new int[tablesinfo[i].ctypes.Length]; tablesize[i].TotalSize = 0; for (int j = 0; j < tablesinfo[i].ctypes.Length; j++) { tablesize[i].Sizes[j] = GetTypeSize(tablesinfo[i].ctypes[j]); tablesize[i].TotalSize = tablesize[i].TotalSize + tablesize[i].Sizes[j]; } } for (int i = 0; i < tablesize.Length; i++) { if (TableLengths[i] > 0) { tables[i].members = new long[TableLengths[i]][]; for (int j = 0; j < TableLengths[i]; j++) { tables[i].members[j] = new long[tablesinfo[i].ctypes.Length]; for (int k = 0; k < tablesinfo[i].ctypes.Length; k++) { if (tablesize[i].Sizes[k] == 2) { tables[i].members[j][k] = reader.ReadInt16() & 65535; } if (tablesize[i].Sizes[k] == 4) { tables[i].members[j][k] = reader.ReadInt32() & 4294967295; } } } } } // end of big for! } catch { return(false); } return(true); }
private XimPath() { XimRepository ximNET = NETDirectory.Open("", false); }