I have a DLL that's compiled, and I don't have the source code for it anymore. The only thing I want from the DLL is the functions it provides, and how they are accessed, i.e. their signature.
How can I do this?
You can extract the following:
Metadata (all classes, methods, parameters, etc.) in case of a .NET Assembly. Use Reflector and ILDasm for this purpose.
Exportable functions in case of a native DLL. Use the dumpbin utility. There is also a professional tool called IDA. It's very powerful and is meant for iterative reverse-engineering.
Related
Consider a C++ API defined as a series of __options(declexport/import) classes.
Further, assume that the caller is never permitted to call the ordinary operator new(size_t) on these classes. Either a static factory method does the new-ing or there is a class-specific operator new. And ditto marks on the delete size as needed (frequently just a virtual destructor).
Now, if you compile and link a DLL and an IMPLIB of with the tools from VS2010, can you hand that implib and DLL to a user of VS2005 and expect it to work?
MFC is not involved here at all.
I'd be particularly grateful to any reference to any relatively formal Microsoft statement on the subject.
So long as the name mangling on the C++ API is identical (they are), and does not use STL-type specific parameters, such as basic_string or std::map, whose implementation may have changed between releases of the compiler (and they have), then it should just work.
Of course, you'll want to make sure you either compiled your DLL using /MT mode (static linked runtimes), or include the redistributables for VS2010 runtimes with your supplied libraries and link targets.
EDIT: Expanding on "don't pass in types that have version-specific implementations". A partial list is most easily found by looking at the output of the exports of MSVC100P.DLL.
cd %VS100COMNTOOLS%\..\VC\redist\x86\Microsoft.VC100.CRT
DUMPBIN /exports MSVCP100.DLL
The next issue will be header-only implementations of things like map or set which have changed under the hood between versions of the compiler.
This is why it's highly recommended that only scalar types be passed across boundaries between memory arenas. And thus, simple tests will pass, and be reliable.
You have not mentioned if you have used MFC to create the DLL's .If you have, regular DLL's should work , but I dont think extension shall work as the latter links to the MFC dlls .I am including links for your reference.
http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c4017
http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20385543.html
http://msdn.microsoft.com/en-us/library/26h8x9sy%28v=VS.100%29.aspx
EDIT
If its a normal DLL, there should not be any problem.Also depends on the linkage type.
When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.
I'm looking at incorporating Lua into a C++ project, and am a bit confused by the presence of the two binaries (lua51.dll and lua5.1.dll) in the distribution from Luabinaries.
According to the docs...
In Windows your library or application
must be linked with a stub library. A
stub library is a library with only
the function declarations that will
bind your DLL with the Lua DLL.
Why? I've never needed stub DLLs before when linking with third-party DLLs?
A stub library is a .lib file, not a DLL. It contains function declarations for all the exported functions in the DLL, which just forward the call into the DLL itself. So if you build an application that you want to link with lua51.dll, you tell the linker to link with lua51.lib, and all calls to exported functions will be forwarded to the DLL. If you didn't do this, you would get a lot of "unresolved external symbol" errors when linking.
This is only needed when statically linking with a DLL (so that it is loaded automatically when the application is run). It is not needed when loading the DLL dynamically with LoadLibrary.
Regarding why they have two different DLLs, The manual says this:
The LuaBinaries DLL packages have a dll proxy called "lua51.dll". It can be used to replace other "lua51.dll" released by other distributions. It will simply forward calls to the "lua5.1.dll". There is no compiled source code involved in the forwarding.
Basically, some existing applications link with lua5.1.dll while others link with lua51.dll and they want to support them both. In any case this is not related to the stub libraries.
I believe it's to do with __declspec(import) and __declspec(export) vs GetProcAddress. However, I don't actually know for sure.
when you need to use a function you include a header file but wheres the function code is defined?
Dave, the code lives in the various and many DLL files in your Windows\system32 directory.
The actual code that implements the Win-32 API are defined in various DLLs on your system. These DLLs have names like kernel32.dll, comctl32.dll etc. You will find them in C:\Windows\System32.
What generally happens is that you link your code with kernel32.lib etc. that have a little code to dynamically load the DLLs when your program starts. This allows Win32 API functions to directly call into the DLLS.
Well as explained above you are in the hands of microsoft.
You can always look at the msdn http://msdn.microsoft.com.
For most API functions you can find some information at the bottom.
For most function you get from there:
Minimum supported client
Minimum supported server
Header
Library
DLL
Unicode and ANSI names
Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.