采用CreateProcess的方法,实现起来比较复杂,但没有上面几种方法的局限性。且可以用其他工具(VC等)调试注入的DLL。下面进行介绍.原理如下:
1. 用CreateProcess(CREATE_SUSPENDED)启动目标进程。
2. 找到目标进程的入口,用ImageHlp中的函数可以实现。
3. 将目标进程入口的代码保存起来。
4. 在目标进程的入口写入LoadLibrary(MyDll)实现Dll的注入。
5. 用ResumeThread运行目标进程。
6. 目标进程就运行了LoadLibrary(MyDll),实现DLL的注入。
7. 目标进程运行完LoadLibrary(MyDll)后,将原来的代码写回目标进程的入口。
8. 目标进程Jmp至原来的入口,继续运行程序。
从原理上可以看出,DLL的注入在目标进程的开始就运行了,而且不是用Debug的方案,这样,就没有上面方案的局限性了。该方案的关键在6,7,8三步,实现方法需要监视进程和DLL合作。下面,结合代码进行分析。
在监视进程中,创建FileMapping,用来保存目标进程的入口代码,同时保证DLL中可以访问。在第7步实现将原目标代码写回目标进程的入口。
上面结构体的代码为汇编代码,对应的汇编为:
准备工作:
第一步:用CreateProcess(CREATE_SUSPENDED)启动目标进程。
// 找到目标进程的入口点,函数如下
第二步:找到目标进程的入口,用ImageHlp中的函数可以实现。
// 保存目标进程的代码
第三步:将目标进程入口的代码保存起来。
// 第四步:在目标进程的入口写入LoadLibrary(MyDll)实现Dll的注入。
// 继续目标进程的运行
第五步:用ResumeThread运行目标进程。
在监视进程中就结束了自己的任务,剩下的第6,7,8步就需要在Dll的DllMain中进行配合。
DLL中用来保存数据的结构体
// 在DllMain的DLL_PROCESS_ATTACH中调用InitApiSpy函数
// 在该函数中实现第6,7,8步
第六步:目标进程就运行了LoadLibrary(MyDll),实现DLL的注入。
FILE_MAP_ALL_ACCESS,
0, 0, 0);
if(lpMem)
{
第七步:目标进程运行完LoadLibrary(MyDll)后,将原来的代码写回目标进程的入口。
第八步:目标进程Jmp至原来的入口,继续运行程序。
这样就实现了原来的目标,将DLL的注入放在目标进程的入口运行,实现了目标进程运行之前运行我们的注入Dll的功能。