Jan 21, 2016

Finding references to assemblies


The current task at my job requires me to patch (a fancy name for change) .NET assemblies, sometimes adding new members, sometimes changing type references, sometimes messing with the method implementation and sometimes doing a bit of all.

From time to time I need to find out why a assembly (A) has a reference to some other assembly (B); basically what I need to know is which type/member(s) from assembly B is being used by assembly A.

One particularly easy way (IMO) is to simply ildasm assembly A and look for references to B; in order to accomplish that you can do something like:


c:\temp> ildasm /all /out=c:\temp\assembly-a.il assembly-a.dll

After you generated the CIL from your assembly your next step is to search for the name of the assembly you want to find references for (in this example, Assembly_B); you'll find one or more (actually one for each referenced assembly) sessions in the IL code like:

.assembly extern /*23000005*/ Assembly_B
{

}

Now, you can either search for the name Assembly_B or by the number to its left (in this case 23000005)

.assembly extern /*23000005*/ Assembly_B
{
  .ver 1:0:0:0
}
.
.
.

IL_0006:  /* 28   | (0A)0000B2       */ call instance void [Assembly_B/*23000005*/]NamespaceName.TypeName::DoSomething()
.
.
.

In this example assembly A is using the instance method DoSomething() from type TypeName in namespace NamespaceName from assembly B.

What do you think?

Happy coding.

(Leia este post em português)

Encontrando referências para um assembly específico


Atualmente meu trabalho tem envolvido a manipulação / modificação de assemblies .NET, as vezes incluindo novos membros, outras mudando referências para tipos e/ou membros, etc.

Invariavelmente, de tempos em tempos acabo necessitando descobrir porque um assembly específico (vamos chamá-lo de A) possui uma referência para outro assembly (B); basicamente o que tenho que descobrir é quais tipos/membros do assembly B estão sendo referenciados (usados) pelo assembly A.

Existem várias formas de obter tal informação; na minha opinião, a mais simples, é converter, através do aplicativo 
 ildasm que vem junto com o .NET Framework, o assembly em questão (A) para IL e procurar por referências para o assembly B; para tanto você pode fazer algo como:

c:\temp> ildasm /all /out=c:\temp\assembly-a.il assembly-a.dll

Depois de gerar o IL do assembly desejado seu próximo passo é procurar pelo nome do assembly que você deseja encontrar referências (neste exemplo, Assembly_B); você verá uma ou mais (para ser mais preciso, uma entrada para cada assembly referenciado) 
sessões parecidas com:
.assembly extern /*23000005*/ Assembly_B
{

}

Agora você pode tanto procurar pelo nome do assembly (Assembly_B) ou pelo número que se encontra à sua esquerda (neste exemplo 23000005)

.assembly extern /*23000005*/ Assembly_B
{
  .ver 1:0:0:0
}
.
.
.

IL_0006:  /* 28   | (0A)0000B2       */ call instance void [Assembly_B/*23000005*/]NamespaceName.TypeName::DoSomething()
.
.
.


Como você pode notar no trecho de IL acima, no offset 06 do IL existe uma referência ao método DoSomething() da classe TypeName, definida no namespace 'Namespace' no assembly Assembly_B.

Happy coding.

(read this post in english)