Ejemplo n.º 1
0
        /// <summary>
        /// Decodes assembly metadata, headers and tables to required values ad file offsets
        /// </summary>
        /// <param name="fileName">Assembly path and filename</param>
        /// <param name="cliHeaderFlag">Reference to CLI Header flag value</param>
        /// <param name="cliHeaderFlagOffset">Reference to CLI Header flag file offset</param>
        /// <param name="strongNameSignatureOffset">Reference to CLI Header strong name signature file offset</param>
        /// <param name="publicKeyIndexOffset">Reference to Public Key Index in Assembly Table file offset</param>
        /// <param name="publicKeyOffset">Reference to Public Key file offset</param>
        /// <param name="assemblyFlag">Reference to Assembly Table Flag value</param>
        /// <param name="assemblyFlagOffset">Reference to Assembly Table Flag file offset</param>
        /// <param name="compiledRuntimeVersion">Reference to string with compiled runtime version</param>
        /// <param name="assemblyReferences">Reference to array to hold assembly references</param>
        /// <param name="blobIndexSize">Blob Index size in bytes</param>
        /// <param name="peKind">PE kind type / Executable architecture</param>
        /// <returns>Returns a bool indicating if assembly data can be retieved successfully</returns>
        public static bool GetAssemblyData(string fileName, ref uint cliHeaderFlag, ref long cliHeaderFlagOffset, ref long strongNameSignatureOffset,
                                           ref long publicKeyIndexOffset, ref long publicKeyOffset, ref uint assemblyFlag, ref long assemblyFlagOffset,
                                           ref string compiledRuntimeVersion, ref ArrayList assemblyReferences, ref int blobIndexSize, ref string peKind)
        {
            FileStream stream = null;

            cliHeaderFlag             = 0;
            cliHeaderFlagOffset       = 0;
            strongNameSignatureOffset = 0;
            publicKeyIndexOffset      = 0;
            publicKeyOffset           = 0;
            compiledRuntimeVersion    = String.Empty;
            assemblyFlag       = 0;
            assemblyFlagOffset = 0;
            assemblyReferences.Clear();

            try
            {
                if (File.Exists(fileName))
                {
                    stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    BinaryReader r = new BinaryReader(stream);

                    try
                    {
                        MModule mod = new MModule(r);

                        if ((mod.ModHeaders != null) && (mod.ModHeaders.COR20Header != null))
                        {
                            cliHeaderFlag       = mod.ModHeaders.COR20Header.Flags;
                            cliHeaderFlagOffset = mod.ModHeaders.COR20Header.Start + CLI_HEADER_FLAGS_OFFSET;
                            // if Strong Name Signature RVA is zero, no Strong Signature is available
                            strongNameSignatureOffset = (mod.ModHeaders.COR20Header.StrongNameSignature.Rva == 0
                                                             ? 0
                                                             : mod.ModHeaders.COR20Header.StrongNameSignature.Start);
                            compiledRuntimeVersion = mod.ModHeaders.MetaDataHeaders.StorageSigAndHeader.VersionString.Replace("\0", String.Empty);
                            peKind        = mod.ModHeaders.OSHeaders.PEHeader.PEImageTypeDescription;
                            blobIndexSize = mod.MDTables.GetBlobIndexSize();

                            // next loop sum tables byte length till reaching Assembly Table - this would give Assembly Table start offset
                            long assemblyTableOffset = mod.ModHeaders.MetaDataTableHeader.End;
                            for (int tablesCounter = 0; tablesCounter < (int)Types.Assembly; tablesCounter++)
                            {
                                assemblyTableOffset += mod.MDTables.Tables[tablesCounter].RawData.Length;
                            }

                            Table tableAssembly = mod.MDTables.GetTable(Types.Assembly);
                            if (tableAssembly.Count > 0) // this should be 1
                            {
                                if (tableAssembly[0][6].RawData == 0)
                                {
                                    // Index for public key points to nothing
                                    publicKeyOffset = 0;
                                }
                                else
                                {
                                    publicKeyOffset = mod.BlobHeap.Start + tableAssembly[0][6].RawData + 1;
                                }

                                assemblyFlag = (uint)tableAssembly[0][ASSEMBLY_TABLE_FLAGS_COLUMN_INDEX].Data;

                                if (assemblyTableOffset > 0)
                                {
                                    publicKeyIndexOffset = assemblyTableOffset + ASSEMBLY_TABLE_PUBLIC_KEY_INDEX_OFFSET;
                                    assemblyFlagOffset   = assemblyTableOffset + ASSEMBLY_TABLE_FLAGS_OFFSET;
                                }
                            }

                            // next loop sum tables byte length till reaching Assembly References Table - this would give Assembly References Table start offset
                            long referenceTableOffset = mod.ModHeaders.MetaDataTableHeader.End;
                            for (int tablesCounter = 0; tablesCounter < (int)Types.AssemblyRef; tablesCounter++)
                            {
                                referenceTableOffset += mod.MDTables.Tables[tablesCounter].RawData.Length;
                            }

                            if (referenceTableOffset > 0)
                            {
                                Table tableAssemblyReferences = mod.MDTables.GetTable(Types.AssemblyRef);
                                if (tableAssemblyReferences.Count > 0)
                                {
                                    for (int referencesCounter = 0; referencesCounter < tableAssemblyReferences.Count; referencesCounter++)
                                    {
                                        AssemblyReference reference =
                                            new AssemblyReference(tableAssemblyReferences[referencesCounter][6].Data.ToString(),
                                                                  tableAssemblyReferences[referencesCounter][0].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][1].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][2].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][3].Data,
                                                                  tableAssemblyReferences[referencesCounter][5].Data.ToString(),
                                                                  referenceTableOffset + (referencesCounter * tableAssemblyReferences.RowSize));
                                        assemblyReferences.Add(reference);
                                    }
                                }
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    catch (Exception)
                    {
                        return(false);
                    }
                    finally
                    {
                        r.Close();
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                return(false);
            }
            catch (IOException)
            {
                return(false);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
		public Relocations(BinaryReader reader, MModule mod)
		{
			uint start, end; 

			if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva == 0) return;

			start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva);
			end = start + mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Size;

			//fill in Region props
			Start = start;
			Length = end-start;

			reader.BaseStream.Position = start;

			RelocationBlock block;
			ArrayList arr = new ArrayList();

			while(reader.BaseStream.Position < end)
			{

				block = new RelocationBlock(reader);
				arr.Add(block);
			}

			_blox = (RelocationBlock[])arr.ToArray(typeof(RelocationBlock));

		}
Ejemplo n.º 3
0
		public ImpExports(BinaryReader reader, MModule mod)
		{
			ArrayList ides = new ArrayList();
			ImportDirectoryEntry ide = null;

			_exports = new ExportRecord[0];
			_ith = new ImportDirectoryEntry[0];

			//imports 

			if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva != 0)
			{

				uint start, end;
				start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva);
				end = mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Size + start;

				reader.BaseStream.Position = start;

				while (reader.BaseStream.Position < end)
				{
					ide = new ImportDirectoryEntry(reader, mod);

					//in older PEs it seems there is no null terminating entry, but in .NET ones there is.
					if (ide.Name == null)
					{
						break;
					}
					else
					{
						ides.Add(ide);
					}
				}

				_ith = (ImportDirectoryEntry[])ides.ToArray(typeof(ImportDirectoryEntry));
			}

			//exports

			if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva != 0)
			{
			
				reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva);
				_extab = new ExportDirTable(reader, mod);

				_expAddrTab = new uint[_extab.AddressTableEntries];
				_expNameTab = new string[_extab.NamePointerCount];
				_expOrdTab = new uint[_extab.NamePointerCount];

				reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.ExportAddressTableRVA);

				for(int i=0; i< _extab.AddressTableEntries; ++i)
				{
					_expAddrTab[i] = reader.ReadUInt32();
				}

				reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.OrdinalRVA);

				for(int i=0; i< _extab.NamePointerCount; ++i)
				{
					_expOrdTab[i] = reader.ReadUInt16();
				}

				reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.NamePointerRVA);

				for(int i=0; i< _extab.NamePointerCount; ++i)
				{
					_expNameTab[i] = mod.StringFromRVA(reader, reader.ReadUInt32());
				}

				//assemble array of exportrecords
				uint len = _extab.AddressTableEntries;
				if (len > _extab.NamePointerCount) len = _extab.NamePointerCount;
				_exports = new ExportRecord[len];
				for(int i=0; i < len; ++i)
				{
					_exports[i] = new ExportRecord(_expOrdTab[i], _expAddrTab[i], _expNameTab[i]);
				}
			}

		}
