Пример #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);
        }
Пример #2
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;
        }