3

I am working on a project to generate a dummy DLL for offline testing. We have the real DLL and its header file, though they seem incompatible. The names in the DLL are unmangled but the function forward declarations declarations are called out as __stdcall:

example.h

DWORD __stdcall DoSomething(byte aByte);

example.dll in Dependency Walker:

2 (0x0002)   2 (0x0002)   DoSomething   0x000831C0

So far as I've read, if it is possible to export a function in the __stdcall convention, its name should read in dependency walker as:

2 (0x0002)   2 (0x0002)   _DoSomething@1   0x000831C0

Does this imply our header file does not correspond to the compiled DLL or am I missing something?

Ultimately, how do I form the export of the dummy function to behave the same way as the real DLL I am emulating?

J Collins
  • 2,106
  • 1
  • 23
  • 30

2 Answers2

5

There are only two ways to not get the __stdcall name decoration:

  • You must use a .def file to rename the exports. Get ahead by not using it.

  • You built your code to target x64. Since it blissfully has only one calling convention, the compiler will ignore your __stdcall attribute and it will not decorate the name. Now you'd need a .def file to rename the export. Never do this, nobody will expect the decoration to be used in 64-bit code.

Do note that, if decorated, the exported name will be _DoSomething@4. The @ part of the name states the size of the stack activation frame. In other words, the number of bytes that need to be popped off the stack before the function returns. It can never be 1 for 32-bit code, it is always a multiple of 4. This name decoration exists because __stdcall is so dangerous, the function popping more or less of the stack than expected causes a very hard to diagnose stack imbalance. The linker catches the function prototype declaration mistake.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    Thanks @Hans, it turns out we used a method that probably in all respects equals your option 1, that is by using a #pragma to rename the export `#pragma comment(linker, "/export:DoSomething=_DoSomething@4")`. Thanks for the hint on the standard byte count multiplier (4 on 32 bit, 8 on 64,) it did seem like a trend that all the numbers I'd seen were multiples of 4, just assumed coincidence. – J Collins Jun 25 '14 at 13:36
  • 1
    Also note, it's not at all my preference to use this, we are just trying to duplicate the functionality of a proprietary DLL. – J Collins Jun 25 '14 at 13:38
  • Hmm, I suppose I'd have to edit my answer to change to *three*. I'll skip, this is not a documented capability of /EXPORT. – Hans Passant Jun 25 '14 at 14:43
0

for stop changing procedures name that you use __stdcall before: if you use gnu c++ compiler add "-Wl,--kill-at" parameter to your linker.

if you use code-blocks:

"Settings" -> "Compiler..."
"Global compiler settings"
"Linker settings"
"Other linker options":
add: "-Wl,--kill-at"

if you use devc++

project->project options
Parameters
add "-Wl,--kill-at" to linker
Amir
  • 1,638
  • 19
  • 26