标签: dllmain

DLL主要在Windows Vs. __attribute __((构造函数))Linux上的入口点

考虑代码

可执行程序:

int main ()
{

    printf("Executable Main, loading library\n");
#ifdef HAVE_WINDOWS
    HMODULE lib = LoadLibraryA ("testdll.dll"); 
#elif defined(HAVE_LINUX)
    void * lib  = dlopen("testdll.so", RTLD_LAZY);  
#endif 

    if (lib) {
        printf("Executable Main, Freeing library\n");
    #ifdef HAVE_WINDOWS
        FreeLibrary (lib); 
    #elif defined(HAVE_LINUX)
        dlclose(lib);   
    #endif 
    }
    printf("Executable Main, exiting\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

DLL

struct Moo
{
    Moo() { printf("DLL Moo, constructor\n"); }
    ~Moo() { printf("DLL Moo, destructor\n"); }
};

Moo m;

#ifdef HAVE_WINDOWS
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved)
{
    switch …
Run Code Online (Sandbox Code Playgroud)

c++ linux windows shared-libraries dllmain

5
推荐指数
1
解决办法
3532
查看次数

在哪种情况下动态CRT在调用用户提供的DllMain时尚未初始化?

序言:这个问题特别关注动态 CRT 的行为,并且仅与之相关/MD.它并不质疑任何其他建议的有效性.DllMain.


我们被告知:(参考:动态链接库的最佳实践,MSDN,2006年5月17日)

您永远不应该在DllMain中执行以下任务:

  • ...
  • 使用动态 C运行时(CRT)中的内存管理功能.如果未初始化CRT DLL,则对这些函数的调用可能导致进程崩溃.
  • ...

其他人已经对此提出质疑(如:质疑论证的有效性),既然我们在那里得到了答案,我们可以清楚地看到一个相当简单的案例,这可能会引起麻烦:

您正在假设DLL的入口点始终是_DllMainCRTStartup.情况并非如此,它只是链接器的默认值.它可以是程序员想要的任何东西,使用链接器的/ ENTRYPOINT选项可以快速轻松地更改.微软没有办法阻止这一点.

所以这些是这个问题的要素:

  • 链接和提供自定义时是否还有其他情况,动态 CRT应该不能完全初始化?/MD/ENTRYPOINT

    • 具体来说,如果所有DLL加载只通过"静态依赖"完成,即根本没有显式LoadLibrary调用,只需链接时间DLL依赖项.
  • 额外:MS文档专门调用"内存管理功能",但据我所知,如果CRT未初始化,可能任何 CRT功能都应该是不安全的.为什么以这种方式调用内存管理功能?

  • 三:

    WRT.对于习惯ENTRYPOINT:我不太明白这是一个如此重要的场景,它需要被包含在不做DllMain列表中而无需进一步限定.IFF我提供了一个自定义入口点,我负责正确初始化CRT,或者CRT在我的程序中的任何地方都不能正常工作,而不仅仅是DllMain.为什么要专门调用DllMain部分?

    这导致我回到Q.1,即如果这是动态 CRT 存在问题的唯一情况.澄清或大开眼界为什么这对于DllMain来说更重要的是,对于DLL的其他部分,或者我可能会错过这里,我们将不胜感激.


额外链接:


理由:我觉得我应该为上下文添加这个:我问这个是因为我们有大量的代码通过全局C++对象构造函数来做事.实际上破坏的事情多年来一直经过审查(如并发LoadLibrary,线程同步等),但所有代码都充满了stdC++和CRT功能,这些功能已经在Windows XP,7和Windows 10上运行多年了任何已知的打嗝.虽然我不是一个哭泣"但它只是有效",我必须在这里做一个工程判断,试图"修复"这个是否有任何短期到中等价值.因此,如果肥皂盒的答案可以留在他们的盒子里,我将不胜感激.

winapi msvcrt visual-c++ dllmain

5
推荐指数
1
解决办法
361
查看次数

在 DllMain() 之前调用了哪些函数?

在 DllMain() 之前调用哪些函数?如果在 C 运行时初始化期间不止一个,那么顺序很重要。

c dll windows-runtime dllmain

4
推荐指数
1
解决办法
1140
查看次数

何时使用DLL_PROCESS_VERIFIER标志调用DllMain?

在Windows上,标准DLL入口点称为DllMain.第二个参数是DWORD ul_reason_for_call.

我在MSDN上查找了第二个参数的可能值.以下是显而易见的:

DLL_PROCESS_ATTACH:
DLL_THREAD_ATTACH:
DLL_THREAD_DETACH:
DLL_PROCESS_DETACH:
Run Code Online (Sandbox Code Playgroud)

但是关于:

DLL_PROCESS_VERIFIER
Run Code Online (Sandbox Code Playgroud)

何时使用此标志调用入口点?在DLL的"正常"操作期间我应该担心它吗?

请注意,我只DLL_PROCESS_VERIFIER在Visual Studio 2005的头文件中看到,而不是2008.

c++ windows dll winapi dllmain

3
推荐指数
1
解决办法
1859
查看次数

注入后未执行 DLLMain()

我已经用 C++ 编写了一个 dll 和注入器。dll代码如下:

#include <cstdio>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <fstream>
#include <winsock.h>
using namespace std;
#pragma comment(lib, "wsock32.lib")

extern "C" __declspec(dllexport) void UploadFile()
{
.....
}

INT APIENTRY DLLMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch(fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(0,"Process Attach","Info",MB_OK);
        UploadFile();
        break;
    case DLL_THREAD_ATTACH:
        MessageBox(0,"Thread Attach","Info",MB_OK);
        UploadFile();
        break;
    case DLL_PROCESS_DETACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    default:
        break;
    }
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

dll 将特定文件上传到服务器。我能够使用 LoadLibrary() 和 CreateRemoteThread() 成功地将 dll 注入“notepad.exe”,但它没有被执行。甚至不是 dllmain() 函数。不知道出了什么问题。

c++ windows dll-injection dllmain

3
推荐指数
1
解决办法
3663
查看次数

为什么不能从 DllMain 函数调用 CreateProcess?

我已经阅读了一些CreateProcess不能从DllMain函数中调用的来源。

创建过程

不要从 DllMain 函数调用 CreateProcess。这会导致应用程序停止响应。

动态链接库最佳实践

永远不要从 DllMain 中执行以下任务: 调用 CreateProcess。创建一个进程可以加载另一个 DLL。

这是为什么?它指出它会导致应用程序停止响应,但这只是一种症状。真正的原因是什么?

我问的原因是我尝试从一个DllMain函数创建一个进程,它看起来工作得很好。

winapi createprocess dllmain

2
推荐指数
1
解决办法
1347
查看次数

为什么DLL_THREAD_DETACH会发生两次?

我正在学习COM.我在DLL中编写了一个简单的COM组件,并在注册表中注册了它.然后我创建了一个简单的客户端并尝试使用我的COM组件.但我不明白这种DllMain行为(我也读过这个).

extern "C" BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
  _In_ DWORD     fdwReason,
  _In_ LPVOID    lpvReserved){
  pDll = hinstDLL;
  if (DLL_PROCESS_ATTACH == fdwReason){
    trace("DllMain(): DLL_PROCESS_ATTACH");
  }
  else if (DLL_THREAD_ATTACH == fdwReason){
    trace("DllMain(): DLL_THREAD_ATTACH");
  }
  else if (DLL_PROCESS_DETACH == fdwReason){
    trace("DllMain(): DLL_PROCESS_DETACH");
  }
  else if (DLL_THREAD_DETACH == fdwReason){
    trace("DllMain(): DLL_THREAD_DETACH");
  }
  else{
    trace("DllMain(): unknown variant...");
  }
  return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

我期望每个DLL_PROCESS_ATTACHDLL_PROCESS_DETACH都被调用并且每个DLL_THREAD_ATTACHDLL_THREAD_DETACH都被调用(如果没有发生异常).

但我看到一个DLL_PROCESS_ATTACH有两个DLL_THREAD_DETACH:

在此输入图像描述

为什么会这样?

c++ com dll winapi dllmain

1
推荐指数
1
解决办法
2265
查看次数