如何将参数传递给DLL初始化例如,通过LoadLibrary加载时?

问题描述

| 如何将参数传递给通过LoadLibrary加载的DLL的初始化函数?有可能吗?也就是说,无需诉诸某种导出功能或共享内存。     

解决方法

没有直接的方法。 最简单的方法可能是通过环境变量。在用before1ѭ调用
LoadLibray
之前,可以很容易地设置它们,然后DLL(在同一过程中)可以用
getenv
检索它们。     ,替代手段 虽然我不太确定这是否属于“共享内存”(因为您也可以使用此方法将数据发送到在单独的进程中加载​​的DLL),也可以在特定位置分配一些内存。使用
VirtualAllocEx
地址,使用
WriteProcessMemory
传递包含DLL将需要的所有数据的结构,然后在加载DLL之前用
VirtualLock
对其进行锁定。 然后在DLL的入口点函数中,我将使用
VirtualUnlock
,使用
ReadProcessMemory
抓取数据,然后使用
VirtualFree
清理资源。 尽管有点断断续续,但是如果您要传递的不仅仅是一个简单的字符串,则这特别有用。 请注意,您必须在目标进程中具有读/写访问权限,此功能才能起作用。 示例(伪代码)
// 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,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,NULL );
    VirtualFree( localData,MEM_RELEASE );
}
    ,另一个可能的解决方案:创建第二个DLL,该DLL只公开一个“ setparam”和一个“ getparam”方法,而不是在应用程序(setparam)和dll的DllMain(getparam)中使用它。这些方法的基本形式是使用静态变量实现的,但是您可以使用更复杂的技术。此解决方案虽然难度稍大,但具有一些优点: 它不使用任何\“ global \”约定(公用DLL的名称除外!) 它不会消耗可能有限的资源(例如环境变量) 很一般:您可以在任何地方使用相同的DLL。 它可能会根据您的需要而变得强大而复杂:例如您可以根据需要使其成为线程安全的。这只是实现的问题。 这是一个最小的示例:
// 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();
//...
    ,它是\“ bad \”和\“ ugly \”,但是您可以在进行调用之前使用内联ASM将参数推入堆栈,并以几乎相同的方式将其弹出。一个非常hack-ish的解决方案,但是它可以工作。我只注意到它是因为它是可能的,而不是因为它是做事的好方法。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...