【问题标题】:C++ Injecting a dll, do you need threads?C++注入一个dll,你需要线程吗?
【发布时间】:2016-04-07 08:12:15
【问题描述】:

我对它有点陌生,我还不完全理解线程术语,尽管我知道如何创建一个线程并运行具有多个线程的程序。我想知道的是,当您创建一个 dll 文件 (c++) 并将其注入到一个进程中时(比如说 gamehacking)。您是否需要在 dll 文件中创建线程,或者这不起作用?在我理解之后,主线程将从主机进程中运行,对吗?或者它是如何工作的?

【问题讨论】:

  • 您不一定需要在 DLL 中创建单独的线程。这取决于您需要做什么。
  • 由于“注入”不是一个固定的术语,因此无法说是否需要线程。您不需要每次都使用线程,但某些注入可能需要它们。
  • 好的,但是在 dll 文件中创建线程并且它们将在主机进程中单独运行是否有效?我在学校,所以我无法测试它,但这个想法突然袭击了我。或者线程会让它运行得更快吗?因为我的外部程序由于多线程而运行非常缓慢,尽管我的代码还没有那么优化。因此,我可能会将其改为 dll 并将其注入到进程中。但我想知道我是否需要线程

标签: c++ multithreading dll


【解决方案1】:

这取决于您计划使用 DLL 实现的目标。如果那个特定的 DLL 有一些静态函数/实用程序类,它只需要一个输入,进行一些计算/处理并产生一个输出,那么这里就不需要线程。

但是,如果该 DLL 要侦听套接字或写入文件或执行需要一些并行性的实际工作,那么您可能希望在该 DLL 中创建线程。

基本上,您必须了解,该 DLL 完成的任务是什么。 DLL 可以在编译时链接为普通库,也可以根据您的需要/用例在运行时动态加载。

回答你的问题,

Would you need to create threads in the dll file, or is that not going to work?

Ans : 并非总是如此。您需要创建线程来完成某些任务。话虽如此,但情况并非总是如此。在进程中运行 DLL 是完全可行的,无需任何线程。

After my understanding the main thread will be running from the host process right? Or how does it work?

Ans : 没错。您运行的任何进程,默认情况下都会有一个线程。如果您的应用程序足够简单,可以由单个线程处理,那么这是一件好事。跟上它:)

【讨论】:

  • 感谢您的回答,它为我清理了一些东西。 :p
  • 很高兴。如果您愿意,您可能想支持我的回答。
【解决方案2】:

由于您具体指的是注入 DLL,因此除了已经说过的内容之外,我还有一些意见供您参考。

首先,让我们确保线程、进程和模块的概念清晰。

线程基本上是代码运行的直接环境。诸如处理器寄存器和堆栈变量的当前状态(例如,在大多数情况下,函数中的局部变量,以及当前执行在代码中的位置)之类的东西属于线程。还有其他资源通常具有线程关联性,例如 windows。这在很大程度上取决于所讨论的资源是否以及它们具有什么样的线程亲和性。

假设您编写了一个简单的 hello world 程序。它将在一个线程中运行,该线程从头到尾遍历您的程序并打印“Hello World”。现在让我们假设您要编写一个程序,该程序缓慢地写入“Hello World”,每秒一个字符,但同时下载一个文件。然后你可以创建第二个线程,让一个线程缓慢输出“Hello World”,一个线程下载文件。这意味着执行可以并行发生,具有不同的本地状态 - 一个线程当前在您的 printHelloWorld 函数内,一个线程在 downloadFile 内。

进程基本上是一个或多个线程的容器。它将它们捆绑在一个使用相同虚拟内存的共享环境中(这意味着例如代码中的全局变量可以从所有线程访问,但这需要仔细同步以避免竞争条件)并共享资源,例如文件句柄进程中的线程创建。因此,您之前的 hello-world-and-download 程序将在 1 个进程中有 2 个线程,例如共享控制台,并在任务管理器中被视为一个实体。

模块是一个包含可执行代码(在大多数情况下)并被加载到进程中的文件。通常,在一个进程中有一个 EXE 文件和几个 DLL 文件作为模块加载。 DLL 文件和 EXE 文件在技术上几乎相同,但 EXE 文件是进程启动的基础,而 DLL 文件是导出某些功能的库,可供其他模块使用。由于我说模块被加载到进程中,这意味着一个模块可以被进程中的所有线程访问,并且它本身没有线程亲和性——在我们前面的例子中,当第二个线程下载文件时,它可能正在调用 HTTP 网络 DLL,然后其代码将在第二个线程中运行。 Windows 会自动将许多模块加载到每个进程中,而其他模块可能由编译器的某些功能加载。

