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:
Vervolgens probeer ik vanuit een andere applicatie (c#) die executable in te laden, en dat lukt:
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?
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