سؤال

I have something weird...

I am trying to do a proxy DLL for an old game (based on LithTech engine, abandonware, Windows 98 application), so I used wrappit, made the DLL, made it compiling, but... Well...

The DLL itself seems to be OK. At least the DllMain gets executed when testing with LOADDLL from OllyDbg...

But when I insert it into the game folder instead of the original DLL, it loads the DLL, and then it doesn't execute the DLL entry point DllMain! In some builds (Visual Studio 2005) it just says nothing. In other builds (Visual Studio 2010) it raises the c0000139 exception (which is "Entry point not found"). But how can it be that entry point is not found when it loads fine with LOADDLL in ollydbg, which means that the entry oint is in place?

Please help me!

UPD: Posting the dumpbin /exports output:

The original DLL:

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file IMUSIC25_.DLL

File Type: DLL

  Section contains the following exports for IMUSIC25.DLL

    00000000 characteristics
    33713027 time date stamp Thu May 08 05:45:11 1997
        0.00 version
           1 ordinal base
          29 number of functions
          29 number of names

    ordinal hint RVA      name

          6    0 0000FD8B DllCanUnloadNow
          7    1 0000FDF9 DllGetClassObject
          8    2 0000FD85 DllRegisterServer
          9    3 0000FD88 DllUnregisterServer
          1    4 000105BD _AllocAAEngine2@8
          2    5 00010507 _AllocAAEngine@4
          3    6 00007101 _AllocAALoader@4
          4    7 000074FC _AllocAALoaderLite@4
          5    8 00010675 _AllocAAMIDIIn@4
         10    9 000106A1 _GetFinalMIDISink@4
         11    A 0001127F _LoadBandFile@12
         12    B 000115F9 _LoadMotifFile@12
         13    C 00011601 _LoadPatternFile@12
         14    D 0001123C _LoadPersonalityByName@12
         15    E 000111F9 _LoadPersonalityFile@12
         16    F 000118F7 _LoadPersonalityFromMemory@12
         17   10 0001131E _LoadSectionFile@12
         18   11 000114BB _LoadSongFile@12
         19   12 000111B6 _LoadStyleByName@12
         20   13 00011173 _LoadStyleFile@12
         21   14 0001182C _LoadStyleFromMemory@12
         22   15 0001155A _LoadTemplateFile@12
         23   16 000102B1 _MusicEngineSimpleInit95@12
         24   17 00010497 _MusicEngineSimpleInit@12
         25   18 00010066 _MusicEngineSimpleInitNT@12
         26   19 000119C2 _Panic@4
         27   1A 00011465 _SaveSectionAsMIDIFile@8
         28   1B 000113E1 _SaveSectionFile@8
         29   1C 00010692 _SetAADebug@4

  Summary

        4000 .data
        1000 .idata
        1000 .rdata
        2000 .reloc
        1000 .rsrc
       1B000 .text

My crafted DLL:

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file IMUSIC25.DLL

File Type: DLL

  Section contains the following exports for imusic25.dll

    00000000 characteristics
    52F816DB time date stamp Mon Feb 10 04:01:31 2014
        0.00 version
           1 ordinal base
          30 number of functions
          30 number of names

    ordinal hint RVA      name

          6    0 00001020 DllCanUnloadNow = ___E__0__@0
          7    1 00001030 DllGetClassObject = ___E__1__@0
          8    2 00001040 DllRegisterServer = ___E__2__@0
          9    3 00001050 DllUnregisterServer = ___E__3__@0
          2    4 00001060 _AllocAAEngine = ___E__5__@0
          1    5 00001130 _AllocAAEngine2 = ___E__4__@0
          3    6 00001070 _AllocAALoader = ___E__6__@0
          4    7 00001080 _AllocAALoaderLite = ___E__7__@0
          5    8 00001090 _AllocAAMIDIIn = ___E__8__@0
         30    9 00001000 _DllMain@12 = _DllMain@12
         10    A 000010A0 _GetFinalMIDISink = ___E__9__@0
         11    B 000010B0 _LoadBandFile = ___E__10__@0
         12    C 000010C0 _LoadMotifFile = ___E__11__@0
         13    D 000010D0 _LoadPatternFile = ___E__12__@0
         14    E 000010E0 _LoadPersonalityByName = ___E__13__@0
         15    F 000010F0 _LoadPersonalityFile = ___E__14__@0
         16   10 00001100 _LoadPersonalityFromMemory = ___E__15__@0
         17   11 00001130 _LoadSectionFile = ___E__4__@0
         18   12 00001110 _LoadSongFile = ___E__17__@0
         19   13 00001120 _LoadStyleByName = ___E__18__@0
         20   14 00001130 _LoadStyleFile = ___E__4__@0
         21   15 00001150 _LoadStyleFromMemory = ___E__20__@0
         22   16 00001160 _LoadTemplateFile = ___E__21__@0
         24   17 00001180 _MusicEngineSimpleInit = ___E__23__@0
         23   18 00001170 _MusicEngineSimpleInit95 = ___E__22__@0
         25   19 00001190 _MusicEngineSimpleInitNT = ___E__24__@0
         26   1A 000011A0 _Panic = ___E__25__@0
         27   1B 000011B0 _SaveSectionAsMIDIFile = ___E__26__@0
         28   1C 000011C0 _SaveSectionFile = ___E__27__@0
         29   1D 000011D0 _SetAADebug = ___E__28__@0

  Summary

        1000 .data
        1000 .rdata
        1000 .rsrc
        1000 .text

UPD: I checked the "GetLastError" on the failing LoadLibraryA call - it is 0x1E7 (487) - ERROR_INVALID_ADDRESS

هل كانت مفيدة؟

المحلول

Well, I managed to fix that by changing the definition of the functions and making them like in the original one.

For that, you need to set the function type to WINAPI (actually it is __stdcall but it seems that the compiler/linker somehow differentiates them? Because the mangling behaviour was different between __stdcall and WINAPI) and define the function parameters - you can calculate the number of needed ones from the last part of the mangled name (which is actually not present in the resulting DLL with the DEF file): @4 means one 4 bytes sized parameter (example - int), @8 means two, etc. You don't even need to know which is exactly the parameter type if you are working with wrappit generated functions - you just need to adjust the size to make mangling correct.

Next, you need to define the relation between the mangled names and ordinals in the DEF file.

There is probably a better and easier approach of using #pragma comment(linker, "/EXPORT:Function=Function@4,@1"), as per C++ DLL Export: Decorated/Mangled names (@wqw's answer) but I haven't tried it.

Also I needed to set up the relocations in project settings - that was probably the cause of "ERROR_INVALID_ADDRESS".

Case closed.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top