[win32] .exe met exports, imports worden niet geladen.

Pagina: 1
Acties:

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Ik heb een executable die een heleboel ingewikkelde dingen doet. Om integratie met andere tools mogelijk te maken heb ik een paar geexporteerde functies toegevoegd:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// An exported function to be used by external tools.
extern "C"
_declspec(dllexport) int _cdecl HavenizeEx(
    const char* baseDir,
    const char* inFile,
    const char* outFile,
    const char* cachePath,
    int editable, // 0 = not editable, 1= editable
    int endian, // 0 = native endian, 1= little endian, 2= big endian
    const char* settingsDir
    )
{
    return 42;
}



Vervolgens probeer ik vanuit een andere applicatie (c#) die executable in te laden, en dat lukt:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        [DllImport("havenizer.exe",
           EntryPoint = "HavenizeEx",
            CharSet = CharSet.Ansi,
            ExactSpelling = false,
            CallingConvention = CallingConvention.Cdecl)]
        public static extern int Havenize(
            string basePath,
            string inFile,
            string outFile,
            string cachePath,
           [MarshalAs(UnmanagedType.I4)] Endianness endianness,
           [MarshalAs(UnmanagedType.I4)] BuildType editable,
            string settingsDir
        );


Het resulterende programma draait feilloos en de call returnt netjes 42. Zodra ik echter iets zinnigs probeer te doen krijg ik een groot aantal 'System.AccesViolation's, die niet gevangen worden door de c# debugger (zelfs niet in mixed mode).
Met een externe debugger heb ik uitgevogeld dat het mis gaat zodra mijn functie GetModuleHandleA (uit kernel32.dll) aanroept. GetModuleHandleA verwijst namelijk naar een adres dat niet geladen is. Om de een of andere reden worden voor mijn executable geen imports gelezen. Hierdoor is mijn importstable leeg, en jump ik naar een niet-bestaand adres, dat een accesviolation oplevert.
Als ik mijn applicatie link als DLL, dan wordt de import-table wel netjes geladen, en draait mijn applicatie gewoon goed. Helaas heb ik de applicatie standalone nodig en moet dat per se het zelfde bestand zijn.

Bestaat er misschien de mogelijkheid om de importtable achteraf in te laden, of kan ik er voor zorgen dat die importtable gewoon geladen wordt?

Localhost, sweet localhost


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zit het probleem niet in het feit dat je string objects meegeeft terwijl de functie const char *'s verwacht? Ergo, moet je daar ook geen speciale marshalling voor doen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Nee, daar ligt het niet aan - met mijn debugger zie ik het volgende:

