How to specify a "clean" name of DLL exports? - windows

I have defined a DLL-export as follows:
__declspec(dllexport)
DWORD WINAPI DllBootstrap(LPVOID addr) {
return 0;
}
Now, using DUMPBIN, the symbol is displayed as follows:
1 0 0001100A ?DllBootstrap##YGKPAX#Z = #ILT+5(?DllBootstrap##YGKPAX#Z)
And this is how the memory looks in Visual Studio:
ยก}....ReflectDLL.dll.?DllBootstrap##YGKPAX#Z..........................................
when inspecting PIMAGE_EXPORT_DIRECTORY.AddressOfNames.
What I need is a clean symbol, i.e., DUMPBIN should output something like:
1 0 0001100A DllBootstrap
and PIMAGE_EXPORT_DIRECTORY.AddressOfNames should point to:
DllBootstrap..........................................
How can I achieve this?

WIN32 BUILDS:
As #RbMm indicated, to retain your function name as-is and get no name decoration, you must use a .DEF file (and remove the __declspec(dllexport) specifier). Then create a DEF file with the line below and either specify it with the /DEF linker option or add it to your Visual Studio project and it will be picked up automatically by the linker:
EXPORTS DllBootstrap
If you don't want to deal with an external .DEF file and you will be using the Visual C++ compiler, the simplest way to limit decoration using just code is to declare your function with 'extern "C"'. This results in decoration including a preceding underscore and appends an "#" along with the argument's byte count in decimal. The following code for example:
extern "C" __declspec(dllexport)
DWORD WINAPI DllBootstrap(LPVOID addr) {
return 0;
}
produces an exported name of:
_DllBootstrap#4
This is how stdcall functions are decorated when C++ name-mangling is disabled with 'extern "C"'. NOTE: WINAPI maps to __stdcall. Retaining 'extern "C"' and changing the convention to __cdecl, you won't get any decoration whatsoever, but module entrypoints should generally remain stdcall as you have it listed in your sample.
If you still want to avoid a .DEF file, there is one last hack you can employ. Add the following line to your code:
#pragma comment(linker,"/EXPORT:DllBootstrap=_DllBootstrap#4")
This will pass an argument to the linker creating a new undecorated name symbol which maps to the decorated name. This isn't very clean as the original name will still exist in your DLL, but you will get your clean exported name.
WIN64 BUILDS (UPDATE):
As Hans Passant commented, for anyone using the Visual C++ 64-bit compiler, there is only the 64-bit calling convention (stdcall, cdecl, etc. keywords are ignored). While C++ mangling will still occur under this compiler, no additional decoration is made to the exported names. In this case, 'extern "C"' would be enough when the sample is compiled as C++ code; if compiled as C, no modifications would be necessary.

Related

Replacing MSVC CRT function with private implementation

