(3).一个全局变量;
2.申请一块大小为要注入的模块的ImageSize的内存;
3.将要注入的模块写入到第2步所申请的内存中,注意,要注入的模块可以是外部的磁盘文件,也可以是注入程序自身已经被加载内存的Image镜像,如果是外部磁盘文件则需要按照注入模块的PE节表展开成Image镜像状态再写入到 第2步所申请的内存中,如果是注入程序本身的Image镜像则可以直接copy到第2步申请的内存之中,经过以上3个步骤,要注入的模块已经成为可执行的Image镜像状态
4.在被注入的目标进程中申请一块大小和第2步所申请内存的大小相同的内存;
5.把第4步申请的内存的首地址当成要注入的模块的ImageBase修复重定位;
6.把第3步生成的Image镜像写入到第4步所申请的内存之中;
7.挂起目标进程的主线程,并获得这个线程的Context;
8.保存第7步所获得的Context结构中的EIP备用,注意,要保存到要注入的模块的全局变量中,也就是第0步所说的那个全局变量;
9.修改Context的EIP,使得EIP的值正是第0步所说的跳转接口函数,此跳转函数的代码如下:
extern "C" VOID __declspec(naked) EntryPoint()
{
__asm
{
push dwRetAddress;//dwRetAddress正是第0步中准备好的全局变量
push ebp;
mov ebp, esp;
sub esp, 0xc0;
pushad;
pushfd;
lea edi, dword ptr ss : [ebp - 0xc0];
mov ecx, 30;
mov eax, 0xcccccccc;
rep stos dword ptr es : [edi];
call RepirIatTabel;
jmp tp;
lp:
popfd;
popad;
mov esp, ebp;
pop ebp;
ret;
tp:
jmp lp;
}
}
10.恢复目标进程的主线程;
11.可以看到在此跳转接口中调用了一个RepirIatTable的函数,这个函数正是第0步中所说的修复此注入模块的IAT表的函数;
12.在修复完IAT表后我们就可以为所欲为地做我们自己想做事情了;
看一下效果动图: