原创文章,转载请贴出处
远程注入时有一个不痛不痒的问题,DLL与shellcode如何卸载自身,做到无痕清除?
由于我的DLL自卸载用到了Shellcode,所以两个问题都需要解决。
DLL卸载一般使用FreeLibrary,但是如果DLL自己Free自己,会遇到下一条指令(eip/rip)无效的问题(DLL自己的内存空间已经卸载了,而下一条指令仍然指向原来的DLL空间)。微软给出的解决办法是FreeLibraryAndExitThread这个函数,卸载DLL后立马退出。
FreeLibrary只是把DLL的引用计数减1,如果之前多次LoadLibrary,则需要多次FreeLibrary来完全卸载DLL,而FreeLibraryAndExitThread只是调用一次FreeLibrary就退出了,很可能DLL根本没有被卸载。
在DLL外部,以下代码可以完全卸载DLL:
while(ret)
{
ret= FreeLibrary(hmod);
}
但是不能在DLL内部使用。
于是想到可以通过把释放DLL的代码写成Shellcode,这样即使DLL被卸载也不会使eip无效。
通过GlobalAlloc得到缓冲区(不能用malloc,因为它的内存随DLL一同释放了),用VirtualProtect使缓冲区可执行,memcpy复制真正释放dll的代码到缓冲区中,执行代码,就可以完全卸载DLL了(X86代码如下)
一点要注意,我的上一篇文章提到VC需要关闭几个开关才能正常的拷贝函数内存指令
struct myEnvir