I have an embedded IoT project that I like to first develop in part by using PC tools such as VisualStudio. My embedded project has only a flash memory for a file system, and I'd like to redirect fopen fread etc. to my own private implementation on Windows. But what I'm encountering is an inability to have my private CRT library take precedence over the built-in CRT (e.g., built-in behavior driven by /MD compiler switch).
I have a simple three project solution.
Project 1 is a test executable. It has a one line main:
int main()
{
test();
}
Project 2 and 3 are static libraries. Project 2 has:
#include <string.h>
#include <stdio.h>
void test()
{
printf("%s\n", strchr("x", 'x'));
}
Project 3 has:
char * strchr(const char * s, int c) // exact signature of MSVC
{
return "overridden";
}
I expect output to be overridden but instead it is
x
But if I add this to Project 1:
printf("%s\n", strchr("y", 'y'));
The output will be
overridden
overridden
First one from test() in library, second from executable main() directly.
Any suggestions?
The linker resolves symbols on a first match basis - priority to separately linked .obj files, then .lib files in the order presented to the linker of the command line. So you can normally override a library symbol just be linking your own replacement. I have never tried it with MSVC, and it is a somewhat brutal approach.
An alternative solution that does not rely on specific linker behaviour is to use the pre-processor to replace standard symbols with your own alternatives. For example:
#if defined _WIN32
#define fopen test_fopen
FILE* test_fopen( const char * filename, const char * mode ) ;
#endif
add the other macros and declarations you need in a header file called testlib.h for example then use a "forced include" (/FI testlib.h in MSVC) to invisibly include the test interface everywhere. Then when built on Windows, all fopen calls will be replaced with test_fopen calling your replacement functions instead.
If the problem is caused by CRT usage in a static library only, and linker is finding MSVCRT DLL export lib before it finds private CRT static lib, a workaround might be to force a reference to the private CRT in the executable source files.
Example matching code above, placed in main as a global:
static char * (*p_strchr)(const char *, int) = strchr;
It is less than ideal but it alters linker search order in a reliable way.
More findings
There may be combinations (that I don't totally understand) where the linker will emit a LNK1169 "one or more multiply defined symbols" (more than one definition) linker error. For example, it might say fopen is defined more than once, and if you reverse the order of the private and MS libraries on the command line, then it might say fread is defined more than once. Perhaps it is caused by MSVC lib having DLL export signature, and the private lib being an import symbol. The behavior is hard to determine as it doesn't error on all of the functions that are being overridden.
If it is possible to switch all private libraries to /MT compiler switch (use static CRT), then the LNK1169 problem is resolved.

Win32 Assembly - Extern function naming (The meaning of '#')

As I see, extern WinAPI functions in assembly code have names like _ExitProcess#4.
What is the meaning of the #4 part, and how to determine what number to use after # ?
I know that this has something to do with DLL we are linking against, but in many cases it's not known what number to use after the #, and this leads to many nasty undefined reference errors.
As Andreas H answer said the number after the # is the number of bytes the function removes from stack before the function returns. This means it should be easy to determine that number, as it's the also number of bytes you need push on the stack to correctly call the function. It should be the number of PUSH instructions before the call multiplied by 4. In most cases this will also be the number of arguments passed to the function multiplied by 4.
If you want to double check that you've gotten the right number and you have Microsoft Visual Studio installed you can find the decorated symbol name from the Developer Command Prompt like this:
C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
Symbol name : _ExitProcess#4
Name : ExitProcess
If you're using the MinGW compiler tools to link your assembly code, you can do this instead:
C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess#4
00000000 T _ExitProcess#4
You'll need to replace C:\MinGW with the directory you installed MinGW.
Since not all Windows APIs reside in the kernel32 import library you'll need to replace kernel32 with the name of the import library given in the Windows SDK documentation for the API function you want to link to. For example, with MessageBoxA you'd need to use user32.lib with Visual Studio and libuser32.a with MinGW instead.
Note there are few rare Windows APIs that don't use the stdcall calling convention. These are functions like wsprintf that take a variable number of arguments, which the stdcall calling convention doesn't support. These functions just have an underscore _ before their names, and no # or number after. They also require that the caller remove the arguments from the stack.
The # symbol is, as the leading underscore, part of the function name when the stdcall calling convention is specified for the function.
The number specifies the number of bytes the function removes from the stack.
The compiler generates this number.
The suffix is added so that the function is not accidentally called with the wrong calling convention or the prototype in the source code specifies the wrong number or size of arguments. So the intention is to provide a means to avoid program crashes.
See also https://msdn.microsoft.com/de-de/library/zxk0tw93.aspx
If you want to get the number to use, make sure you have _NT_SYMBOL_PATH defined to the correct value.
Like:
srv*https://msdl.microsoft.com/download/symbols
or
srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols
For example (in cmd.exe, windows command line):
set _NT_SYMBOL_PATH=srv*https://msdl.microsoft.com/download/symbols
Then use:
dumpbin /exports /symbols kernel32.lib | findstr _ExitProcess#
You'll have to be in the directory where kernel32 is and you'll have to have grep.
Probably is a way to use built in find command. You could also redirect it to a file and then view it in your editor.

use a function from dll in visual studio 2010(visual c++)

I made a dll from my project and export a function using extern "C" like the code below:
main.cpp
extern "C" __declspec(dllexport) void __cdecl VectorOfMarker(char* InAdd,vector<NewMarker>& VectorMarkers)
{
DetectSeg d;
d.VectorOfMarker(InAdd,VectorMarkers);
}
I build the project and create the .dll and .lib files successfully.
then I create a new visual c++ project and try to use this dll and mentioned function in it.
Although I copied the .dll and .lib files to the same directory but I can't use extern "C" to import my function to the 2nd project. I think that I need to change some settings in visual studio 2010 to use the functions
Can anyone help me for this?
How can I use my exported function?
Too many thanks in advance
I think you are confused as to what type of the dll you are building.
There are two typed of the dynamitic linking implicit and explicit
.
To dynamically link a dll implicitly, you create dll that exports some functions and/or variables. This will create a DLL module and .lib import library. The module that is using this type of the dll, must have header file with function prototypes and must be linked with .lib import library.
So you are linking at the compile time. Since exports are done using __declspec(dllexport) and __declspec(dlleimport) and exported functions names are decorated (mangled). They look like ?ExportedTest##YAXPAD#Z.
Another type is explicit linking and that is most likely what you are doing.
Usually for this type of DLL function are exported using .def files to produce function names that are not decorated. This also can be achieved by using extern "C" modifier to tell C++ compiler to compile function as C style, hence exported function is not decorated and usre _ (underscore).
To use this type of the DLL you have todeclare function type and parameters, call Load library, and GetProcAddress to get function pointer. Then you will be able to make a call as follows:
typedef void (*DLLVectorOfMarker)(char*, vector<int>&);
HMODULE hMod = LoadLibrary(_T("ExportTest.dll")); // your lib name goes here
DLLVectorOfMarker pfnVectorOfMarker = (DLLVectorOfMarker)GetProcAddress(hMod, "VectorOfMarker");
vector <int> VectorMarkers;
pfnVectorOfMarker("some string", VectorMarkers);

Using DLLs with NASM

I have been doing some x86 programming in Windows with NASM and I have run into some confusion. I am confused as to why I must do this:
extern _ExitProcess#4
Specifically I am confused about the '_' and the '#4'. I know that the '#4' is the size of the stack but why is it needed? When I looked in the kernel32.dll with a hex editor I only saw 'ExitProcess' not '_ExitProcess#4'.
I am also confused as to why C Functions do not need the underscore and the stack size such as this:
extern printf
Why don't C Functions need decorations?
My third question is "Is this the way I should be using these functions?" Right now I am linking with the actual dll files themselves.
I know that the '#4' is the size of the stack but why is it needed?
To enable the linker to report a fatal error if your compiler assumed the wrong calling convention for the function (this can happen if you forget to include header files in C and ignore all the compiler warnings or if a declaration doesn't exactly match the function in the shared library).
Why don't C Functions need decorations?
Functions that use the cdecl calling convention are decorated with a single leading (so it would actually be _printf).
The reason why no parameter size is encoded into the decorated name is that the caller is responsible for both setting up and tearing down the stack, so an argument count mismatch will not be fatal for the stack setup (though the calling function might still crash if it isn't given the right arguments, of course). It might even be possible that the argument count is variable, like in the case of printf.
When I looked in the kernel32.dll with a hex editor I only saw ExitProcess not _ExitProcess#4.
The mangled names are usually mapped to the actual exported names of the DLL using definition files (*.def), which then get compiled to *.lib import library files that can be used in your linker invocation. An example of such a definition file for kernel32.dll is this one. The following line defines the mapping for ExitProcess:
_ExitProcess#4 = ExitProcess
Is this the way I should be using these functions?
I don't know NASM very well, but the code I've seen so far usually specifies the decorated name, like in your example.
You can find more information on this excellent page about Win32 calling conventions.

VC++ / Dev-C++: How to include an DLL?

I have written an DLL in Delphi which exports functions. I would like to use these functions in a C++ program without using dynamic Linking (LoadLibrary() API-Call).
The "import" declaration would be
extern "C" int __stdcall getVersionNumber();
I mainly use Bloodshed Dev-C++ which creates Windows Executables. But I do not know how to tell the compiler that it should import the function "getVersionNumber" from "STATMONDLL32.dll".
After I spent many hours by googling the problem, without any result (there was only weird stuff written about .a files and .lib files, which I do not have compiled by Delphi...) I have also installed VC++, but even there, I could not find a way to tell the compiler to use a specific DLL.
I have created a DEF file for this DLL - how can I tell Dev-C++ and/or VC++ to use it? (Dev-C++ prefered)
// Edit: Delphi is creating UNDECORATED symbols. The symbol is exactly "getVersionNumber".
I have created following DEF file with an alias for decoration:
LIBRARY STATMONDLL32
EXPORTS
getVersionNumberA = _getVersionNumberA#0
I have created a *.lib file with VC++ "lib.exe":
lib.exe /DEF:StatMonDll32.def /OUT:StatMonDll32.lib
I have included the lib in VC++ linker settings.
But VC++ tells me that it cannot resolve the external symbol _getVersionNumberA#0 ! Please help!
// Edit: I have uploaded the DLL here: http://www.viathinksoft.de/temp/StatMonDll32.dll . Can you access the symbol getVersionNumberA with VC++ ? I am searching for a solution since 6 days now :'-(
Best regards
Daniel Marschall
You can use dynamic linking, it should work something along the lines of:
extern "C" typedef int (__stdcall *pfnadd)(int a, int b);
extern "C" typedef int (__stdcall *pfngetversion)(void);
HMODULE mod = LoadLibraryA("mydll.dll");
pfnadd add = (pfnadd)GetProcAddress(mod, "Add");
pfngetversion getVersionNumberA =
(pfngetversion)GetProcAddress(mod, "getVersionNumberA");
and then you can just call using the function pointer:
add(1, 2);
std::cout << getVersionNumberA();
Although, it seems like your question has bits and pieces of two different functions!

Resources