问题描述:

Windows has an utility called rundll32.exe that can execute native dynamic link libraries as applications.

Say I have a piece of code that prints "Hello World!" to the console. Is it possible to write a library in C++ (preferably Visual C++) that can be executed using rundll32.exe and will run this code? If so, how?

网友答案:

Googling "rundll32", the 3rd hit was a link to documentation,

http://support.microsoft.com/kb/164787

According to that documentation, rundll32 calls a user-specified function with signature like wWinMain (except the first argument here is a window handle instead of an instance handle),

void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

So, trying this out:

// File [foo.def]
EXPORTS
    sayHello
// File [foo.cpp]
#include <iostream>

namespace myCode {

    void sayHello()
    {
        using namespace std;
        cout << "Hello, world!" << endl;
    }

}    // namespace myCode

#undef UNICODE
#define UNICODE
#include <windows.h>

extern "C" 
__declspec( dllexport )
void CALLBACK sayHello( HWND, HINSTANCE, wchar_t const*, int )
{
    AllocConsole();
    freopen( "CONIN$", "r", stdin ); 
    freopen( "CONOUT$", "w", stdout ); 
    freopen( "CONOUT$", "w", stderr ); 

    DWORD const infoBoxOptions = MB_ICONINFORMATION | MB_SETFOREGROUND;
    MessageBox( 0, L"Before call...", L"DLL message:", infoBoxOptions );
    myCode::sayHello();
    MessageBox( 0, L"After call...", L"DLL message:", infoBoxOptions );
}

Building & running:

[d:\dev\test]
> cl foo.cpp foo.def user32.lib /MD /LD /D _CRT_SECURE_NO_WARNINGS
foo.cpp
   Creating library foo.lib and object foo.exp

[d:\dev\test]
> rundll32 foo.dll,sayHello

[d:\dev\test]
> _

The output is presented in its own console window, created via AllocConsole, which is generally necessary since rundll32 is a GUI subsystem program (this is also the reason for the freopen calls).

To present the output in an existing console window one can just omit the calls to AllocConsole and freopen, and redirect standard output of rundll32 to a pipe. E.g. standard output can be piped through Windows’ more when the output is just a few lines, or through some *nix-utility cat for more lines. However, in the standard command interpreter [cmd.exe] it doesn’t work to just redirect the output to con.

网友答案:

http://support.microsoft.com/kb/164787

This MSDN article I believe is still accurate; you define an entrypoint as

  void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
网友答案:

While it is possible to use rundll32 to run a properly-designed function in a DLL, it is not recommended. Doing so means that your DLL is at the mercy of rundll32's process settings (large address awareness, terminal service awareness, DPI awareness, elevation manifest, etc.) Even worse: If some other rundll32 process triggers an application compatibility behavior (such as low fragmentation heap), then that will affect all rundll32 processes including yours.

Just write a separate EXE.

网友答案:

Like said by Joe and yourself, use something like this:

 void CALLBACK func(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) 
 { 
   std::cout << "Hello world!" << std::endl; 
 }

However, CALLBACK = __stdcall, which, when your "func" is exported will changed to [email protected]

You could change this name, http://support.microsoft.com/kb/140485

so, you might want to try something similar to this:

rundll32.exe DLLTest.dll,[email protected] 
相关阅读:
Top