好的,那么,回到你的问题:

是否需要在 dll 文件中创建线程[...]?

本质上,使用 DLL 与是否需要创建新线程无关。这取决于您想做什么 - 如果您需要与正在运行的任何其他代码并行执行一些耗时的任务,那么您需要为其创建一个新线程,否则就没有必要了。

[...]还是不行?

如前所述,您可以根据需要创建新线程(它会起作用),但这并不是使用 DLL 的必要条件。

根据我的理解,主线程将从主机进程中运行,对吗?

宿主进程的主线程当然会在宿主进程中。 (虽然技术上没有“主线程”,因为让进程中的第一个线程创建第二个线程然后终止是完全有效的,所以只有第二个线程会再运行,你通常会让第一个线程通过进程的整个生命周期,在这种情况下您可能可以将其称为“主线程”。)但是,当前运行的代码位于哪个模块中,将取决于线程当前正在做什么。

让我回到“注入”的问题:前面的答案似乎假设了一个更“正常”的环境,您的 DLL 只是链接到程序并打算由它加载。在这种情况下,您的 DLL 的初始化例程(在将模块加载到进程中时自动运行)将只在“主线程”中运行,可能在进程的实际工作开始之前。

但是,当您注入 DLL 时,情况会有所不同。这取决于您如何进行注射:

  • 如果您通过修改宿主EXE 的导入表来注入DLL,那么您的DLL 将按照我刚才所说的“正常”方式加载。因此,您可以期望您的初始化例程在进程启动期间在主线程中运行。
  • 如果您使用 AppInit_DLLs 注册表项注入 DLL,则相同。
  • 如果您通过启动挂起的主机进程来注入 DLL,然后编写一个存根以将 DLL 加载到进程的内存中并使用 SetThreadContext 将指令指针指向它,那么同样的事情。
  • 如果您通过远程调用目标进程内的LoadLibrary 的方式注入DLL,使用CreateRemoteThread,那么,正如名称所暗示的那样,您正在进程内创建一个新线程 .在这个线程中,LoadLibrary 将加载您的 DLL 并调用您的初始化例程,因此在这种情况下,您的初始化例程确实会在“主线程”之外的新线程中运行。

【讨论】:

    【解决方案3】:

    每个进程至少有一个线程。当该进程启动时,可以将一堆函数或库链接到该进程的内存空间。这就是dll。与直接链接到二进制文件相比的优点是库只需要存在于文件系统中的一处和内存中的一处,同时被多个进程使用。这是一种链接技术,类似于在 Linux 中使用 .so 文件的方式。它与线程无关。

    【讨论】:

    • 好的,所以我实际上应该从我正在尝试为其制作程序的进程中运行我的程序,而不是制作外部程序?我正在做一个游戏黑客哈哈
    【解决方案4】:

    您是否需要在 dll 文件中创建线程,或者那样不行?

    加载一个不包含将要运行的代码的 DLL 没有任何意义。也就是说,DLL 代码可以通过多种方式运行:

    • 加载 DLL 时,它有机会运行一些初始化代码

    • 在初始化期间,它可能:

      • 启动一个或多个线程,这些线程可以继续运行 - 可能会监视触发它们的某些操作的某些事件

      • 注册来自操作系统或应用程序的回调,例如设置信号处理程序、按键处理程序、任何类型的事件处理程序......

    • 它可能包含程序将动态查找并运行的函数,将您的 DLL 代码误认为是程序附带的这些函数的原始版本

    其中哪些适合您的需求完全取决于您的 DLL 试图实现的目标,以及实现它的技术要求。例如,如果监视某些内存以具有特定内容,然后进一步修改它,那么在您的 DLL 中具有一个由操作系统警报服务调用的函数就足够了,如果未找到触发内存内容,则将自身重置以稍后再次关闭.但是,触发器可能是文件的存在,或共享内存服务,正在创建的套接字等。

    根据我的理解,主线程将从主机进程中运行,对吗?或者它是如何工作的?

    是的 - 在进程内启动的线程 - 包括任何 DLL 初始化例程 - 也在进程内。有一些库函数可能会创建其他进程 - 例如 fork、popen、system - 可能包含它们自己的线程。

    【讨论】:

    • 谢谢 :) Toofewcharacters
    猜你喜欢
    • 2020-11-09
    • 2021-10-16
    • 2021-11-14
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多