J'ai été à la recherche d'un moyen d'obtenir toutes les chaînes qui mappent aux noms de fonctions dans une DLL.
J'entends par là toutes les chaînes pour lesquelles vous pouvez appeler GetProcAddress. Si vous effectuez un dump hexadécimal d'une dll, les symboles (chaînes) sont présents, mais je suppose qu'il faut un appel système pour acquérir ces noms.
Cela prend un peu de travail, mais vous pouvez le faire par programme en utilisant la bibliothèque DbgHelp de Microsoft.
Débogage d’applications pour Microsoft .Net et Microsoft Windows, par John Robbins est un excellent livre (même s’il est un peu plus ancien) qui contient les détails de l’utilisation et le source complet. Et, vous pouvez le chercher sur Amazon pour pas cher!
Si vous avez MS Visual Studio, il existe un outil de ligne de commande appelé DUMPBIN.
dumpbin/exports <nameofdll>
Il existe trois types distincts de DLL sous Windows:
DLL classiques qui exposent toutes les fonctions disponibles dans la table des exportations de la DLL. Vous pouvez utiliser dumpbin.exe ou depend.exe de Visual Studio, ou le programme free dependency walker pour examiner ces types. Matt Pietrek a écrit de nombreux articles et utilitaires permettant de creuser des fichiers Win32 PE. Découvrez ses classiques Articles de MSDN Magazine . Les DLL C++ contenant des classes exportées exporteront toutes les méthodes de la classe. Malheureusement, il exporte les noms mutilés, de sorte que la sortie de dumpbin est pratiquement illisible. Vous devrez utiliser un programme tel que vc ++ _filet.exe pour démêler la sortie.
DLL COM qui exposent des objets COM. Ces DLL exposent une poignée de fonctions exportées régulières (DllRegisterServer, etc.) permettant au système COM d'instancier des objets. De nombreux utilitaires peuvent examiner ces DLL, mais ils peuvent être assez difficiles à examiner s'ils ne possèdent pas de bibliothèques de types incorporées. 4Developers possède un certain nombre de bons outils COM/ActiveX
DLL .NET contenant des assemblys .NET. Typiquement, vous utiliseriez un outil tel que .NET Reflector pour creuser dans ces répertoires.
Edit: le lien 4Developers ne fonctionne pas.
Il existe également le programme DEPENDs à http://www.dependencywalker.com/
Essayez ceci (code Linux):
#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;
}
Il suit les références à l'intérieur du fichier PE et appelle finalement une fonction de rappel pour chaque symbole exporté. Pour un aperçu du format du fichier PE, voir: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
Je ne connais pas d'API Win32 pour le faire: vous (ou l'un des outils mentionnés dans d'autres articles) le faites en connaissant le format binaire d'un fichier PE et en lisant le fichier: voir http://msdn.Microsoft.com/en-us/magazine/cc301808.aspx (et cet article mentionnait un utilitaire "PEDUMP").
J'utilise dumpbinGUI , qui vous donne la liste des exportations (et beaucoup plus) à partir d'un clic droit dans l'Explorateur Windows dumpbin
et depends
vous donneront également les listes.
Vous devez inspecter l'en-tête PE du fichier .dll, car c'est ce que Windows fait de toute façon.
En supposant que vous ayez un pointeur sur le IMAGE_OPTIONAL_HEADER
du .dll (vous pouvez utiliser la fonction ImageNtHeader
de dbghelp avec un handle vers un .dll chargé via LoadLibrary
ou tenter de le trouver vous-même si vous connaissez vous-même la disposition du .dll), vous voudrez Pour regarder optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
, recherchez la table d'exportation par rapport à l'en-tête facultatif avec le décalage dedans, puis parcourez la table d'exportation (il s'agit d'un IMAGE_EXPORT_DIRECTORY
).
Pour les funsies, une image PE compatible avec les versions antérieures commence par un IMAGE_DOS_HEADER
; le décalage par rapport à IMAGE_NT_HEADER
est IMAGE_DOS_HEADER::e_lfanew
et le IMAGE_OPTIONAL_HEADER
est incorporé dans l'en-tête NT.
vous pouvez utiliser un programme appelé visualiseur d'exportation dll: http://www.nirsoft.net/utils/dll_export_viewer.html
Je dois toujours faire ça. Je viens d'aller sur l'un de ces sites. Ils hébergent les informations dont nous avons généralement besoin.
Vous pouvez également utiliser l'outil linux "objdump" sous Windows, mais vous devrez peut-être installer cygwin au préalable.
J'utilise les commandes suivantes:
# 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
Je suppose que vous allez finir par analyser le fichier PE et vous démêler vous-même si vous voulez trouver les noms de fonction d'une DLL inconnue dans le système d'exécution ou d'un système extrêmement inutile ("dumpbin"); la magie.
Vous devriez être plus clair sur ce que vous voulez.
BFD library fait ce que vous voulez (et l’évier de la cuisine), qui est le composant principal de plusieurs outils GNU binutils. Je ne peux pas être sûr que cela conviendra à votre problème.
Vous n'avez besoin d'aucun outil et vous n'avez pas besoin d'analyser PE. Il suffit d’utiliser l’API Win32 standard (D)
Le code (en C) a été publié à plusieurs reprises sur Adv.Win32 api ng ( News: //comp.os.ms-windows.programmer.win32) (depuis 1992)