Montagem (CLI) - Assembly (CLI)

Definido pela Microsoft para uso em versões recentes do Windows , um assembly na Common Language Infrastructure (CLI) é uma biblioteca de código compilado usada para implantação, controle de versão e segurança. Existem dois tipos: assemblies de processo ( EXE ) e assemblies de biblioteca ( DLL ). Uma montagem de processo representa um processo que usará classes definidas em montagens de biblioteca. Os assemblies CLI contêm código em CIL , que geralmente é gerado a partir de uma linguagem CLI e, em seguida, compilado em linguagem de máquina em tempo de execução pelo compilador just-in-time . Na implementação do .NET Framework , este compilador faz parte do Common Language Runtime (CLR).

Uma montagem pode consistir em um ou mais arquivos. Os arquivos de código são chamados de módulos. Um assembly pode conter mais de um módulo de código. E uma vez que é possível usar diferentes linguagens para criar módulos de código, é tecnicamente possível usar várias linguagens diferentes para criar um assembly. O Visual Studio, entretanto, não oferece suporte ao uso de linguagens diferentes em um assembly.

Nomes de montagem

O nome de uma montagem consiste em quatro partes

  1. O nome curto. No Windows, é o nome do arquivo Portable Executable (PE) sem a extensão.
  2. A cultura. Este é um identificador RFC 1766 da localidade para o assembly. Em geral, os conjuntos de bibliotecas e processos devem ser neutros em relação à cultura; a cultura só deve ser usada para montagens de satélites .
  3. A versão. Este é um número pontilhado composto de quatro valores - maior, menor, construção e revisão.
  4. Um token de chave pública . Este é um hash de 64 bits da chave pública que corresponde à chave privada usada para assinar o assembly. Diz-se que uma montagem assinada tem um nome forte .

O token de chave pública é usado para tornar o nome do assembly exclusivo. Assim, dois assemblies de nome forte podem ter o mesmo nome de arquivo PE e ainda assim a CLI os reconhecerá como assemblies diferentes. O sistema de arquivos do Windows ( FAT32 e NTFS ) reconhece apenas o nome do arquivo PE, portanto, dois assemblies com o mesmo nome de arquivo PE (mas cultura, versão ou token de chave pública diferentes) não podem existir na mesma pasta do Windows. Para resolver esse problema, a CLI apresenta o GAC ( Global Assembly Cache ) que é tratado como uma única pasta pelo tempo de execução, mas é realmente implementado usando pastas aninhadas do sistema de arquivos.

Para evitar ataques de spoofing , onde um cracker tentaria fazer passar um assembly parecendo outra coisa, o assembly é assinado com uma chave privada. O desenvolvedor do assembly pretendido mantém a chave privada em segredo, então um cracker não pode ter acesso a ela nem simplesmente adivinhá-la. Assim, o cracker não pode fazer sua montagem se passar por outra coisa, faltando a possibilidade de assiná-la corretamente após a alteração. Assinar o assembly envolve pegar um hash de partes importantes do assembly e, em seguida, criptografar o hash com a chave privada. O hash assinado é armazenado no assembly junto com a chave pública. A chave pública irá descriptografar o hash assinado. Quando o CLR carrega um assembly de nome forte, ele gera um hash do assembly e o compara com o hash descriptografado. Se a comparação for bem-sucedida, isso significa que a chave pública no arquivo (e, portanto, o token de chave pública) está associada à chave privada usada para assinar o assembly. Isso significa que a chave pública no assembly é a chave pública do editor do assembly e, portanto, um ataque de falsificação é impedido.

Versões de montagem

Os assemblies CLI podem ter informações de versão, permitindo-lhes eliminar a maioria dos conflitos entre aplicativos causados ​​por assemblies compartilhados. No entanto, isso não elimina todos os conflitos de versão possíveis entre os assemblies.

Assemblies e segurança CLI

