我试图通过解析StackOverflow问题中的最高投票答案来理解GAC中的DLL识别:What is the GAC in .NET?
作者带我们浏览C:\ Windows \ assembly \ GAC_64 \ System.Data的树结构,最后总结。 。 。
在这里您可以看到System.Data的版本2.0.0.0__b77a5c561934e089。
DLL由5个部分标识:
Name Version Architecture Culture Public Key
......那是我不清楚的部分。一旦我到了树的叶子,我如何提取DLL的标识的5个部分,并且与程序集的名称有什么关系?
在我使用程序集的示例中,名称为:
的目录v4.0_2.0.6178.1045__d45c8e156fba2841
...在该目录中有一个名为
的DLLAb3d.DXEngine.dll
...那么如何提取其识别的五个部分呢?
修改
Lifu Huang,下面建议有一种方法可以从visual studio访问ILDASM。我没有内置的方式(VS 2013),但有一种方法可以添加它,如下所述: http://dailydotnettips.com/2016/01/05/did-you-know-you-can-launch-ildasm-tool-from-inside-visual-studio-itself-how/ ...所以我这样做了,当我尝试在GAC上的DLL上运行ILDASM时,我从ILDASM收到错误“受保护的模块 - 无法反汇编”
答案 0 :(得分:0)
如何提取其识别的五个部分?
您可以在CLR标题和程序集的元数据中找到它们。
实际上每个托管模块(dll或exe)都由四部分组成:
元数据(这是介绍此主题的blog post)。主要有三种类型的元数据表:
IL代码(从源代码生成的IL代码)
答案 1 :(得分:0)
如果您知道格式,则可以通过编程方式阅读元数据。这是一些代码。 Link
public static CorFlagsReader ReadAssemblyMetadata(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
long length = stream.Length;
if (length < 0x40)
return null;
BinaryReader reader = new BinaryReader(stream);
// Read the pointer to the PE header.
stream.Position = 0x3c;
uint peHeaderPtr = reader.ReadUInt32();
if (peHeaderPtr == 0)
peHeaderPtr = 0x80;
// Ensure there is at least enough room for the following structures:
// 24 byte PE Signature & Header
// 28 byte Standard Fields (24 bytes for PE32+)
// 68 byte NT Fields (88 bytes for PE32+)
// >= 128 byte Data Dictionary Table
if (peHeaderPtr > length - 256)
return null;
// Check the PE signature. Should equal 'PE\0\0'.
stream.Position = peHeaderPtr;
uint peSignature = reader.ReadUInt32();
if (peSignature != 0x00004550)
return null;
// Read PE header fields.
ushort machine = reader.ReadUInt16();
ushort numberOfSections = reader.ReadUInt16();
uint timeStamp = reader.ReadUInt32();
uint symbolTablePtr = reader.ReadUInt32();
uint numberOfSymbols = reader.ReadUInt32();
ushort optionalHeaderSize = reader.ReadUInt16();
ushort characteristics = reader.ReadUInt16();
// Read PE magic number from Standard Fields to determine format.
PEFormat peFormat = (PEFormat)reader.ReadUInt16();
if (peFormat != PEFormat.PE32 && peFormat != PEFormat.PE32Plus)
return null;
// Read the 15th Data Dictionary RVA field which contains the CLI header RVA.
// When this is non-zero then the file contains CLI data otherwise not.
stream.Position = peHeaderPtr + (peFormat == PEFormat.PE32 ? 232 : 248);
uint cliHeaderRva = reader.ReadUInt32();
if (cliHeaderRva == 0)
return new CorFlagsReader(0,0,0, peFormat);
// Read section headers. Each one is 40 bytes.
// 8 byte Name
// 4 byte Virtual Size
// 4 byte Virtual Address
// 4 byte Data Size
// 4 byte Data Pointer
// ... total of 40 bytes
uint sectionTablePtr = peHeaderPtr + 24 + optionalHeaderSize;
Section[] sections = new Section[numberOfSections];
for (int i = 0; i < numberOfSections; i++)
{
stream.Position = sectionTablePtr + i * 40 + 8;
Section section = new Section();
section.VirtualSize = reader.ReadUInt32();
section.VirtualAddress = reader.ReadUInt32();
reader.ReadUInt32();
section.Pointer = reader.ReadUInt32();
sections[i] = section;
}
// Read parts of the CLI header.
uint cliHeaderPtr = ResolveRva(sections, cliHeaderRva);
if (cliHeaderPtr == 0)
return null;
stream.Position = cliHeaderPtr + 4;
ushort majorRuntimeVersion = reader.ReadUInt16();
ushort minorRuntimeVersion = reader.ReadUInt16();
uint metadataRva = reader.ReadUInt32();
uint metadataSize = reader.ReadUInt32();
CorFlags corflags = (CorFlags)reader.ReadUInt32();
// Done.
return new CorFlagsReader(majorRuntimeVersion, minorRuntimeVersion, corflags, peFormat);
}
答案 2 :(得分:0)
您需要的大部分信息都可以从System.Reflection AssemblyName对象中获得。
此代码将获取System.Web.dll
的强名称,处理器体系结构,版本和公钥标记:
var n = System.Reflection.AssemblyName.GetAssemblyName(@"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.web.dll");
Console.WriteLine(String.Format("{0} {1} {2} {3}", n.Name, n.Version, n.ProcessorArchitecture, BitConverter.ToString(n.GetPublicKeyToken())));
输出:
System.Web 4.0.0.0 Amd64 B0-3F-5F-7F-11-D5-0A-3A
如果你不想为此编写程序,你也可以使用a PowerShell script做同样的事情:
[reflection.assemblyname]::GetAssemblyName("${pwd}\System.Web.dll") | fl