How to pass arguments to DLL initialization (ex. w

2019-05-11 00:12发布

How could one pass arguments to the initialization function of a DLL loaded via LoadLibrary? Is it possible at all? Without resorting to some kind of exported function or shared memory, that is.

4条回答
看我几分像从前
2楼-- · 2019-05-11 00:26

Another possible solution: create a second DLL that only exposes a "setparam" and a "getparam" method, than use it in both the application (setparam) and the dll's DllMain (getparam). In their basic form, the methods are implemented with static variables, but you can use more sophisticated technologies. This solution, although slightly more difficult, has some advantages:

  • it doesn't use any "global" convention (except the name of the common DLL!)

  • it doesn't consume possibly limited resources (e.g. environment variables)

  • it's general: you can use the same DLL wherever you want.

  • it may be made as powerful and complicated as you need: e.g. you can make it thread-safe if required. It's only a matter of implementation.

Here's a minimal example:

// The "helper" DLL //
static int param;
void setparam(int v) { param = v; }
int getparam(void) { return param; }

// The application //
setparam(12345);
LoadLibrary("TheDLL.dll");

// The DLL to which you want to pass parameters //
BOOL WINAPI DllMain(HINSTANCE h,DWORD re,LPVOID res)
{
int param;
  switch (re)
  {
  case DLL_PROCESS_ATTACH:
     param = getparam();
//...
查看更多
来,给爷笑一个
3楼-- · 2019-05-11 00:42

There is no direct way.

The easiest may be through environment variables. They can be set easily before calling LoadLibray with setenv, and then the DLL (in the same process) can retrieve them with getenv.

查看更多
贪生不怕死
4楼-- · 2019-05-11 00:45

It is "bad" and "ugly" but you can push arguments on to the stack with in-line ASM before you make your call and pop them back off in much the same way. A very hack-ish solution, but it can work. I only note it because it's POSSIBLE, not because it's a good way to do things.

查看更多
叼着烟拽天下
5楼-- · 2019-05-11 00:48

An alternative means

  While I'm not quite sure if this falls under "shared memory" (since you can also use this method to send data to DLLs loaded in separate processes, as well)... You could allocate some memory at a specific address using VirtualAllocEx, pass in a struct containing all the data the DLL will need using WriteProcessMemory, then lock it with VirtualLock before loading the DLL.

Then in the DLL's entry point function, I would use VirtualUnlock, grab that data using ReadProcessMemory, then VirtualFree to clean up resources.

Although a bit choppy, this is especially useful if you have more than just a simple string to pass on.
Note that you must have read/write access in the target process for this to work.
 

Example (pseudo-code)

// YourApp.cpp

struct DataToSend {
    int myInt;
    char myStr[320];
};
DataToSend m_data = { 1337, "This is a test string...\0" };

// ...
PVOID remoteData = VirtualAllocEx( hTargetProcess, NULL, sizeof(m_data), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
WriteProcessMemory( hTargetProcess, remoteData, &m_data, sizeof(m_data), NULL );
VirtualLock( remoteData, sizeof(m_data) );
// Save the address (DWORD) of remoteData to the registry, to a local file, or using setenv as suggested in other answers here

 

// YourDll.cpp

BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
    DataToSend m_data = {0};
    PVOID localData = /* address used in YourApp */ NULL;
    //...
    VirtualUnlock( localData, sizeof(m_data) );
    ReadProcessMemory( hProcess, localData, &m_data, sizeof(m_data), NULL );
    VirtualFree( localData, 0, MEM_RELEASE );
}
查看更多
登录 后发表回答