Mein Projekt muss .c- und .dll-Dateien überprüfen. es kombiniert diese Informationen, um zu bestimmen, was es anrufen soll und ruft es dann an.Programmgesteuertes Aufrufen aufrufbarer DLL-Funktionen
Ich muss die DLLs überprüfen, welche DLL welche Funktion hat. Ich bin so weit gegangen, die DLL in den Speicher zu mappen, ohne sie zu initialisieren. Jetzt muss ich den Header etwas zuordnen, damit ich den Abschnitt lesen kann, der die aufrufbaren Namen enthält.
Wie kann ich das tun? so weit dies ist der Code:
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
public static string[] GetFKTNames(string dll)
{
IntPtr lib = LoadLibraryEx(dll, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
//INDICATES WHAT I WANT TO DO, BUT DOES NOT WORk
//Header header = GetHeader(lib);
//Unload(lib);
//return header.Names;
}
EDIT # 2:
i ein wenig Fortschritte gemacht, und beenden Sie es für heute ... gibt es 4 freie Tage hier in Deutschland kommen ...
Ich bin mir nicht ganz sicher, ob das Marshalling korrekt ist - ich hatte keine Möglichkeit es zu testen. Ich würde gerne ein Buch zu diesem Thema lesen - also kommentiere bitte, wenn du ein gutes Buch kennst, das erklärt, wie dieser Headerstuff funktioniert und welche verschiedenen Header es gibt.
private static List<string> ListDLLFunctions(string sADllName)
{
List<string> names = new List<string>();
IntPtr LoadedImage = LoadLibraryEx(sADllName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
IMAGE_NT_HEADERS header = (IMAGE_NT_HEADERS) Marshal.PtrToStructure(libPtr, typeof(IMAGE_NT_HEADERS));
// ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)
// ImageDirectoryEntryToData(LoadedImage.MappedAddress,
// false, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);
// if (ImageExportDirectory != NULL)
// {
// dNameRVAs = (DWORD *)ImageRvaToVa(LoadedImage.FileHeader,
// LoadedImage.MappedAddress,
// ImageExportDirectory->AddressOfNames, NULL);
// for(size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
// {
// sName = (char *)ImageRvaToVa(LoadedImage.FileHeader,
// LoadedImage.MappedAddress,
// dNameRVAs[i], NULL);
// slListOfDllFunctions.push_back(sName);
// }
// }
FreeLibrary(LoadedImage);
return names;
}
static void Main(string[] args)
{
List<string> names = ListDLLFunctions("KERNEL32.DLL");
}
Nachdem ich diese Funktion für ein paar kleine Projekte benutzt habe, bin ich auf das Problem gestoßen, dass nicht alle DLLs auf diese Weise entfernt werden können. Ich hatte Probleme, indem ich nur zwei verschiedene Compiler verwendete. Es gibt also viel zu tun ... aber ich werde meine Herangehensweise an das Kernproblem ändern. – Johannes