简单的说是指通过给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下个断点:
0012FC50 00602C9D /CALL 到 VirtualAllocEx 来自 fxxk.00602C9A
0012FC54 0000004C |hProcess = 0000004C
0012FC58 00400000 |lpAddress = 00400000
0012FC5C 00053000 |dwSize = 53000 (339968.)
0012FC60 00003000 |flAllocationType = 3000 (12288.)
0012FC64 00000004 \flProtect = 4
这样就知道该在何处Dump,要Dump多大了:
Dump出来之后,需要对文件做几个小修复:把文件对其粒度FileAlignment改为内存对齐粒度SectionAlignment同样的值,之后还需要把所有节表头的PointerToRawData改为VirtualAddress同样的值,保存即可。