Ich habe nach einem Weg gesucht, um alle Zeichenfolgen zu ermitteln, die Funktionsnamen in einer DLL zuordnen.
Damit meine ich alle Zeichenfolgen, für die Sie GetProcAddress aufrufen können. Wenn Sie einen Hex-Dump einer DLL erstellen, sind die Symbole (Strings) vorhanden, aber ich denke, dort muss ich einen Systemaufruf ausführen, um diese Namen zu erhalten.
Es ist ein bisschen Arbeit, aber Sie können dies programmgesteuert mit der Bibliothek " DbgHelp " von Microsoft tun.
Debugging-Anwendungen für Microsoft .Net und Microsoft Windows, von John Robbins ist ein ausgezeichnetes (wenn auch etwas älteres) Buch, das Details zur Verwendung und vollständige Quelle enthält. Und Sie können es bei Amazon günstig abholen!
Wenn Sie über MS Visual Studio verfügen, gibt es ein Befehlszeilenprogramm namens DUMPBIN.
dumpbin/exports <nameofdll>
Es gibt drei verschiedene Arten von DLLs unter Windows:
Klassische DLLs, die jede verfügbare Funktion in der Exporttabelle der DLL anzeigen. Sie können dumpbin.exe oder depend.exe von Visual Studio oder den kostenlosen Dependance Walker verwenden, um diese Typen zu untersuchen. Matt Pietrek hat viele Artikel und Hilfsprogramme zum Auffinden von Win32 PE-Dateien geschrieben. Werfen Sie einen Blick auf seine Klassiker MSDN Magazine-Artikel . C++ - DLLs, die exportierte Klassen enthalten, exportieren jede Methode in der Klasse. Leider werden die entstellten Namen exportiert, so dass die Ausgabe von dumpbin praktisch nicht lesbar ist. Sie müssen ein Programm wie vc ++ _ filt.exe verwenden, um die Ausgabe zu entwirren.
COM-DLLs, die COM-Objekte verfügbar machen. Diese DLLs stellen einige handelsübliche exportierte Funktionen (DllRegisterServer usw.) bereit, mit denen das COM-System Objekte instanziieren kann. Es gibt viele Dienstprogramme, die diese DLLs anzeigen können. Wenn sie jedoch nicht über eingebettete Typbibliotheken verfügen, kann es schwierig sein, sie zu untersuchen. 4Entwickler haben eine Reihe guter COM/ActiveX-Tools
.NET-DLLs, die .NET-Assemblys enthalten. Normalerweise würden Sie ein Tool wie .NET Reflector verwenden, um in diese zu graben.
Edit: 4Developers-Link funktioniert nicht.
Außerdem gibt es das DEPENDs-Programm unter http://www.dependencywalker.com/
Versuchen Sie diesen (Linux) C-Code:
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
unsigned int vpe2offset(void * base, unsigned int vpe) {
unsigned int * ptr = base;
unsigned int pe_offset;
unsigned short num_sections;
pe_offset = ptr[0x3c/4]; //PE header offset
ptr = base + pe_offset; //PE header address
num_sections = ((unsigned short*)ptr)[6/2]; //Section count
ptr = ((void*)base) + 0x18 + 0x60 + 16*8 + pe_offset;//Address of first section
while (num_sections--) {
if (vpe >= ptr[0x0c/4] && vpe < ptr[0x0c/4] + ptr[0x10/4]) {
return vpe - ptr[0x0c/4] + ptr[0x14/4];
}
ptr += 0x28/4;
}
return 0;
}
void iterate_exports(void * base, int(*iterator)(char*)) {
unsigned int * ptr = base;
unsigned int pe_offset,
exports_offset,
number_of_names,
address_of_names;
pe_offset = ptr[0x3c/4];
ptr = base + pe_offset;
exports_offset = ptr[0x78/4];
ptr = base + vpe2offset(base, exports_offset);
number_of_names = ptr[0x18/4];
address_of_names = ptr[0x20/4];
ptr = base + vpe2offset(base, address_of_names);
while (number_of_names-- && iterator((char*)(base + vpe2offset(base, ptr++[0])))) {
/* Do nothing */
}
}
int print_symbol_name(char * name) {
printf("%s\n", name);
return 1;
}
int main(int argc, char const *argv[]) {
int fd;
struct stat st;
void * base;
if (argc == 1) {
printf("Usage: %s <dll>\n", argv[0]);
} else if (stat(argv[1], &st) == 0 && (fd = open(argv[1], O_RDONLY)) >= 0) {
base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (base != MAP_FAILED) {
iterate_exports(base, print_symbol_name);
munmap(base, st.st_size);
} else {
fprintf(stderr, "Could not map \"%s\".\n", argv[1]);
}
close(fd);
} else {
fprintf(stderr, "Could not open \"%s\" for reading.\n", argv[1]);
}
return 0;
}
Es folgt Referenzen innerhalb der PE-Datei und ruft schließlich für jedes exportierte Symbol eine Rückruffunktion auf. Einen Überblick über das PE-Dateiformat finden Sie hier: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
Ich kenne keine WIn32-API, um dies zu tun: Stattdessen wissen Sie (oder eines der in anderen Beiträgen erwähnten Tools), dass Sie das binäre Format einer PE-Datei kennen und die Datei lesen: siehe http://msdn.Microsoft.com/en-us/magazine/cc301808.aspx (und der Artikel erwähnte ein "PEDUMP" -Dienstprogramm).
Ich benutze dumpbinGUI , wodurch Sie die Liste der Exporte (und vieles mehr) mit einem Rechtsklick im Windows Explorer anzeigen können. dumpbin
und depends
geben Ihnen beide Listen ebenfalls.
Sie müssen den PE-Header der .dll überprüfen, da dies letztendlich auch von Windows ausgeführt wird.
Angenommen, Sie haben einen Zeiger auf den IMAGE_OPTIONAL_HEADER
der .dll (Sie können entweder die ImageNtHeader
-Funktion von dbghelp mit einem Handle auf eine über LoadLibrary
geladene .dll verwenden oder versuchen, sie selbst zu finden, wenn Sie das Layout der .dll selbst kennen) Um optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
anzusehen, suchen Sie die Exporttabelle relativ zum optionalen Header mit dem Versatz dort und gehen dann die Exporttabelle durch (es ist ein IMAGE_EXPORT_DIRECTORY
).
Für Spaß beginnt ein abwärtskompatibles PE-Bild mit einem IMAGE_DOS_HEADER
; Der Versatz zum IMAGE_NT_HEADER
ist IMAGE_DOS_HEADER::e_lfanew
und der IMAGE_OPTIONAL_HEADER
ist im NT-Header eingebettet.
es gibt ein Programm namens DLL Export Viewer, das Sie verwenden können: http://www.nirsoft.net/utils/dll_export_viewer.html
Ich muss das immer tun. Ich gehe einfach zu einer dieser Seiten. Sie hosten die Informationen, die wir normalerweise benötigen.
Sie können das Linux-Tool "objdump" auch unter Windows verwenden, müssen jedoch möglicherweise zuerst cygwin installieren.
Ich benutze die folgenden Befehle:
# feed the output to less
objdump -x nameOfThe.Dll| less
# or use egrep to filter
objdump -x /cygdrive/c/Windows/system32/user32.dll | \
egrep "^\s*\[[ [:digit:]]{4}\] \w{1,}" | less
Ich denke, Sie werden PE-Dateien analysieren und sich selbst entwirren, wenn Sie die Funktionsnamen einer unbekannten DLL in der Laufzeit oder ein extrem nutzloses System ("dumpbin") finden möchten. Zauber.
Sie sollten klarer sein, was Sie wollen.
BFD library führt das aus, was Sie wollen (und die Küchenspüle), was die Hauptkomponente mehrerer GNU - binutils-Werkzeuge ist. Ich kann nicht sicher sein, ob es zu Ihrem Problem passt.
Sie benötigen kein Werkzeug und Sie müssen kein PE analysieren. Verwenden Sie einfach die Standard-Win32-API (D).
Der Code (in C) wurde mehrmals auf Adv.Win32 veröffentlicht ( News: //comp.os.ms-windows.programmer.win32) (seit 1992 ...)