2

我正在尝试从控制台应用程序加载 DLL。简单的控制台应用程序如下所示:

#include <iostream>
#include <windows.h>

int main(){
    HMODULE handleDll = LoadLibraryA("C:\\Tools\\TestDLL.dll");
    if (handleDll)
    {
        std::cout << "DLL Loaded at Address: " << handleDll << std::endl;
    }

    FreeLibrary(handleDll);
}

DLL 应该弹出一个 MessageBox,但它只是在屏幕上闪烁而不是等待用户输入。DLL代码如下:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>

DWORD WINAPI ThreadProc( __in  LPVOID lpParameter )
{
    MessageBox(NULL, L"Hi From The Thread!", L"Pop a Box!", MB_OK);
    return 0;
}

extern "C" __declspec(dllexport) 
VOID PopMessageBox()
{
    DWORD ThreadID;
    HANDLE handleThread; 

    handleThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadID);
    CloseHandle(handleThread);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        PopMessageBox();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

我的问题是..如何使线程函数中的代码完全执行而不会过早终止或导致痛苦的死锁?为我不完美的英语和缺乏经验道歉。

4

1 回答 1

-1

原因是你在做一些不安全的事情DllMain:你在打电话CreateThread

您在响应流程附加时可以从内部执行的操作非常有限,文档指出这一事实:DllMain

在 DLL 入口点中可以安全地执行的操作有很大的限制。有关在 DllMain 中调用不安全的特定 Windows API,请参阅一般最佳实践。如果您需要除了最简单的初始化之外的任何其他内容,请在 DLL 的初始化函数中执行此操作。您可以要求应用程序在 DllMain 运行之后和调用 DLL 中的任何其他函数之前调用初始化函数。

该警告将您链接到“一般最佳实践”,其中包括“[c]all CreateThread。如果您不与其他线程同步,创建一个线程可以工作,但这是有风险的。”

即使没有与其他线程同步相关的风险,此代码在其他方面也很脆弱:例如,您main只需调用FreeLibrary和退出。您在 DLL 中生成的线程(实际上可能是在执行中间)将具有它应该运行的未映射代码。你实际上是从它下面拉出地毯!

于 2020-10-30T07:43:18.917 回答