前言
动态库dll与静态库lib编程5:进程注入技术。
一、说明
1.1 为什么要进行进程注入
到了WinNT以后的系列操作系统中,每个进程都有自己的4GB私有进程地址空间,彼此互不相关。进程A中的一个地址(比如0x12345678),到了进程B中相同的地方,存的东西完全不一样,或者说不可预料。所以说如果进程A想要看看或者修改进程B地址空间中的内容,就必须深入到其地址空间中。因为DLL是可以被加载到任何进程当中的,所以在进程注入中,DLL应该是主角,也就是说一些核心的代码都应该在DLL中编写。
1.2 进程注入的具体说明
注入的缺点:如果DLL程序的算法不是很好,或者DLL文件有bug,那么将影响目标进程的执行效率,或者说干脆目标进程崩溃。
注入的具体方法:目前Windows操作系统上面注入的方法很多,比如钩子、远程线程技术等。
二、远程线程技术实现进程注入
1.用到的API函数
OpenProcess(),获取已知进程的句柄
VirtualAllocEx(),在进程中申请空间
WriteProcessMemory(),向进程中写入东西
GetProcAddress(),取得函数在DLL中的地址
CreateRemoteThread(),在其他进程中创建新线程
CloseHandle(),关闭句柄
2.实例
新建工程
选择Windows桌面向导,即为传统的Win32项目
为了方便,这里使用桌面应用程序
编译器会自动生成一些代码框架,编译后得到如下结果
为了演示方便,这里不需要使用窗口,因此需要删掉一些系统自动生成的代码和资源。删掉如下文件
继续删掉两个头文件
只保留如下文件
然后删掉InjectTest.cpp中的一些代码使得程序能够正常运行,删除后的文件内代码如下。只保留程序的入口点函数WinMain()
// InjectTest.cpp : 定义应用程序的入口点。
//
#include "pch.h"
#include "InjectTest.h"
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
return 0;
}
同时,为了保证代码的正常运行,在预编译头文件pch.h中加入如下代码
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#<