C++Builder Define DLL Export Function Names Using DEF File

Recently, I've been working on looking for the way to customize dll export function names in C++Builder.
There are several methods to achieve this in VC++, including using a .def file, using __declspec keyword, and using an /EXPORT specification in a LINK command.
The third way seems not to be supported by bcc32 compiler (aka Borland C++ compiler), so I've researched on the implementation of the prior two methods.

First, I use __declspec(dllexport) keyword with specifying different calling conventions to export the functions below.

void __declspec(dllexport) DLLEXPORT()
{
return;
}

void __fastcall __declspec(dllexport) FASTCALL_DLLEXPORT()
{
return;
}

void __stdcall __declspec(dllexport) STDCALL_DLLEXPORT()
{
return;
}

void __cdecl __declspec(dllexport) CDECL_DLLEXPORT()
{
return;
}

extern "C" void __declspec(dllexport) EXTNC_DLLEXPORT()
{
return;
}

extern "C" void __fastcall __declspec(dllexport) EXTNC_FASTCALL_DLLEXPORT()
{
return;
}

extern "C" void __stdcall __declspec(dllexport) EXTNC_STDCALL_DLLEXPORT()
{
return;
}

extern "C" void __cdecl __declspec(dllexport) EXTNC_CDECL_DLLEXPORT()
{
return;
}

If we look up our code in a disassembler, we'll find that all of these functions have the same operation code like below.

TestDll.DLLEXPORT$qv - 55                    - push ebp
TestDll.DLLEXPORT$qv+1- 8B EC - mov ebp,esp
TestDll.DLLEXPORT$qv+3- 5D - pop ebp
TestDll.DLLEXPORT$qv+4- C3 - ret

And let me use impdef tool to list all the export functions to a def file.

impdef TestDll.def TestDll.dll

TestDll.def
LIBRARY     TESTDLL.DLL

EXPORTS
@CDECL_DLLEXPORT$qv @4 ; CDECL_DLLEXPORT()
@DLLEXPORT$qv @1 ; DLLEXPORT()
@EXTNC_FASTCALL_DLLEXPORT @6 ; extnc_fastcall_dllexport
@FASTCALL_DLLEXPORT$qqrv @2 ; __fastcall FASTCALL_DLLEXPORT()
@STDCALL_DLLEXPORT$qqsv @3 ; __stdcall STDCALL_DLLEXPORT()
EXTNC_STDCALL_DLLEXPORT @7 ; EXTNC_STDCALL_DLLEXPORT
_EXTNC_CDECL_DLLEXPORT @8 ; _EXTNC_CDECL_DLLEXPORT
_EXTNC_DLLEXPORT @5 ; _EXTNC_DLLEXPORT
___CPPdebugHook @9 ; ___CPPdebugHook

The result shows that whether we use extern "C" or not, the effect of functions using __cdecl are the same.
The reason is that it is the default calling convention for C and C++ programs.
(@1 with @4 and @5 with @8)
And this setting can be found in Project Options.

So if we modify our TestDll.def like this:

TestDll.def
LIBRARY     TESTDLL.DLL

EXPORTS
A=@CDECL_DLLEXPORT$qv
B=@DLLEXPORT$qv
C=@EXTNC_FASTCALL_DLLEXPORT
D=@FASTCALL_DLLEXPORT$qqrv
E=@STDCALL_DLLEXPORT$qqsv
F=EXTNC_STDCALL_DLLEXPORT
G=_EXTNC_CDECL_DLLEXPORT
H=_EXTNC_DLLEXPORT

and put it into the project then do a compile, cheer! We make it!

Let me orginize the result into tables:

void FUNCTION_NAME()

C/C++ __cdecl __stdcall __fastcall
extern "C" ´╝┐FUNCTION_NAME FUNCTION_NAME @FUNCTION_NAME
@FUNCTION_NAME$qv @FUNCTION_NAME$qqsv @FUNCTION_NAME$qqrv

After all, we can now export __declspec(naked) function in this way!
Since functions declared with the naked attribute, the compiler generates code without prolog and epilog code, we can have a pure assembly function and do less operations to hijack a dll. :p

extern "C" void __stdcall __declspec(naked) MyFunction()
{
__asm
{
Xor Eax, Eax
Ret
}
}
TestDll.def
LIBRARY     TESTDLL.DLL

EXPORTS
MyExportFunction=MyFunction
TestDll.MyExportFunction - 31 C0                 - xor eax,eax
TestDll.MyExportFunction+2- C3 - ret

Ref:
http://docwiki.embarcadero.com/RADStudio/XE6/en/Module_Definition_Files
http://aftcast.pixnet.net/blog/post/22191720-%E4%BD%BF%E7%94%A8vc%E8%88%87bcb%E9%96%8B%E7%99%BC%E7%9A%84dll
http://purefractalsolutions.com/show.php?a=utils/expdef
http://msdn.microsoft.com/en-US/library/d91k01sh.aspx
http://msdn.microsoft.com/en-US/library/7k30y2k5.aspx
http://msdn.microsoft.com/en-US/library/dabb5z75.aspx