2017-01-13 5 views
0

Я пытаюсь понять идентификацию DLL в GAC путем разбора сверху голосовала ответ в этом StackOverflow вопрос: What is the GAC in .NET?идентификации DLL в GAC

Писатель идет нас через структуру дерева для C: \ Windows \ assembly \ GAC_64 \ System.Data и заканчивается. , ,

Здесь вы можете увидеть версию 2.0.0.0__b77a5c561934e089 of System.Data.

Библиотека DLL идентифицируется 5 частей:

Name 
Version 
Architecture 
Culture 
Public Key 

... и это та часть, я неясными дальше. Как только я добрался до листьев дерева, как мне извлечь эти 5 частей идентификации DLL, и есть ли какое-либо отношение к названию сборки?

В примере я работаю с сборок каталогов с именами, как:

v4.0_2.0.6178.1045__d45c8e156fba2841

... и внутри этого каталога есть DLL с имя как

Ab3d.DXEngine.dll

... так как я могу извлечь пять частей его идентификации?

EDIT:

Лиф Хуан, ниже предположил, что существует способ получить доступ к ILDASM из Visual Studio. Не было встроенного способа от моего (VS 2013), но был способ ДОБАВИТЬ его, описанный здесь: http://dailydotnettips.com/2016/01/05/did-you-know-you-can-launch-ildasm-tool-from-inside-visual-studio-itself-how/ ... так что я сделал это, и когда я попытался запустить ILDASM в DLL в GAC Я получил сообщение об ошибке от ILDASM поговорки «Protected модуля - не разбирайте»

+0

Хм, эти ssemblies, кажется, не принадлежат там. V4.0 GAC хранится в c: \ windows \ microsoft.net \ assembly. Просмотрите процедуру установки. –

+0

Я их не клал. Но мой вопрос: как я могу легко извлечь пять частей, упомянутых в сообщении SO? – user316117

ответ

0

как извлечь пять частей его идентификации?

Вы можете найти их в заголовке CLR и метаданных сборки.

На самом деле каждый управляемый модуль (DLL или EXE) состоит из четырех частей:

  • PE32 или PE32 + заголовок (Информация используется Windows)
  • заголовка CLR (информация используется CLR)
  • Метаданные (Вот blog post введение этой темы).Есть в основном три типа таблиц метаданных:

    • Ассамблея Manifest (глобальная информация о сборке)
    • Определения Таблица (информация о вещах, определенных в этом модуле, например ModuleDef, TYPEDEF, MethodDef, PropertyDef)
    • Справочные таблицы (информация о вещи называют этим модулем, например AssemblyRef, ModuleRef, TypeRef, MemberRef)
  • IL код (IL-код генерируется из исходного кода)

+0

Спасибо, но не могли бы вы быть более конкретными? Есть ли простой способ увидеть их? Надеемся, что что-то меньшее, чем рабочая и машинная работа, чем создание команды _ildasm_ с полным путем и параметрами из командной строки командной строки разработчика. – user316117

+1

@ user316117 Я помню, что Visual Studio SDK поставляется с пользовательским интерфейсом ildasm, который может облегчить боль при создании команды. –

+0

Спасибо, я пробовал это - ** см. Мое редактирование на мой вопрос ** - и я запустил ILDASM и получил ошибку. Это не может быть так сложно - люди должны делать это каждый день - как это делается? – user316117

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); 
    } 
+0

Спасибо, но причина, по которой я связался с исходным вопросом и ссылался на самый ранний ответ, состоял в том, что он, казалось, показывал нам материал из командной строки, а затем завершил разговор об этих 5 атрибутах, и этот ответ получил 100 upvotes, поэтому Я принял всех, но я мог видеть связь.Я надеялся, что мне не придется писать код, чтобы увидеть базовые вещи, такие как имя и номер версии GAC DLL. Если я хочу использовать GAC DLL в качестве ссылки в программе, мне не нужно знать номер версии и архитектуру? Нужно ли людям писать программы для этого? – user316117

+0

Хорошо, если вы просто хотите имя и версию, см. Мой другой ответ, который я собираюсь опубликовать. –

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 
Смежные вопросы