如何调试DLLMain函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何调试DLLMain函数相关的知识,希望对你有一定的参考价值。

我想编写DLL,但我想测试我正在编写的内容。 我尝试用F5调试它,但收到错误: enter image description here 我读了文章Walkthrough: Creating and Using a Dynamic Link Library (C++)如何做它和它的latest version。 但他们建议创建包含这些功能的头文件。

在我的例子中,我用Loader创建了DLL项目(dllmain.cpp)。

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    HANDLE hd;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hd = CreateFileA("C:UsersmyuserDesktop	est.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        OutputDebugString(L"HELLO");
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

我在同一个解决方案中创建了一个新的C ++控制台项目,但我不知道如何调用函数DllMain并对其进行调试。

为了使它有条不紊,我现在有两个项目: 1. Loader - 这是DLL项目 2. DLLTester - 这是一个控制台应用程序,它将从Loader项目运行DLL。

我将DLL项目的文件夹(Loader)添加到DLLTester项目的其他包含目录中。 我为DLL项目创建了一个标题(Loader.h)并添加了函数签名DLLMain

现在我可以在DLLMain function中看到它。 但我不知道我需要传递给这个函数的参数: enter image description here

我明白我需要传递3个参数: 1. HMODULE hModule 2. DWORD ul_reason_for_call 3. LPVOID lpReserverd

但我不需要进入那里。

码: 装载机项目: Loader.h:

#pragma once
#include "stdafx.h"

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
);

dllmain.cpp:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    HANDLE hd;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hd = CreateFileA("C:UsersmyuserDesktop	est.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        OutputDebugString(L"HELLO");
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

DLLTester项目: DLLTester.cpp:

// DLLTester.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Loader.h"

int main()
{
    DllMain(?,?,?) -> not sure what to enter here
    return 0;
}

看起来如何: enter image description here

答案

DllMain实际上是一个相当特殊的函数,当使用LoadLibraryLoadLibraryEx加载DLL时会自动调用(除非你做了一些邪恶的东西来防止它)。

如果你真的想调用它,你可以使用GetProcAddress,但不管你信不信,DLL的实际入口点通常是_DllMainCRTStartup(实际上除了调用构造函数和进行其他初始化之外还调用DllMain)。它甚至可以被开发者覆盖为完全不同的东西。

所以我真的不知道如何调用DllMain可以对任何普通的DLL做任何有用的事情。它不执行所有的初始化/清理(特别是启动时的C ++构造函数调用),并且它已经被调用(除非你用DONT_RESOLVE_DLL_REFERENCES来抑制它)。

另一答案

调试DllMain的简单方法是使用静态链接(即使用__declspec(dllexport)/ __ declspec(dllimport)语法),然后将您的DLL项目设置为启动项目,但让调试器启动链接到图书馆。您将程序设置为在项目设置中运行(项目 - >属性,然后调试 - >命令。

然后,您可以设置断点并从DLL中正常执行跟踪。

我知道你可以为动态加载的DLL中的正常函数做断点和诸如此类的东西,我只是不确定DllMain。

以上是关于如何调试DLLMain函数的主要内容,如果未能解决你的问题,请参考以下文章

正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码

正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

错误异常大全:正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

错误异常大全:正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

从DllMain调用LoadLibrary