【问题标题】:CreateThread in DLL Terminating PrematurelyDLL中的CreateThread过早终止
【发布时间】:2020-10-30 07:26:59
【问题描述】:

我正在尝试从控制台应用程序加载 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;
}

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

【问题讨论】:

  • 你不应该在DllMain内部调用CreateThreaddocs.microsoft.com/en-us/windows/win32/dlls/…
  • 您有关于如何正确执行我正在尝试的操作的示例代码?
  • 这里有 2 个线程并行工作:主线程和使用 CreateThread 创建的线程。当主线程退出时应用程序停止。此事件也终止辅助线程。正如其他答案所述,这里的主要问题是您在 DLLMain 中的操作非常有限。
  • @valkyrie:您的目标是从 DLL 中启动线程吗?还是弹出消息框?
  • 我的目标是摆脱在 DllMain 中束缚我的一切。如果我能做到这一点,我可以在弹出消息框的基础上做一些有价值的事情。

标签: c++ dll-injection createthread


【解决方案1】:

原因是你在DllMain 中做了一些不安全的事情:你正在调用CreateThread

您在DllMain 内响应进程附加的操作受到非常限制,这是documentation 调用的事实:

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

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

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

【讨论】:

    猜你喜欢
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    相关资源
    最近更新 更多