   How to replace a compiled DLL with mine?
  We have an old game that has a DLL, which is an interface to DirectSound. The DLL does not work for Windows Vista +. I tried creating a DLL with the same name and functions, but for some reason after overwriting the file with mine, the exe has a problem with it. My DLL's DllMain is never even initialized.I created a C++ app and had no problem loading my library or the games' library. We do not have the source code for the game (or DLL), so we're in a bind.I was thinking the exe may have a way of determining an alien DLL. File hash value and version information was eliminated..How can an exe determine a DLL is alien before even loading?Thank you   
  Maybe this will help.dumpbin for original DLL:PE signature foundFile Type: DLLFILE HEADER VALUES   14C machine (x86)5 number of sections   35890C9D time date stamp Thu Jun 18 05:48:29 19980 file pointer to symbol table0 number of symbols    E0 size of optional header  210A characteristics    Executable    Symbols stripped    32 bit word machine    DLLOPTIONAL HEADER VALUES   10B magic # (PE32)  5.10 linker version 1D000 size of code  BA00 size of initialized data0 size of uninitialized data  5CC0 entry point (10005CC0)  1000 base of code 1E000 base of data   10000000 image base (10000000 to 1002BFFF)  1000 section alignment   200 file alignment  4.00 operating system version  0.00 image version  4.00 subsystem version0 Win32 version 2C000 size of image   400 size of headers0 checksum2 subsystem (Windows GUI)0 DLL characteristics100000 size of stack reserve  1000 size of stack commit100000 size of heap reserve  1000 size of heap commit0 loader flags    10 number of directories 1FF00 [244] RVA [size] of Export Directory 29000 [ 64] RVA [size] of Import Directory0 [  0] RVA [size] of Resource Directory0 [  0] RVA [size] of Exception Directory0 [  0] RVA [size] of Certificates Directory 2A000 [    1458] RVA [size] of Base Relocation Directory 1E000 [ 54] RVA [size] of Debug Directory0 [  0] RVA [size] of Architecture Directory0 [  0] RVA [size] of Global Pointer Directory0 [  0] RVA [size] of Thread Storage Directory0 [  0] RVA [size] of Load Configuration Directory0 [  0] RVA [size] of Bound Import Directory 292B0 [24C] RVA [size] of Import Address Table Directory0 [  0] RVA [size] of Delay Import Directory0 [  0] RVA [size] of COM Descriptor Directory0 [  0] RVA [size] of Reserved DirectorySECTION HEADER #1   .text name   1CF2B virtual size    1000 virtual address (10001000 to 1001DF2A)   1D000 size of raw data400 file pointer to raw data (00000400 to 0001D3FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers60000020 flags    Code    Execute ReadSECTION HEADER #2  .rdata name    2144 virtual size   1E000 virtual address (1001E000 to 10020143)    2200 size of raw data   1D400 file pointer to raw data (0001D400 to 0001F5FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers40000040 flags    Initialized Data    Read Only  Debug Directories   Time Type  Size RVA  Pointer    -------- ------ -------- -------- --------    35890C9D misc   110 00000000    27000    Image Name: Debug/dsdll.dll    35890C9D fpo60 00000000    27110    35890C9D cv 2D 00000000    27300    Format: NB10, 35890BBE, 3, C:\dev\dsdll\Debug\dsdll.pdb  Section contains the following exports for dsdll.dll    00000000 characteristics    35890C9D time date stamp Thu Jun 18 05:48:29 1998   0.00 version 1 ordinal base10 number of functions10 number of names    ordinal hint RVA name1    0 000010AA DSChangeVol2    1 000010A0 DSDestroy3    2 00001005 DSFileInit4    3 0000100A DSInit5    4 00001064 DSPulse6    5 00001073 DSSetListenerPosition7    6 00001032 DSSetRolloff8    7 00001014 DestroyDSound9    8 0000102D StartDSound    10    9 00001087 StopDSoundSECTION HEADER #3   .data name    70AC virtual size   21000 virtual address (10021000 to 100280AB)    5400 size of raw data   1F600 file pointer to raw data (0001F600 to 000249FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbersC0000040 flags    Initialized Data    Read WriteSECTION HEADER #4  .idata nameCB4 virtual size   29000 virtual address (10029000 to 10029CB3)E00 size of raw data   24A00 file pointer to raw data (00024A00 to 000257FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbersC0000040 flags    Initialized Data    Read WriteSECTION HEADER #5  .reloc name    177F virtual size   2A000 virtual address (1002A000 to 1002B77E)    1800 size of raw data   25800 file pointer to raw data (00025800 to 00026FFF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers42000040 flags    Initialized Data    Discardable    Read Only  Summary   8000 .data   1000 .idata   3000 .rdata   2000 .reloc  1D000 .textdumpbin for my DLL:PE signature foundFile Type: DLLFILE HEADER VALUES   14C machine (x86)7 number of sections   4C0CD413 time date stamp Mon Jun 07 04:12:19 2010 45600 file pointer to symbol table  13BB number of symbols    E0 size of optional header  2306 characteristics    Executable    Line numbers stripped    32 bit word machine    Debug information stripped    DLLOPTIONAL HEADER VALUES   10B magic # (PE32)  2.56 linker version 3DA00 size of code 45200 size of initialized data  4C00 size of uninitialized data  1000 entry point (6D501000)  1000 base of code 3F000 base of data   6D500000 image base (6D500000 to 6D54EFFF)  1000 section alignment   200 file alignment  4.00 operating system version  1.00 image version  4.00 subsystem version0 Win32 version 4F000 size of image   400 size of headers 7B18C checksum3 subsystem (Windows CUI)0 DLL characteristics200000 size of stack reserve  1000 size of stack commit100000 size of heap reserve  1000 size of heap commit0 loader flags    10 number of directories 48000 [21E] RVA [size] of Export Directory 49000 [684] RVA [size] of Import Directory0 [  0] RVA [size] of Resource Directory0 [  0] RVA [size] of Exception Directory0 [  0] RVA [size] of Certificates Directory 4A000 [    4090] RVA [size] of Base Relocation Directory0 [  0] RVA [size] of Debug Directory0 [  0] RVA [size] of Architecture Directory0 [  0] RVA [size] of Global Pointer Directory0 [  0] RVA [size] of Thread Storage Directory0 [  0] RVA [size] of Load Configuration Directory0 [  0] RVA [size] of Bound Import Directory0 [  0] RVA [size] of Import Address Table Directory0 [  0] RVA [size] of Delay Import Directory0 [  0] RVA [size] of COM Descriptor Directory0 [  0] RVA [size] of Reserved DirectorySECTION HEADER #1   .text name   3D840 virtual size    1000 virtual address (6D501000 to 6D53E83F)   3DA00 size of raw data400 file pointer to raw data (00000400 to 0003DDFF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers60000060 flags    Code    Initialized Data    Execute ReadSECTION HEADER #2   .data name170 virtual size   3F000 virtual address (6D53F000 to 6D53F16F)200 size of raw data   3DE00 file pointer to raw data (0003DE00 to 0003DFFF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbersC0000040 flags    Initialized Data    Read WriteSECTION HEADER #3  .rdata name    2640 virtual size   40000 virtual address (6D540000 to 6D54263F)    2800 size of raw data   3E000 file pointer to raw data (0003E000 to 000407FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers40000040 flags    Initialized Data    Read OnlySECTION HEADER #4    .bss name    4BE0 virtual size   43000 virtual address (6D543000 to 6D547BDF)  0 size of raw data  0 file pointer to raw data  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbersC0000080 flags    Uninitialized Data    Read WriteSECTION HEADER #5  .edata name21E virtual size   48000 virtual address (6D548000 to 6D54821D)400 size of raw data   40800 file pointer to raw data (00040800 to 00040BFF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers40000040 flags    Initialized Data    Read Only  Section contains the following exports for dsdll.dll    00000000 characteristics    4C0CD413 time date stamp Mon Jun 07 04:12:19 2010   0.00 version 1 ordinal base10 number of functions10 number of names    ordinal hint RVA name1    0 000012DC DSChangeVol2    1 000012E6 DSDestroy3    2 000012F0 DSFileInit4    3 000012FA DSInit5    4 00001304 DSPulse6    5 0000130E DSSetListenerPosition7    6 00001318 DSSetRolloff8    7 00001322 DestroyDSound9    8 0000132C StartDSound    10    9 00001336 StopDSoundSECTION HEADER #6  .idata name684 virtual size   49000 virtual address (6D549000 to 6D549683)800 size of raw data   40C00 file pointer to raw data (00040C00 to 000413FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbersC0000040 flags    Initialized Data    Read WriteSECTION HEADER #7  .reloc name    4090 virtual size   4A000 virtual address (6D54A000 to 6D54E08F)    4200 size of raw data   41400 file pointer to raw data (00041400 to 000455FF)  0 file pointer to relocation table  0 file pointer to line numbers  0 number of relocations  0 number of line numbers42000040 flags    Initialized Data    Discardable    Read Only  Summary   5000 .bss   1000 .data   1000 .edata   1000 .idata   3000 .rdata   5000 .reloc  3E000 .text;Quote:Original post by Rich76We have an old game that has a DLL, which is an interface to DirectSound. The DLL does not work for Windows Vista +. I tried creating a DLL with the same name and functions, but for some reason after overwriting the file with mine, the exe has a problem with it. My DLL's DllMain is never even initialized.Unfortunately, it's not quite that simple. There's a lot to it, so I'll just briefly cover a few of the issues:- CRT mismatches: If the DLL is not a run-time loaded DLL (i.e., a .lib was required to compile the interface into the EXE) then CRT mismatches will result in possible crashes and failure of a module (DLL) to load.- Interface mismatches: If your DLL does not export every single class, function, object, etc... as the source does with the same exact naming convention and calling convention, then the DLL simply won't work due.- Configuration mismatches: Stack size, heap size, unicode/ascii, etc... All these project configuration options need to be matched correctly (or better than) between your DLL and the game's DLL to avoid problems. A simple example is if the DLL requires a 8mb stack and your DLL sticks with 512kb, then the DLL is going to crash as soon as more than 512kb of stack space is used.- Incomplete implementations: If you simply try to provide skeleton functions, then the DLL can fail if the EXE is dependent on the DLL to initialize variables or allocate memory for it. Imagine if the EXE calls a DLL function to allocate memory in the DLL (as it should) and your function implementation does not do that, then the EXE is going to have invalid memory and will most likely crash.So, as you can see, you can't really replace custom DLLs simply by creating your own and dropping it in. At best, you could write a proxy DLL to hook the exported interfaces, but anything more than that requires heavy reverse engineering.Quote:I created a C++ app and had no problem loading my library or the games' library. We do not have the source code for the game (or DLL), so we're in a bind.This is expected because your app is significantly simpler than the game and will not make use of everything it needs to like the game would.Quote:I was thinking the exe may have a way of determining an alien DLL. File hash value and version information was eliminated.To check this, simply modify the contents of the game's DLL and see if it still loads. The easiest way about this is to just open the DLL in OllyDbg and replace some INT 3s with NOPs. You'll want to change some at the beginning, middle, and end to make sure you hit a nice spread of code regions that might be hashed. Usually, DLLs will be hashed in an all-or-nothing fashion from the physical file before it's loaded into memory. There are protections that do in-memory dynamic hashing to verify contents, but I'd not expect something like that to be used in a DirectSound wrapper.Quote:How can an exe determine a DLL is alien before even loading?I really don't think that's the problem here. If you are getting problems with a DLL as the EXE loads, it's going to be a problem in the DLL itself rather than a protection detecting something is amiss (in which case, the user is usually told about the problem). That is especially true when it comes to games because there's nothing more frustrating to developers than being told users' applications simply don't start with no error.So, basically what you need to do is figure out why the DLL doesn't work on Vista+ platforms first through the use of a debugger/disassembler (like OllyDbg, Immunity, or IDA Pro). Once you can find out why the DLL doesn't work, you can then work on implementing binary patches to fix the issue or possibly write a secondary DLL that you inject to redirect problematic functions into new ones. Either way, you won't be coding a new DLL from scratch to replace the DLL in it;s entirely unless you had the source code as there's too much that could go on. Hope that helps, good luck!   ;Quote:Original post by Drew_BentonQuote:Original post by Rich76We have an old game that has a DLL, which is an interface to DirectSound. The DLL does not work for Windows Vista +. I tried creating a DLL with the same name and functions, but for some reason after overwriting the file with mine, the exe has a problem with it. My DLL's DllMain is never even initialized.Unfortunately, it's not quite that simple. There's a lot to it, so I'll just briefly cover a few of the issues:- CRT mismatches: If the DLL is not a run-time loaded DLL (i.e., a .lib was required to compile the interface into the EXE) then CRT mismatches will result in possible crashes and failure of a module (DLL) to load.- Interface mismatches: If your DLL does not export every single class, function, object, etc... as the source does with the same exact naming convention and calling convention, then the DLL simply won't work due.- Configuration mismatches: Stack size, heap size, unicode/ascii, etc... All these project configuration options need to be matched correctly (or better than) between your DLL and the game's DLL to avoid problems. A simple example is if the DLL requires a 8mb stack and your DLL sticks with 512kb, then the DLL is going to crash as soon as more than 512kb of stack space is used.- Incomplete implementations: If you simply try to provide skeleton functions, then the DLL can fail if the EXE is dependent on the DLL to initialize variables or allocate memory for it. Imagine if the EXE calls a DLL function to allocate memory in the DLL (as it should) and your function implementation does not do that, then the EXE is going to have invalid memory and will most likely crash.So, as you can see, you can't really replace custom DLLs simply by creating your own and dropping it in. At best, you could write a proxy DLL to hook the exported interfaces, but anything more than that requires heavy reverse engineering.Quote:I created a C++ app and had no problem loading my library or the games' library. We do not have the source code for the game (or DLL), so we're in a bind.This is expected because your app is significantly simpler than the game and will not make use of everything it needs to like the game would.Quote:I was thinking the exe may have a way of determining an alien DLL. File hash value and version information was eliminated.To check this, simply modify the contents of the game's DLL and see if it still loads. The easiest way about this is to just open the DLL in OllyDbg and replace some INT 3s with NOPs. You'll want to change some at the beginning, middle, and end to make sure you hit a nice spread of code regions that might be hashed. Usually, DLLs will be hashed in an all-or-nothing fashion from the physical file before it's loaded into memory. There are protections that do in-memory dynamic hashing to verify contents, but I'd not expect something like that to be used in a DirectSound wrapper.Quote:How can an exe determine a DLL is alien before even loading?I really don't think that's the problem here. If you are getting problems with a DLL as the EXE loads, it's going to be a problem in the DLL itself rather than a protection detecting something is amiss (in which case, the user is usually told about the problem). That is especially true when it comes to games because there's nothing more frustrating to developers than being told users' applications simply don't start with no error.So, basically what you need to do is figure out why the DLL doesn't work on Vista+ platforms first through the use of a debugger/disassembler (like OllyDbg, Immunity, or IDA Pro). Once you can find out why the DLL doesn't work, you can then work on implementing binary patches to fix the issue or possibly write a secondary DLL that you inject to redirect problematic functions into new ones. Either way, you won't be coding a new DLL from scratch to replace the DLL in it;s entirely unless you had the source code as there's too much that could go on. Hope that helps, good luck!Wow, thank you for the extensive information. Guess my head was too high up in the clouds. :) Thank you again.::Rated::   