GCC et msvcrt.dll [Résolu]

Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
- - Dernière réponse : cs_Nebula
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
- 14 sept. 2004 à 21:53
Je viens de faire une remarque pour le moins préoccupante...

J'utilise GCC (3.4.2) pour compiler des applications Win32, et j'ai remarqué en dumpant les exécutables générés qu'il y avait toujours des imports provenant de msvcrt.dll, alors que je n'utilise QUE des fonctions de l'API !

Par exemple, ce bête code
#include <windows.h>

INT WINAPI WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPTSTR CmdLine, INT CmdShow) {
  return 0;
}
compilé ainsi
gcc -s toto.c -o toto.exe -mwindows
a les imports suivants :
	DLL Name: msvcrt.dll
vma:  Hint/Ord Member-Name Bound-To
51a8	   39  __getmainargs
51b8	   60  __p__environ
51c8	   62  __p__fmode
51d8	   80  __set_app_type
51ec	  121  _cexit
51f8	  233  _iob
5200	  350  _onexit
520c	  388  _setmode
5218	  533  abort
5220	  540  atexit
522c	  560  fflush
5238	  569  fprintf
5244	  575  free
524c	  626  malloc
5258	  656  signal


Le plus bizarre étant que lorsque je désassemble WinMain avec GDB, j'obtiens ce code, parfaitement clean :
(gdb) disassemble WinMain
Dump of assembler code for function WinMain:
0x401290 <WinMain>:     push   ebp
0x401291 <WinMain+1>:   mov    ebp,esp
0x401293 <WinMain+3>:   mov    eax,0x0
0x401298 <WinMain+8>:   pop    ebp
0x401299 <WinMain+9>:   ret    0x10
End of assembler dump.
Aucune référence aux fonctions sus-nommées, donc...

Y'a t'il un moyen de faire sauter çà (où de trifouiller la table d'imports pour vérifier si ces fonctions sont bien utilisées) ? Je savais que GCC s'appuyait sur cette DLL pour les applications console, mais j'ignorais que çà concernait aussi Win32...
Afficher la suite 

9 réponses

Meilleure réponse
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
3
Merci
Allez, j'ai fini par arriver à une solution pleinement satisfaisante, sans même devoir recompiler le compilateur : il suffit de jouer sur les bonnes options (et de lire les sources pour trouver ce qui est exploitable)...

Donc, comment se passer de MSVCRT.DLL avec MinGW et générer du code Win32 natif (allégé de 5Ko en prime):
1) compiler avec les options suivantes: -nostartfiles -nodefaultlibs -nostdlib
2) remplacer "int main(void)" par "void mainCRTStartup(void)"
"int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)" par "void WinMainCRTStartup(void)"
"BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)" par "BOOL WINAPI DllMainCRTStartup(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)"
3) pour avoir à nouveau argv et lpCmdLine, utiliser GetCommandLine
4) pour avoir les HCONSOLE de stdin/out/err, utiliser GetStartupInfo
5) pour printf et assimilées, utiliser FormatMessage et/ou WriteConsole (WriteFile pour les fichiers)
6) l'import automatique de kernel32/user32 étant désactivé, il faudra les lier manuellement
7) et voilà ! çà devrait fonctionner pour d'autres compilateurs (testé sur MSVC++ 6.0)

Bien sûr, aucune fonction de la CRT ne doit être utilisée, puisqu'elle n'est plus initialisée (memset semble marcher convenablement, toutefois)... Et il faut utiliser ExitProcess pour retourner le code d'erreur !

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 205 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_Nebula
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
13
0
Merci
Salut Nebula,
oui pas normal du tout, un prog GUI ne devrait avoir de references que sur le kernel win32.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
0
Merci
Salut BruNews :)

J'ai trouvé ce qui clochait, en fait WinMain est localisée en 0x00401290 et le programme démarre en 0x00401240, qui correspond à ceci :
(gdb) disassemble 0x00401240
Dump of assembler code for function WinMainCRTStartup:
0x401240 <WinMainCRTStartup>:   push   ebp
0x401241 <WinMainCRTStartup+1>: mov    ebp,esp
0x401243 <WinMainCRTStartup+3>: sub    esp,0x8
0x401246 <WinMainCRTStartup+6>: mov    DWORD PTR [esp],0x2
0x40124d <WinMainCRTStartup+13>:        call   ds:0x4050e0
0x401253 <WinMainCRTStartup+19>:        call   0x401100 <__mingw_CRTStartup>
0x401258 <WinMainCRTStartup+24>:        nop
0x401259 <WinMainCRTStartup+25>:        lea    esi,[esi*1]
End of assembler dump.


Je change de compilateur, à moins de trouver une alternative à ce caca... Dommage.
Commenter la réponse de cs_Nebula
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
13
0
Merci
Rien de tel que VS pour compiler du Windows.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
0
Merci
Bon j'ai trouvé un truc TRES intéressant :
gcc -g toto.c -o toto -nostartfiles -mwindows
C:\GCC\BIN\..\lib\gcc\mingw32\3.4.2\..\..\..\..\mingw32\bin\ld.exe: warning: cannot find entry symbol _WinMainCRTStartup
; defaulting to 00401000


Avec cette option -nostartfiles, on zappe msvcrt.dll et le code d'initialisation de la CRT, en gagnant 3Ko en prime...

Le warning sur la fonction introuvable peut être ignoré en paix, j'ai vérifié avec GDB, la nouvelle adresse correspond à celle de WinMain.

Pas besoin de changer mes habitudes, donc :-)
Commenter la réponse de cs_Nebula
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
13
0
Merci
Alors j'ajoute: rien de tel que Nebula !!!

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
0
Merci
J'ai parlé trop vite : çà fonctionne très bien sur ce code simpliste, mais aucune de mes applis ne veut plus compiler après...

J'ai lancé un thread sur le forum de MinGW, on verra bien s'ils ont une solution (l'url pour ceux que çà pourrait intéresser : http://sourceforge.net/forum/forum.php?thread_id=1144206&forum_id=7134 )
Commenter la réponse de cs_Nebula
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
13
0
Merci
Ben faut vraiment avoir envie...

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
790
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
0
Merci
C'est clair... Heureusement que le jeu en valait la chandelle, j'ai failli désespérer %-6
Commenter la réponse de cs_Nebula