Als het als EXE gecompileerd is:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
extern "C"
_declspec(dllexport) int _cdecl HavenizeEx(
    const char* baseFolder,
    const char* inFile,
    const char* outFile,
    const char* cachePath,
    int editable,
    int endian,
    const char* settingsDir
    )
{
    HMODULE h = GetModuleHandleA(0);
031E9E30  push        0    
031E9E32  call        dword ptr ds:[463050h] 


Als het als DLL gecompileerd is:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
extern "C"
_declspec(dllexport) int _cdecl HavenizeEx(
    const char* baseFolder,
    const char* inFile,
    const char* outFile,
    const char* cachePath,
    int editable,
    int endian,
    const char* settingsDir
    )
{
    HMODULE h = GetModuleHandleA(0);
10047650  push        0    
10047652  call        dword ptr [__imp__GetModuleHandleA@4 (1005D0B0h)] 


Zoals je wellicht opmerkt, ontbreekt bij de EXE-variant het symbool voor getmodulehandle. Dat is dus een indicatie dat de importtable leeg is.

edit:

Overigens heb ik al wel dingetjes geprobeerd te doen met die strings (strlen). Dat werkt gewoon goed.

[ Voor 12% gewijzigd door kvdveer op 12-10-2005 11:55 ]

Localhost, sweet localhost


  • Glow
  • Registratie: November 2000
  • Laatst online: 22-07-2023

Glow

46&2 are just ahead of me.

Je zou kunnen proberen met de hand (LoadLibrary() / GetProcAdress()) naar de DLL kunnen linken waar GetModuleHandle() in zit.

Of, geef gewoon de HINSTANCE mee als param aan de functie :) (/me = radeloos)

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
LoadLibrary laadt de importtable niet, dus heb ik er niets aan. Al mijn code gaat er vanuit dat de importtable geladen is. Ik heb er weinig zin in om een half miljoen regels te gaan herschrijven - en dat is uiteraard ook niet de bedoeling.

offtopic:
Lees het topic voor je blaat, GlowThijs!


En trouwens: LoadLibrary zit in kernel32.dll, dat is precies de module die ik mis.

[ Voor 13% gewijzigd door kvdveer op 12-10-2005 12:04 ]

Localhost, sweet localhost


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik heb geen ervaring met .Net en dll's, maar als het goed is produceert de linker van je .exe ook een .lib. Kun je daar expliciet mee linken in je c# project?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Anders probeer eerst een nieuwe "hello-world" .exe te maken (m.a.w.: zo simpel mogelijk), en kijk of die een import-table heeft (zou wel moeten, toch?)

Zo ja, verander dan geleidelijk aan je project-instellingen en/of meegelinkte libraries in dit project totdat ze overeenkomen met je 'echte' project, en kijk of je er een vinger achter kunt krijgen bij welke instelling het fout gaat.

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Mijn executable heeft wel een importtable - hij wordt alleen niet ingelezen. Daardoor gaat het jumpen vanaf de importtable mis. Ik was op zich al bezig met een testproject, maar voorlopig zie ik ongeveer dezelfde problemen. Stay tuned for more information.

Localhost, sweet localhost


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Het probleem doet zich ook voor bij het meest eenvoudige testproject - zodra het wordt gecompileerd als exe, wordt bij LoadLibrary(...) de importtable genegeerd.

Iemand anders nog suggesties?

Localhost, sweet localhost


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
kvdveer schreef op woensdag 12 oktober 2005 @ 14:25:
Het probleem doet zich ook voor bij het meest eenvoudige testproject - zodra het wordt gecompileerd als exe, wordt bij LoadLibrary(...) de importtable genegeerd.

Iemand anders nog suggesties?
Als ik het volgende programmaatje maak en compile als console app, dan werkt het gewoon:
C++:
1
2
3
4
5
6
#include <windows.h>

int main(int argc, char **argv){
    HMODULE hModule = GetModuleHandle(NULL);
    return 0;
}


De gegenereerde assembly-code is precies dezelfde:
GAS:
1
2
3
4
00401000  push        0    
00401002  call        dword ptr [__imp__GetModuleHandleA@4 (405000h)] 
00401008  xor         eax,eax 
0040100A  ret             

Bij mij wordt de import-table dus wel geladen... wat doe jij anders dan ik?

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
Je vergeet een deel: ik ben namelijk via LoadLibrary(...) de gegenereerde exe aan het importeren. In die situatie wordt de importtable niet geladen.

offtopic:
Kom op mensen, ik doe mijn best om alles zo volledig mogelijk de beschrijven, en het enige wat ik krijg zijn reacties van mensen die mijn verhaal niet gelezen hebben. Van ingeburgerde tweakers en vooral van admins moet ik toch kunnen verwachten dat ze de draad lezen? Anders had ik hier net zo goed een "het werkt niet!!!111!1!!" topic kunnen plaatsen.
Voor mensen die niet weten waar ik op doel: ik ben bezig met loadlibrary op een .exe-file.

Localhost, sweet localhost


  • Glow
  • Registratie: November 2000
  • Laatst online: 22-07-2023

Glow

46&2 are just ahead of me.

Ah kom op, je schat ons wel laag in.

Kan je btw geen import library aanmaken bij een .exe ? Of als dat niet kan, gewoon LoadLibrary gebruiken. Misschien dat dat werkt. Zou je even naar moeten kijken anders.

http://www.google.nl/search?q=loadlibrary+exe

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
kvdveer schreef op woensdag 12 oktober 2005 @ 16:38:
Je vergeet een deel: ik ben namelijk via LoadLibrary(...) de gegenereerde exe aan het importeren. In die situatie wordt de importtable niet geladen.

offtopic:
Kom op mensen, ik doe mijn best om alles zo volledig mogelijk de beschrijven, en het enige wat ik krijg zijn reacties van mensen die mijn verhaal niet gelezen hebben. Van ingeburgerde tweakers en vooral van admins moet ik toch kunnen verwachten dat ze de draad lezen? Anders had ik hier net zo goed een "het werkt niet!!!111!1!!" topic kunnen plaatsen.
Voor mensen die niet weten waar ik op doel: ik ben bezig met loadlibrary op een .exe-file.
Verrek, nu je het zegt, uit post #5 in dit topic hadden we idd kunnen opmaken dat het misschien om LoadLibrary ging: "...LoadLibrary laadt de importtable niet...". Als je dat nu in het vervolg in de OP vermeldt, en de niet-relevante stukken code wegliet, dan was het misschien ook wat duidelijker voor ons geweest.

Maar goed, ik zou het verder ook niet weten. Succes.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Ik denk niet dat die mogelijkheid er is.
Je kan proberen om in iedere externe functie te zien of die modules geladen zijn, en eventueel ze manueel te laden. Maar ik denk niet dat het kan.
Even MSDN'en brengt dit naar boven:
link

Is het een mogelijkheid om je EXE als COM/ActiveX server te laten draaien ?
daarmee omzeil je het hele gedoe aangezien je applicatie dan in de achtergrond geladen wordt.

ASSUME makes an ASS out of U and ME


  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025
MrBucket schreef op woensdag 12 oktober 2005 @ 16:56:
[...]

Verrek, nu je het zegt, uit post #5 in dit topic hadden we idd kunnen opmaken dat het misschien om LoadLibrary ging: "...LoadLibrary laadt de importtable niet...". Als je dat nu in het vervolg in de OP vermeldt, en de niet-relevante stukken code wegliet, dan was het misschien ook wat duidelijker voor ons geweest.

Maar goed, ik zou het verder ook niet weten. Succes.
Sja. Als je niets van het onderwerp afweet, zegt DllImport je niets. Het verschil tussen DLL en EXE zul je ook niet kunnen plaatsen. Dan is het logisch dat je een zinloze post plaatst. Maargoed, als je niets van het onderwerp afweet, waarom plaats je dan uberhaupt een post?

Je hebt gelijk dat ik LoadLibrary niet in mijn OP noem, ik ben al de hele dag op onderzoek en de vereenvoudigde versie met LoadLibrary had ik toen nog niet ontdekt. Toen ik dat wel wist heb ik het genoemd. (overigens gebruikt c#'s DllImportAttribute gewoon LoadLibraryEx, dus dat is niet echt anders.)

[ Voor 37% gewijzigd door kvdveer op 12-10-2005 17:15 . Reden: Quote toegevoegd. ]

Localhost, sweet localhost


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

kvdveer schreef op woensdag 12 oktober 2005 @ 16:38:
offtopic:
Kom op mensen, ik doe mijn best om alles zo volledig mogelijk de beschrijven, en het enige wat ik krijg zijn reacties van mensen die mijn verhaal niet gelezen hebben. Van ingeburgerde tweakers en vooral van admins moet ik toch kunnen verwachten dat ze de draad lezen? Anders had ik hier net zo goed een "het werkt niet!!!111!1!!" topic kunnen plaatsen.
Voor mensen die niet weten waar ik op doel: ik ben bezig met loadlibrary op een .exe-file.
Zeg, doe eens even normaal. De mensen hier proberen serieuze suggesties te doen. Voor anderen kan ik niet spreken, maar ik heb je topic wel volledig gelezen. Mijn suggestie van die .lib heb je voor het gemak maar even achterwege gelaten, of iig niet op gereageerd. Dat het om LoadLibrary ging was op dat moment nog niet duidelijk. Als je nou gewoon even niet hoog van de toren blaast en met respect omgaat met de mensen die je proberen te helpen, komen we wellicht ook tot een oplossing. Als je dat niet kan kan ik je topic net zo goed sluiten, want je weet het immers zelf toch beter.

[ Voor 3% gewijzigd door .oisyn op 12-10-2005 17:30 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
kvdveer schreef op woensdag 12 oktober 2005 @ 17:03:
Sja. Als je niets van het onderwerp afweet, zegt DllImport je niets. Het verschil tussen DLL en EXE zul je ook niet kunnen plaatsen. Dan is het logisch dat je een zinloze post plaatst. Maargoed, als je niets van het onderwerp afweet, waarom plaats je dan uberhaupt een post?
Als jij het onderwerp in de eerste plaats goed had afgebakend had ik wel iets nuttigs met mijn tijd kunnen doen in plaats van jouw posts navlooien naar aanwijzingen over waar je nu eigenlijk mee bezig bent.

En mijn kennis over het verschil tussen dll's en executables is nog vrij aardig. Een verschil is bijvoorbeeld dat 2 executables, i.t.t. dll's, niet onder alle omstandigheden in dezelfde adresruimte gebruikt kunnen worden, en dat ligt niet aan LoadLibrary.

Maar ik voel me eigenlijk niet meer zo geroepen om hier nu nog meer tijd in te steken.
Pagina: 1