从您的描述中,您似乎已经知道如何让目标进程加载您的DLL。如果我的假设是正确的,那么答案很简单:从DLLMain创建一个线程并在线程中实现你的逻辑。只要您的代码遵守下面列出的规则,您就可以了。
这个document描述了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可能会导致该DLL
崩溃的过程。
- 使用动态C运行时(CRT)中的内存管理功能。如果未初始化CRT DLL,则对这些函数的调用可能导致进程崩溃。
- 调用User32.dll或Gdi32.dll中的函数。某些函数加载另一个DLL,可能无法初始化。
- 使用托管代码。
以下任务在DllMain中可以安全执行:
- 在编译时初始化静态数据结构和成员。
- 创建并初始化同步对象
- 分配内存并初始化动态数据结构(避免上面列出的功能。)
- 设置线程本地存储(TLS)。
- 打开,读取和写入文件。
- 调用Kernel32.dll中的函数(上面列出的函数除外)。
- 将全局指针设置为NULL,从而推迟动态成员的初始化。在Microsoft Windows Vista™中,您可以使用一次性初始化函数来确保在多线程环境中仅执行一次代码块。
我的第二个问题不太清楚。要将代码注入另一个进程,您必须从某个地方(浏览器,exe,等等)开始,然后写入目标进程内存以使其加载您的DLL。