Question

Ma question n'est pas exactement la même chose que celle-ci (ce n'est pas théorique, il y a seulement un thread principal sans boucle de message, InitInstance et ExitInstance ne constituent pas des appels appropriés).

J'utilise une application console sans boucle de message; cette application charge un exe avec la fonction LoadLibrary, de sorte qu'il puisse utiliser ses fonctions exportées. Mauvaise nouvelle: la fonction DllMain de l'exe n'est pas appelée (et j'ai vérifié les tables de symboles, en utilisant un fichier def, DllMain apparaît correctement); la doc dit qu'elle est appelée si le module chargé est une DLL (aussi mauvais).

Quelles sont les conditions (si elles existent) qui pourraient conduire à l'exécution de la fonction DllMain de l'exe lorsque LoadLibrary est appelée (et peut-être à nouveau lorsque FreeLibrary est appelée)?

Cordialement

Était-ce utile?

La solution

La condition la plus évidente est que le processus appelant LoadLibrary () obtienne explicitement GetProcAddress ("DllMain"), puis l'appelle.

Autres conseils

Les conditions sont les suivantes:

1) Le binaire en cours de chargement a été compilé en tant que DLL (lorsque vous utilisez gcc / ld, cela signifie que vous utilisez l’option - shared ; Si vous utilisez - shared , le fichier résultant être une dll, et ne fonctionnera pas, voir ci-dessous)

2) IMAGE_FILE_DLL est défini dans l'en-tête du fichier PE du fichier binaire en cours de chargement. S'il est défini, le fichier est une dll et l'éditeur de liens Windows appellera sa fonction DllMain () lorsqu'il liera ce fichier à votre programme (peu importe la façon dont il est lié - LoadLibrary () au moment de l'exécution ou -nombibliothèque au moment de la compilation). Pour cela, le fichier doit également satisfaire (1). Mais avec cet indicateur, le fichier binaire en cours de chargement ne sera pas exécutable. Si IMAGE_FILE_DLL n'est pas défini, DllMain () ne sera pas appelé lorsque le fichier sera chargé dans votre programme.

La compilation de dll avec - shared , puis la suppression manuelle de IMAGE_FILE_DLL de son en-tête (en utilisant un éditeur hexadécimal) ne fonctionnera pas. Lorsque vous l'exécutez, seul DllMain () sera exécuté et fdwReason sera un nombre non défini ( 0x28ffd4 sur ma machine).

Mettre à jour

Tous les fichiers DLL et EXE sur Windows sont des fichiers PE. La différence réside dans la façon dont ils sont liés et les indicateurs définis dans leurs en-têtes. C’est pourquoi j’écris fichier en cours de chargement , et non dll en cours de chargement .

Le dernier paragraphe décrit également le scénario dans lequel vous compilez le fichier en tant que dll, puis le convertissez en exe en jouant avec son en-tête. Ça ne marche pas.

Nommer n’a rien à voir avec cela (vous pouvez choisir n’importe quel nom et avec quelques bricolages pexports + dlltool , vous pouvez créer une bibliothèque d’importation pour un fichier .exe et pouvoir le lier en tant que -lexenamewithoutextension

Pour clarifier:

  • si vous le compilez sans - shared :
    • IMAGE_FILE_DLL ne sera pas défini dans ce fichier, il sera exécutable, mais DllMain () ne sera PAS appelé lorsque vous le lierez.
  • si vous le compilez avec - shared :
    • IMAGE_FILE_DLL sera défini dans celui-ci, il ne sera PAS exécutable, mais DllMain () sera appelé lorsque vous le lierez.
  • si vous le compilez sans - shared , activez-le l'indicateur IMAGE_FILE_DLL manuellement:
    • il ne sera plus exécutable et aucun DllMain () ne sera appelé lorsque vous le lierez.
  • si vous le compilez avec - shared , désactivez l'indicateur IMAGE_FILE_DLL manuellement:
    • il sera exécutable, mais DllMain () sera exécuté à la place de main (), et DllMain () ne sera PAS appelé lorsque vous le lierez.

En effet, le nom " DllMain " de la fonction est complètement ignorée par Windows (l'ancienne documentation de Windows NT 3.x sur l'API Windows l'indiquait explicitement).

Quand une DLL est chargée, la fonction n'est pas appelée DllMain (), mais la fonction située au point d'entrée du fichier est appelée.

Bien sûr, l'éditeur de liens créera le fichier DLL de manière à ce que DllMain () soit cette fonction.

Cependant, pour les fichiers EXE, la fonction d’entrée (qui appellera WinMain ()) est située au point d’entrée.

Il est donc évident que Windows ne peut pas appeler cette fonction lors du chargement du fichier EXE en tant que DLL.

Compléter la bonne réponse de MSalters :

Dans ce cas, appelez le "faux". DllMain avec DLL_XXX_ATTACH juste après LoadLibrary et avec DLL_XXX_DETACH juste avant FreeLibrary et effectuez manuellement les autres appels.

Une autre implémentation suivante consisterait à créer et à charger une DLL d'interface capable de rappeler automatiquement le fichier EXE sur son faux DllMain (je ne sais pas si cela pourrait fonctionner); mais cela peut être plus compliqué que d'appeler manuellement le faux DllMain dans un certain nombre de cas. (impossible de LoadLibrary dans un DllMain)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top