I'm trying to use the dnlib library wich is part of the de4dot project to load an assembly and get the IL instructions contained on the "body" of all the methods.
I've compiled an assmebly with this VB.NET source:
Public Class Main
Public Sub testmethod(ByVal testparameter As String)
MsgBox(testparameter)
End Sub
Public Class Test2
Public Function testfunction(ByVal testparameter As String) As String
Return testparameter
End Function
End Class
End Class
I know that the compiler modifies a lot of things, but I think that the method names (in this case) will not be modified, please correct me if I'm wrong.
Then I'm trying to retrieve those methods with this code:
Imports dnlib.DotNet
Imports dnlib.DotNet.Emit
Private Sub Test_Handler() Handles MyBase.Shown
Dim asmResolver As New AssemblyResolver()
Dim modCtx As New ModuleContext(asmResolver)
' All resolved assemblies will also get this same modCtx
asmResolver.DefaultModuleContext = modCtx
' Enable the TypeDef cache for all assemblies that are loaded
' by the assembly resolver. Only enable it if all auto-loaded
' assemblies are read-only.
asmResolver.EnableTypeDefCache = True
Dim Assembly As ModuleDefMD = ModuleDefMD.Load("C:\WindowsApplication.exe")
Assembly.Context = modCtx
' Use the previously created (and shared) context
Assembly.Context.AssemblyResolver.AddToCache(Assembly)
Dim Members As IEnumerable(Of MemberRef) = Assembly.GetMemberRefs
For Each m As MemberRef In Members
If m.IsMethodRef Then
Dim Method As MethodDef = m.ResolveMethod
If Method.HasBody Then
Dim sb As New System.Text.StringBuilder
With sb
.AppendLine(String.Format("Method Name: {0}", Method.FullName))
.AppendLine()
.AppendLine(String.Format("Method Signature: {0}", Method.Signature.ToString))
.AppendLine()
.AppendLine(String.Format("Method Instructions: {0}", Environment.NewLine &
String.Join(Environment.NewLine, Method.Body.Instructions)))
End With
MessageBox.Show(sb.ToString)
End If
End If
Next
End Sub
The problem is that the only documentation of this library that I've seen is the XML documentation file and some very basic examples on the dnlib site that helped me to write the code above, but I'm not sure how to resolve/retrieve those methods 'cause I'm not doinf it properly, the code above does not resolve any method that I've compiled (testmethod and testfunction), instead that it shows me a lot of constructors (.ctor) and other methods.
What I would like to do is just perform an iteration of all the methods (privated, public, etc) contained in the source that I've compiled regardless of the numer of Classes that the project has and regardless of what class contains an specific method, to get its instructions.
It appears you are simply poking around in the Assembly, so all you get back is the stuff defined in AssemblyInfo.vb
. What you probably want to do is iterate the Types in the Assembly then drill into the members or properties defined for the one you are looking for.
This code should get you pointed in the right direction:
Dim modDef As ModuleDefMD = ModuleDefMD.Load("C:\Temp\ConsoleApplication1.exe")
For Each t As TypeDef In modDef.GetTypes
'print the Type name
Console.WriteLine(t.Name)
' stupid way to match a Type, but will work for demo purposes
If t.FullName.StartsWith("ConsoleApplication1.Module1") Then
For Each meth As MethodDef In t.Methods
' print the method name
Console.WriteLine(" Method: {0}", meth.Name)
Next
End If
Next
The output looks like this, note that your methods are listed.
<Module>
MyApplication
MyComputer
MyProject
MyWebServices
ThreadSafeObjectProvider`1
InternalXmlHelper
RemoveNamespaceAttributesClosure
Module1
Method: Main
Method: testmethod
Test2
Method: .ctor
Method: testfunction
Resources
MySettings
MySettingsProperty