DLL注入的最佳实践?

use*_*287 4 c++ dll reverse-engineering memory-editing dll-injection

假设我想将DLL注入到每250毫秒编辑一次地址A的进程中.我需要使用DllMain,对吧?问题是我不允许在DllMain内等待.所以我必须创建一个线程?或者这不绕过限制?我该怎么做呢?

此外,使用DLL注入使用EXE编辑应用程序的内存有什么好处?

另外,CreateThread中的堆栈大小应该是多少?如果它太小或太大怎么办?我怎么知道我需要多少钱?

小智 5

从您的描述中,您似乎已经知道如何让目标进程加载您的DLL.如果我的假设是正确的,那么答案很简单:从DLLMain创建一个线程并在线程中实现你的逻辑.只要您的代码遵守下面列出的规则,您就可以了.

文档描述了DLLMain中可以做什么和不可以做什么以及为什么.

如文档所述,您永远不应在DllMain中执行以下任务:

  • 调用LoadLibrary或LoadLibraryEx(直接或间接).这可能会导致死锁或崩溃.
  • 与其他线程同步.这可能会导致死锁.
  • 获取由等待获取加载程序锁定的代码所拥有的同步对象.这可能会导致死锁.
  • 使用CoInitializeEx初始化COM线程.在某些情况下,此函数可以调用LoadLibraryEx.
  • 调用注册表函数.这些功能在Advapi32.dll中实现.如果在DLL之前未初始化Advapi32.dll,则DLL可以访问未初始化的内存并导致进程崩溃.
  • 调用CreateProces.创建进程可以加载另一个DLL.
  • 调用ExitThread.在DLL分离期间退出线程可能导致再次获取加载程序锁定,从而导致死锁或崩溃.
  • 调用CreateThread.如果不与其他线程同步,则创建线程可以正常工作,但这样做有风险.
  • 创建命名管道或其他命名对象(仅限Windows 2000).在Windows 2000中,命名对象由终端服务DLL提供.如果未初始化此DLL,则对DLL的调用可能导致进程崩溃.
  • 使用动态C运行时(CRT)中的内存管理功能.如果未初始化CRT DLL,则对这些函数的调用可能导致进程崩溃.
  • 调用User32.dll或Gdi32.dll中的函数.某些函数加载另一个DLL,可能无法初始化.
  • 使用托管代码.

在DllMain中执行以下任务是安全的:

  • 在编译时初始化静态数据结构和成员.
  • 创建并初始化同步对象
  • 分配内存并初始化动态数据结构(避免上面列出的功能.)
  • 设置线程本地存储(TLS).
  • 打开,读取和写入文件.
  • 调用Kernel32.dll中的函数(上面列出的函数除外).
  • 将全局指针设置为NULL,推迟动态成员的初始化.在Microsoft Windows Vista™中,您可以使用一次性初始化函数来确保在多线程环境中仅执行一次代码块.

你的第二个问题不太清楚.要将代码注入另一个进程,您必须从某个地方(浏览器,exe,等等)开始,然后写入目标进程内存以使其加载您的DLL.