Ejemplo n.º 4
0
		public ExportDirTable(BinaryReader reader, MModule mod)
		{
			_ExportFlags = reader.ReadUInt32();
			_TimeStamp = reader.ReadUInt32();
			_MajorVersion = reader.ReadUInt16();
			_MinorVersion = reader.ReadUInt16();
			_Name = mod.StringFromRVA(reader, reader.ReadUInt32());
			_OrdinalBase = reader.ReadUInt32();
			_AddressTableEntries = reader.ReadUInt32();
			_NamePointerCount = reader.ReadUInt32();
			_ExportAddressTableRVA = reader.ReadUInt32();
			_NamePointerRVA = reader.ReadUInt32();
			_OrdinalRVA = reader.ReadUInt32();
		}
Ejemplo n.º 5
0
		public ImportDirectoryEntry(BinaryReader reader, MModule mod)
		{
			Start = reader.BaseStream.Position;

			uint iltRVA = reader.ReadUInt32();
			_DateTimeStamp = reader.ReadUInt32();
			_ForwarderChain = reader.ReadUInt32();
			uint nameRVA = reader.ReadUInt32();
			_Name = mod.StringFromRVA(reader, nameRVA);
			uint iatRVA = reader.ReadUInt32(); //can also get this from the PEHeader's data dirs

			Length = reader.BaseStream.Position - Start;

			long offs = reader.BaseStream.Position; // remember our position at the end of the imp dir entry record

			if (nameRVA == 0)
			{
				//indicate that this is not valid, because we reached the null terminating record
				//or because we are hopelessly lost
				_Name = null;
				return;
			}

			try
			{
				

				//get imp look table from RVA
				ArrayList arr;
				uint tableOffs, field;

				if (iltRVA != 0)
				{
				
					arr = new ArrayList();
					tableOffs = mod.ModHeaders.Rva2Offset(iltRVA);
					reader.BaseStream.Position = tableOffs;
					field = reader.ReadUInt32();
					while(field != 0)
					{
						arr.Add(new ImportAddress(field, reader, mod));
						field = reader.ReadUInt32();
					}

					_ImportLookupTable = (ImportAddress[])arr.ToArray(typeof(ImportAddress));
				}


				//get imp Addr table from RVA
				if (iatRVA != 0)
				{
					arr = new ArrayList();
					tableOffs = mod.ModHeaders.Rva2Offset(iatRVA);
					reader.BaseStream.Position = tableOffs;
					field = reader.ReadUInt32();
					while(field != 0)
					{
						arr.Add(field);
						field = reader.ReadUInt32();
					}

					_ImportAddressTable = (uint[])arr.ToArray(typeof(uint));
				}


			}
			catch//(Exception e)
			{
			}
			finally
			{
				//restore stream pos
				reader.BaseStream.Position = offs;
			}

		}
Ejemplo n.º 6
0
		public ImportAddress(uint n, BinaryReader reader, MModule mod)
		{
			if ((n & 0x80000000) != 0)
				_ByOrdinal = true;
			else
				_ByOrdinal = false;

			if (_ByOrdinal)
			{
				_Ordinal = n & 0x7fffffff;
			}
			else
			{
				uint nameOffs = n & 0x7fffffff;
				long offs = reader.BaseStream.Position;
				reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(nameOffs);
				reader.ReadInt16();//hint

				byte b = reader.ReadByte();

				while(b != 0)
				{
					_Name += (char) b;
					b = reader.ReadByte();
				}

				reader.BaseStream.Position = offs;

			}
		}