一、注入技术的用途
从Windows内存体系(1)--虚拟地址空间文章中我们可以知道:
在 Windows 系统中,每个进程都有自己私有的地址空间。当我们用指针来引用内存时,指针的值表示的是进程自己的地址空间的一个虚拟的内存地址。进程不能通过指针来引用其他进程地址空间的内存。 这种设计提升了操作系统的健壮性和安全性,比如一个进程存在缺陷,可能会引用和覆盖随机地址处的内存数据,那么我们就不用担心这个缺陷会影响到操作系统及其他进程。
独立的地址空间有利于系统的稳定性。但也带来了诸多不便,下面列举了需要跨越进程的边界来访问另一个进程地址空间的情况:
- 我们要从另一个进程创建的窗口来派生子类窗口,比如附着在 Windows 资源管理器上的一些小插件等。
- 我们需要假借其他进程之名做某些事情。
- 我们需要获取其他进程的更多详细信息,如加载了哪些 dll 等。
- 我们需要对其他进程的某些函数进行HOOK。
- 以及干一些羞羞的事情…
为了满足上述需求,我们可以使用 DLL 注入的技术,将我们自己开发的 DLL 注入到另一个进程的地址空间中,这样 DLL 中的代码就可以在该进程地址空间中执行。
二、什么样的 DLL 可以被注入
理论上任何 DLL 都可以被注入到其他进程之中,但是大多数情况下,我们注入到其他进程之中是为了实现某些功能、做某些事情的,所以我们需要在 DLL 被注入之后,DLL 中的功能代码能够被自动执行。
DLL 被首次载入到进程中时,会收到DLL_PROCESS_ATTACH
通知,即调用DllMain
函数,并且参数fdwReason
的值被设为DLL_PROCESS_ATTACH
。
我们可以在收到DLL_PROCESS_ATTACH
通知时开始我们的业务逻辑。
下面是一个最简单的 dll 的源码,在被注入成功后(即收到DLL_PROCESS_ATTACH
通知时)弹出消息提示框:
1 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved ) { |
另外,当 DLL 被从目标进程卸载时,DLL 会收到DLL_PROCESS_DETACH
通知,我们可以在该通知的处理过程中做最后的善后工作,防止出现资源泄漏、程序崩溃等问题。