0

(rephrased question after reading comments)

What if I have an application or .dll statically dynamically linked against some .dll through an import library and then I replace the latter .dll with a different (version of the) .dll which exports all symbols of the original .dll and maybe adds some new ones?

Specifically, is there any guarantee this will work?

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
user1832484
  • 371
  • 3
  • 8
  • 1
    You don't statically link to DLLs. –  Apr 07 '18 at 21:33
  • D.L.L. : *Dynamic* Linked Library. If something is statically linked then you can't replace the library without relinking. One reason for doing that is the scenario you are suggesting - statically linking avoids the issues (but is inefficient). – cdarke Apr 07 '18 at 21:55
  • This happens very frequently in practise. Every time you run your app on a different version of Windows, for example - much of Windows is implemented as DLLs, although side-by-side DLLs muddy the water a bit. – Paul Sanders Apr 08 '18 at 05:29
  • can't understand reasons for downvoting, but I'm here to learn not to score points – user1832484 Apr 08 '18 at 11:33
  • 1
    @user1832484: wasn't me, some people will downvote if they think you did not do enough research yourself. Don't worry about it. – cdarke Apr 08 '18 at 14:19
  • Nor me, some people on here just don't get it. And I guess one might say, direct from philosophy corner, that there _are_ no guarantees in this life. One just has to make do. So we do. Touched up your post and snuck in an upvote, what the hell. – Paul Sanders Jul 14 '18 at 13:45
  • @cdarke Inefficient how? (You didn't think I'd just let that go, did you? :) Maybe I'll get that excavator badge or something :) – Paul Sanders Jul 14 '18 at 13:50
  • @PaulSanders: one of the reasons for DLLs is that the code pages are shared between processes. EXE file code pages are also shared, but only between processes running the same EXE. So if you have *n* processes running different EXEs but the same DLL library then only one copy of the code pages will be mapped to virtual memory and the pages stand less chance of being paged out. Static linking means every EXE has to have its own copy of the library pages loaded. – cdarke Jul 14 '18 at 21:34
  • @cdarke OK, not bad, although [ASLR](https://blogs.msdn.microsoft.com/oldnewthing/20170118-00/?p=95205) has moved the goalposts quite considerably. – Paul Sanders Jul 14 '18 at 21:53
  • @PaulSanders: I don't think that's related to page sharing, that's another level of abstraction on. Base addresses are how the process maps the page, it doesn't affect the fact that it is shared. – cdarke Jul 15 '18 at 07:26
  • @cdarke It is actually (sorry, can't dig up a suitable reference right now). If a DLL always maps to the same base address then its pages can be shared between processes. If not, then they can't (because MSVC doesn't generate position-independent code). Note to self: check if this is still true for 64 bit builds. – Paul Sanders Jul 15 '18 at 08:42
  • @PaulSanders: https://blogs.msdn.microsoft.com/oldnewthing/20160413-00/?p=93301 – cdarke Jul 15 '18 at 14:08
  • 1
    @cdarke Oh, ok, that's a lot better than Raymond's other post. Good link, well worth reading. – Paul Sanders Jul 15 '18 at 16:32

1 Answers1

2

This works generally, and it is a common way to fix bugs or security vulnerabilities in the field, without recompiling the client programs. The key to success is ABI compatibility.

Symbol names are present within the DLL files, and the address of each function is looked up by symbol name when the DLL is loaded.

Specific gotchas that could prevent compatibility:

  • Both DLL versions must have the same architecture (32 or 64 bit).
  • The arguments and return types should match on both DLL versions.
  • Also, the semantic meaning of each function call should at least be equivalent. If the DLL has an add_widget function that used to add widgets, but in the new DLL it removes widgets, there could be a problem.
  • Calling conventions need to match between the old and new DLLs.
  • If the new DLL is compiled with a different compiler, or with a different version of the same compiler, then symbols that are not declared extern "C" could break, because of name mangling.
  • If standard library types are passed across the DLL boundary, then the standard library needs to be the same version (and the client programs need to use that version too).
Jack C.
  • 744
  • 3
  • 7
  • thank you, so use of the import library is just replacing the `GetProcAddress` stuff? – user1832484 Apr 07 '18 at 22:45
  • 1
    Yes, if you link against an import library, the system loads the DLLs and maps the addresses before your entry point is called. The import libraries contain stubbed functions that get re-mapped at load time. Check out: https://stackoverflow.com/questions/3573475/how-does-the-import-library-work-details – Jack C. Apr 07 '18 at 22:53