0

I've been trying to call a function which resides in an injected DLL using the DLL injector process. The code from this answer works fine with no arguments but passing an argument causes random (non-initialized) gibberish like -1733099520 to be passed to the function instead of the desired DWORD:

DWORD speed_up = 1;
RemoteLibraryFunction(hProcess, targetDll, "set_speedup", &speed_up, sizeof speed_up, &lpReturn);

The DLL function I'm calling is defined as:

#define DLL_EXPORT extern "C" __declspec(dllexport)

DLL_EXPORT void set_speedup(const DWORD new_speed)
{
    sprintf_s(debug_message_buffer, "Setting new speed to: %i\n", new_speed);
    OutputDebugStringA(debug_message_buffer);
    speed = new_speed;
}

Note that I'm using DebugView++ to observe the output of OutputDebugStringA().

What am I doing wrong? It seems like the parameters are not set/passed correctly but the code seems correct and no functions failed.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
  • Attach a debugger to the remote process. When execution reaches `set_speedup`, go up one stack frame and see how the parameters were set up. Compare that against the function preamble to see how it expects its parameters. – Botje Aug 06 '19 at 08:17
  • What is the calling convention? Enforce it perhaps with __stdcall. – Michael Chourdakis Aug 06 '19 at 08:28
  • `CreateRemoteThread` expects the `ThreadProc` to use WINAPI __stdcall calling conventions, while the default calling convention is __cdecl. This should be evident from the disassembly in my first comment. – Botje Aug 06 '19 at 08:34
  • @Botje: Thanks for the calling conventions hint but enforcing `__stdcall` still does not work. It now yields values like `528154624`: `extern "C" __declspec(dllexport) void __stdcall set_speedup(const DWORD new_speed)` – BullyWiiPlaza Aug 06 '19 at 18:21
  • Back to the debugger then. That will tell you how arguments are passed and how the function expects them. – Botje Aug 06 '19 at 19:50

1 Answers1

0

It turns out the passed parameter was passed in as address of the DWORD instead of the DWORD. This can be fixed by changing the called function's signature to something like the following:

#define DLL_EXPORT extern "C" __declspec(dllexport)

DLL_EXPORT void set_speedup(const LPVOID acceleration_pointer)
{
    const auto acceleration = *static_cast<DWORD*>(acceleration_pointer);
    speed = acceleration;
}

The calling convention did not matter. Now the call works as expected.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185