Reputation: 81
I am writing a utility that disassembles dll/exe files written in c#, and then scans all types inside this file for the presence of methods imported from an unmanaged DLL. I need to get information about each imported method, including the name/path of the DLL from which this method is imported, that is, the value of the first argument of the DllImport attribute. Let's assume that there is such a function declaration in the dll/exe file:
[DllImport("C:\\TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void HelloWorld();
I am new to reflection and am trying to use PEReader
to view all types and search for functions imported from DLL. I'm calling GetImport()
from the System.Reflection.Metadata.MethodDefinition
to determine whether the current MethodDefinition is an imported method. Via GetImport().Attributes
I hope to get all the DllImport parameters, including the path of this DLL, but this does not give the desired result:
using (var fileStream = new FileStream(pathToBinary, FileMode.Open, FileAccess.Read))
{
using (var peReader = new PEReader(fileStream))
{
var mdReader = peReader.GetMetadataReader();
foreach (var typeHandler in mdReader.TypeDefinitions)
{
var typeDef = mdReader.GetTypeDefinition(typeHandler);
foreach (var methodHandler in typeDef.GetMethods())
{
var methodDef = mdReader.GetMethodDefinition(methodHandler);
var import = methodDef.GetImport();
if(import.Module.IsNil)
{
continue;
}
//Returns "CallingConventionCdecl" but not ""C:\\TestDll.dll," CallingConventionCdecl":
var dllImportParameters = import.Attributes.ToString();
}
}
}
}
That is, GetMethod().Attributes
returns all DLLImport parameters except the library name/path from which the method is imported.
How do I get the DLL path from the first argument of DllImport?
Upvotes: 1
Views: 693
Reputation: 81
I found a solution to my problem. So import
has a Module
property that returns an instance of System.Reflection.Metadata.ModuleReferenceHandle
. With MetaDataReader.GetModuleReference(moduleReferenceHandle)
it can be converted to System.Reflection.Metadata.ModuleReference
. In turn, an instance of ModuleReference
has a Name
property that returns StringHandle
and can also be converted to string using MetaDataReader.GetString(stringHandle)
. This is the name/path of the DLL.
Full resolution of the issue:
string dllPath = mdReader.GetString(mdReader.GetModuleReference(import.Module).Name);
Upvotes: 2