A segurança de acesso ao código CLI é baseada em conjuntos e evidências . A evidência pode ser qualquer coisa deduzida da montagem, mas normalmente é criada a partir da fonte da montagem - se a montagem foi baixada da Internet, uma intranet ou instalada na máquina local (se a montagem for baixada de outra máquina, será ser armazenado em um local em área restrita dentro do GAC e, portanto, não é tratado como instalado localmente). As permissões são aplicadas a assemblies inteiros, e um assembly pode especificar as permissões mínimas necessárias por meio de atributos personalizados (consulte os metadados CLI ). Quando o assembly é carregado, o CLR usará a evidência do assembly para criar um conjunto de permissões de uma ou mais permissões de acesso ao código. O CLR irá então verificar se este conjunto de permissões contém as permissões necessárias especificadas pelo assembly.

O código CLI pode executar uma solicitação de segurança de acesso ao código. Isso significa que o código executará alguma ação privilegiada apenas se todos os assemblies de todos os métodos na pilha de chamadas tiverem a permissão especificada. Se um assembly não tiver permissão, uma exceção de segurança será lançada.

O código CLI também pode executar a demanda vinculada para obter a permissão da pilha de chamadas. Nesse caso, o CLR examinará apenas um método na pilha de chamadas na posição TOP para a permissão especificada. Aqui, o walk-through da pilha está vinculado a um método na pilha de chamadas pelo qual o CLR assume que todos os outros métodos em CALL STACK têm a permissão especificada. A montagem é uma combinação de arquivo METADATA e MSIL.

Assembléias de satélite

Em geral, os assemblies devem conter recursos de cultura neutra. Se você deseja localizar seu assembly (por exemplo, usar cadeias de caracteres diferentes para localidades diferentes), você deve usar assemblies satélites - assemblies especiais, apenas de recursos. Como o nome sugere, um satélite está associado a uma montagem chamada montagem principal. Esse assembly (digamos, lib.dll) conterá os recursos neutros (que a Microsoft diz ser inglês internacional , mas implica ser inglês americano). Cada satélite tem o nome da biblioteca associada anexado a .resources (por exemplo lib.resources.dll). O satélite recebe um nome de cultura não neutro, mas como isso é ignorado pelos sistemas de arquivos Windows existentes (FAT32 e NTFS), isso significa que pode haver vários arquivos com o mesmo nome PE em uma pasta. Como isso não é possível, os satélites devem ser armazenados em subpastas na pasta do aplicativo. Por exemplo, um satélite com recursos em inglês do Reino Unido terá um nome CLI de "lib.resources Version = 0.0.0.0 Culture = en-GB PublicKeyToken = null", um nome de arquivo PE de lib.resources.dll e será armazenado em uma subpasta chamada en-GB.

Os satélites são carregados por uma classe CLI chamada System.Resources.ResourceManager . O desenvolvedor deve fornecer o nome do recurso e informações sobre o assembly principal (com os recursos neutros). A classe ResourceManager lerá a localidade da máquina e usará essas informações e o nome do assembly principal para obter o nome do satélite e o nome da subpasta que o contém. ResourceManager pode então carregar o satélite e obter o recurso localizado.

Referenciando assemblies

Pode-se fazer referência a uma biblioteca de código executável usando o sinalizador / reference do compilador C #.

Atraso na assinatura de uma assembleia

Os assemblies compartilhados precisam fornecer um nome forte para identificar exclusivamente o assembly que pode ser compartilhado entre os aplicativos. A nomenclatura forte consiste no token de chave pública, cultura, versão e nome do arquivo PE. Se for provável que um assembly seja usado para o propósito de desenvolvimento que é um assembly compartilhado, o procedimento de nomenclatura forte contém apenas a geração de chave pública. A chave privada não é gerada nesse momento. Ele é gerado apenas quando o assembly é implantado.

Linguagem de uma montagem

A montagem é construída com o código CIL, que é uma linguagem intermediária. A estrutura converte internamente o CIL ( bytecode ) em código de montagem nativo . Se tivermos um programa que imprime "Hello World", o código CIL equivalente para o método é:

 .method private hidebysig static void  Main(string[] args) cil managed {
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldstr      "Hello World"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ret } // end of method Class1::Main

O código CIL carrega a String na pilha, chama a função WriteLine e retorna.

Veja também

Referências