I have worked with "CPPLoadLibrary" example (from Microsoft All-in-One framework)
Okay, there are two ways of export symbols from the sample DLL.
Export symbols from a DLL using .DEF files
A module-definition (.DEF) file is a text file containing one or more module
statements that describe various attributes of a DLL. Create a .DEF file and
use the .def file when building the DLL. Using this approach, we can export
functions from the DLL by ordinal rather than by name.
Export symbols from a DLL using __declspec(dllexport)
__declspec(dllexport) adds the export directive to the object file so we do
not need to use a .def file. This convenience is most apparent when trying to
export decorated C++ function names.
And so we have the following code.
typedef int (_cdecl* LPFNGETSTRINGLENGTH1) (PCWSTR);
typedef int (CALLBACK* LPFNGETSTRINGLENGTH2) (PCWSTR);
LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)
GetProcAddress(hModule, "GetStringLength1");
LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)
GetProcAddress(hModule, "_GetStringLength2#4");
So my question is how to determine the name of symbol in order to call GetProcAddress?
in first case it's pretty straightforward, we take that symbol name from .DEF file.
But what about "_GetStringLength2#4"
What is underscore? What is "#4" stand for?
Thanks.
If you don't use a .DEF file, the export names are decorated according to their calling convention in order to support exporting overloaded functions. See Why can't I GetProcAddress a function I dllexport'ed?:
[T]he decoration scheme varies from architecture to architecture and from calling convention to calling convention. So, for example, if the function is exported from a PPC DLL, you would have to do GetProcAddress(hinst, "..SomeFunction"), but if it is exported from an 80386 DLL as extern "C" __stdcall, you would need GetProcAddress(hinst, "_SomeFunction#8"), but if it's __fastcall you would need GetProcAddress(hinst, "#SomeFunction#8").
What's more, C++ decoration varies from compiler vendor to compiler vendor. A C++ exported function might require GetProcAddress(hinst, "?SomeFunction##YGXHH#Z") if compiled with the Microsoft C++ compiler, but some other decorated string if compiled with the Borland C++ compiler.
So if you intend people to be able to GetProcAddress for functions and you intend your code to be portable to multiple platforms, or if you intend them to be able to use your DLL from a language other than C/C++ or use a C++ compiler different from Microsoft Visual Studio, then you must export the function by its undecorated name.
See The history of calling conventions, part3 for a description of the various name decoration schemes. In this case, the function uses the __stdcall calling convention, so it's decorated by prepending an underscore and appending a # sign and the number of bytes worth of parameters it takes. It takes one word-sized argument for a total of 4 bytes, so it's decorated as _GetStringLength2#4.
To answer your actual question, use your compiler's TDUMP or similar tool, or any other tool that can display an executable's exports table, so you can see the actual exported names.
Related
My experience is with Delphi XE2 and I am not familiar with MS Visual C/C++. I am trying to compile some MS Visual C++ code into a DLL I can use from Delphi.
The compiled DLL exported functions cannot be found by Delphi.
Using a hex editor the DLL export table looks like the following snippets and does not have NULL terminated function names (a NULL ASCII char is positioned following the eol "Z"):
?MM_End##YAH_N#Z
?MM_GetCurrentPosition##YAHPAN0000#Z
?MM_GetWindow##YAHPAN000#Z
?MM_MarkGetLinkFile##YAHPAXPADH#Z
?MM_Start##YAH_N#Z
The C++ header code looks like this:
...
#define MMAPI_API __declspec(dllexport)
...
MMAPI_API int MM_Start(bool run_mmnav);
MMAPI_API int MM_End(bool close_mmnav);
...
With reference to https://msdn.microsoft.com/en-AU/library/dt232c9t%28v=vs.90%29.aspx. I have tried several variations of __stdcall and _cdecl but cannot get MS Visual C++ to compile the export table with NULL terminated strings.
You are attempting to reverse engineer, by guesswork, a format that is well documented. The PE format is known and documented. There's no point in you trying to reverse it with a hex editor. There's no need for you to understand the format at all. Use an existing tool to list the exported functions. For instance dumpbin from the MS tool chain, or Dependency Viewer.
Once you've listed the exports you'll find that they have been exported under their C++ mangled names. Name mangling is how C++ compilers encode the function signature in the function name used for linking. Mangling was designed to allow C++ tool chains to support overloaded functions and continue using C style linker technology.
You'll see a list of exported symbols like these:
?MM_Start##YAH_N#Z
?MM_End##YAH_N#Z
etc.
Run these through a demangler to confirm that they are what you are expecting. The above symbols demangle as:
int __cdecl MM_Start(BOOL)
int __cdecl MM_End(BOOL)
You can import them using those names if you wish. For example:
function MM_Start(run_mmnav: BOOL): Integer; cdecl;
external dllname name '?MM_Start##YAH_N#Z';
function MM_End(run_mmnav: BOOL): Integer; cdecl;
external dllname name '?MM_End##YAH_N#Z';
Or you can choose to suppress C++ name mangling of the exported functions when you compile the DLL. Do that by wrapping the function declarations in an extern "C" block, or by exporting the functions with a .def file.
I wanted to create a C++ dll (to be used in a dot net application). Some functionality I needed was already implemented in another C++ dll.
The dll I was referencing was set up like this (including the comment):
extern "C"
{
__declspec(dllexport) BOOL SomeFunctionToBeUsedExternally();
}
// internal functions
BOOL OtherFunctions();
I need to use one of the OtherFunctions in my code.
So, I added the proper include in my own code, added dependencies on the lib created by the dll above, and used the method I needed. As a result, of course, I got another __declspec(dllexport)... function.
It refused to link though, I got an error about the OtherFunction.
I verified everything, looked online - nothing seems to solve my problem.
Then, I added a __declspec(dllexport) in front of the function I needed, and it works.
I don't understand though. I thought, the dllexport marked functions will be exported to the dll, but aren't all functions sent to the lib ?
Why do I have to export functions to the dll, if I am not linking against the dll but against the lib ?
No, the linker does not automatically export all identifiers. The dllexport attribute tells the linker which identifiers are exported. Without this you would be forced to either export every identifier in the DLL or specify which identifiers should not be exported. When the linker creates the DLL it also creates an import library and includes information about which identifiers are exported based on that attribute.
When you want to use a DLL you need link with the appropriate .lib file for good reason. The .lib file tells the linker which identifiers are exported, the name of the DLL they are in and other information. It is also possible to export identifiers from the DLL by ordinal instead of by name. In this case the linker still needs to match the identifier with the appropriate ordinal. This is only possible by having an accompanying library file that contains that information since it is not present in DLL's export table.
No, only exported functions end up in the .lib. As you can tell.
It is not a static link library, it the import library for the DLL. It is a very simple and very small file since it contains no code at all. Just a list of the exported functions. The linker needs it to resolve the external in the client code, it needs to know the name of the DLL and the actual exported function name or ordinal (could be different) so it can add the entry to client's import table. Import libraries having the same filename extension as static libraries was perhaps a bit unfortunate.
I have got MyDll.dll and its function defined as below
void pascal Myfunction(BOOL);
when I'm trying to use the function in another project i am unable get the address of the function with GetProcAddress(). Here is my code:
void callMyDll()
{
HINSTANCE hDll;
hDll=LoadLibrary(_T("MyDll.dll");
if(hDll!=NULL)
{
cout<<"\n DLL Loaded \n";
}
else
cout<<"\n DLL Not loaded\n"
typedef void (__stdcall *MyFunction)(bool)
Myfunction mf1 = (MyFunction) GetProcAddress(hDll, "MyFunction");
if (mf1!=NULL)
cout<<"\n Function Loaded Successfully \n";
else
cout<<"\n Function not loaded \n";
FreeLibrary(hDll);
}
I'm getting output as:
DLL Loaded
Function not loaded
But when I'm trying with known DLLs like glut32.dll and its functions it is working fine.
I think it may be problem with its function like
void pascal MyFunction(BOOL);
Can anybody help me in this regard?
You need to use extern "C" to prevent name mangling and ensure the function is exported:
extern "C" __declspec(dllexport) void Myfunction(BOOL);
To view the exports from your DLL you can use dumpbin.exe utility that is shipped with Visual Studio:
dumpbin.exe /EXPORTS MyDll.dll
This will list the names of all exported symbols.
In addition to this do not have either of the following compiler switches specified:
Gz __stdcall calling convention: "Myfunction" would be exported as Myfunction#4
Gr __fastcall caling convention: "Myfunction" would be exported as #Myfunction#4
Note: I think last symbol is dependent on compiler version but is still not just "Myfunction".
The DLL export process is subject to name mangling and decoration. The long obsolete 16 bit pascal calling convention is equivalent to stdcall on 32 bit platforms.
First of all you should use extern "C" to specify C linkage and disable name mangling.
However, your function will still be subject to name decoration. If you export it with __declspec(dllexport) then it will in fact be exported with the name _Myfunction#4. If you wish to export it by its true name then you need to use a .def file.
However, the possibility still remains that you did not export the function from the DLL at all. Use Dependency Walker to check whether it was exported, and if so by what name.
Why are you using the pascal calling-convention? Perhaps that alters the names of symbols, and if so you might need to take that into account.
The symbol is going to be decorated, so it will never be called MyFunction, its more likely _MyFunction#4. you can quickly check this using something like dumpbin.
You can read up more on mangling here, if you want to avoid mangling, you need to use a def file to specify symbol names (or ordinals).
I'm working on a DLL which will be used from another language (so no import libs and including the dll's headers) using the _stdcall calling convetion. The problem is that VC++ seems to always do some name decoration on its exported symbols. All the references ive seen say use extern "C" but this still seems to leave me with a leading underscore, and a # plus a number after the exported name.
The worst bit is the automated means of loading extension dll's in the target language essentially does "func_name = GetProcAddress(dll, "func_name")" so using an undecorated name GetProcAddress fails, and using the decorated name it complains of an illegal variable name (# is not allowed) :(
How can I make VC++ export somthing with no name decorations at all?
extern "C" __declspec(dllexport) int __stdcall test(int x, const char *str);
dumpbin.exe
00011366 _test#8 = #ILT+865(_test#8)
You can use a .def file. It will let you export the functions without the decorations.
Read: Exporting from a DLL Using DEF Files
LIBRARY Vcam.ax
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
The above is from Filters.def, what does it actually do?
See MSDN:
Module-Definition (.def) Files
Exporting from a DLL Using DEF Files
About PRIVATE, they say this:
The optional keyword PRIVATE prevents
entryname from being placed in the
import library generated by LINK. It
has no effect on the export in the
image also generated by LINK.
In other words, those functions are hidden from the DLL's table of entry points and reserved for the OS.
The .def file on Win32 describes what functions get exported from a DLL. Unlike with .so files on gcc/Linux, where every symbol gets exported by default, you have to tell the compiler what functions to export. The standard way is to list it in a .def file. The other way is to use __declspec(dllexport) with Visual C++ (where using decorated function names would be no fun to use).
There are some keywords to place after the function name; you can speficy an ordinal number, that it shouldn't be exported by name (good for hiding your function names), or that it is private.
The documentation on MSDN describes the complete format:
Module-Definition (.def) Files