傀儡进程(参见《动态加载并执行Win32可执行程序》),简单的说是指通过给CreateProcess传递一个CREATE_SUSPENDED参数可以使得被创建的子进程处于挂起状态,此时EXE的映像会被加载到进程空间中,但是并不会立即被执行,除非调用ResumeThread。在ResumeThread之前,通过GetThreadContext获取主线程的上下文以取得PEB等,调用ZwUnmapViewOfSection/NtUnmapViewOfSection卸载子进程原有区块,通过VirtualAllocEx在子进程指定的基址分配空间,调用ReadProcessMemory和WriteProcessMemory这样的API来读写子进程空间的内容,调用 VirtualProtectEx修改内存的属性为可读可写可执行,最后调用SetThreadContext/ResumeThread即可让子进程执行恶意代码。
《动态加载并执行Win32可执行程序》提到的是把已知的EXE注入到其他正常的EXE之中,要获取到恶意代码直接拿到恶意的EXE就行了。而如果恶意代码是加密了的呢?比如把恶意代码加密后就存放于自身,然后创建自身子进程,解密恶意代码注入子进程,那么就要想办法对子进程内存Dump了。Dump的时机是在ResumeThread即将被调用之前,而此时在LordPE中直接完整Dump会出错,用PE Tools Dump下来的是原始的EXE,并不能把恶意代码Dump下来,用OllyDbg附加也提示出错。
这时其实可以用LordPE的部分Dump功能来完成,只需要知道内存地址的起始地址与大小即可,所以可以在VirtualAllocEx下个断点:
这样就知道该在何处Dump,要Dump多大了:
Dump出来之后,需要对文件做几个小修复:把文件对其粒度FileAlignment改为内存对齐粒度SectionAlignment同样的值,之后还需要把所有节表头的PointerToRawData改为VirtualAddress同样的值,保存即可。
这样就把恶意代码拿到手了。