读书人

注入程序的dll 怎么强制删除?

发布时间: 2013-10-27 15:21:50 作者: rapoo

注入程序的dll 如何强制删除??
钩子dll ,挂的全局钩子,所以很多程序都会注入
在升级程序的时候,调用了UnhookWindowsHookEx后dll却经常还保留在其他程序的进程中
导致更新文件失败,
在想有没有什么方法可以强制删除dll,使得升级能够成功

或者有什么方法能够在调用UnhookWindowsHookEx之后dll能完全的退出所有的程序??
[解决办法]
dll注入,一般都是ViturlMalloc到对方进程开一个线程,然后在线程中把事先准备好的dll load进对方进程里。
所以,想要把LoadLibrary的效果除去的,需要用对应的FreeLibrary,但参数是一个问题,要得到这个模块的句柄值,即要把LoadLibrary返回的handle值发回来才行,进程间通信的方法还是很多的,简单点的话,可以在LoadLibrary之后把HMoudle的值,写入一个固定位置的txt里,然后要卸载dll的,去读这个txt。
得到HMoudle值后,再用VitrulMalloc开线程调用FreeLibrary即可。当然最好是dll的dllmain做点处理把函数替换回去,防止卸载不掉,或者卸载完成后,目标进程崩溃。
[解决办法]
全局消息钩子会注入GUI进程,在该进程窗口有某些动作时注入,UnhookWindowsHookEx 后,也不是立即就自动释放,而是在被注入窗口有某些动作时才释放。
没有方法能使全局消息钩子注入的DLL能受你控制地被释放,但有一个优化方案,就是你UnhookWindowsHookEx后广播一个消息,这样就能让被注入的进程在未进行任何动作时“尽量地”感知全局钩子已卸载。
但这也不能保证。
而你的需求和这其实没有关系,删除不了,可以改名。你可以尝试:
if (!覆盖成功)
{
原文件 改名为 原文件.old;
更新文件到 原文件;
原文件.old 标记为重启删除;
}

如果只是想更新,根本没必要非把原来的删除。
[解决办法]

引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

dll注入,一般都是ViturlMalloc到对方进程开一个线程,然后在线程中把事先准备好的dll load进对方进程里。
所以,想要把LoadLibrary的效果除去的,需要用对应的FreeLibrary,但参数是一个问题,要得到这个模块的句柄值,即要把LoadLibrary返回的handle值发回来才行,进程间通信的方法还是很多的,简单点的话,可以在LoadLibrary之后把HMoudle的值,写入一个固定位置的txt里,然后要卸载dll的,去读这个txt。
得到HMoudle值后,再用VitrulMalloc开线程调用FreeLibrary即可。当然最好是dll的dllmain做点处理把函数替换回去,防止卸载不掉,或者卸载完成后,目标进程崩溃。


我LoadLibrary 之后挂完钩子之后就已经马上FreeLibrary了


不能马上FreeLibrary的,挂完钩子,你用于替换的函数都是在dll里的吧,你FreeLibrary之后,这些函数不就失效了么,达不到效果。如果这些函数是频繁使用的,那么你调用FreeLibrary时,由于dll中的函数正在使用中,那么FreeLibrary就会失败。
如果是FreeLibrary失败,可以用FreeLibraryAndExitThread强制退出。但也是要在,你不想再hook函数的时候调用,不然不仅hook也随之结束,被hook的进程可能也会立即崩溃。


但是我一直都是hook 之后就 freelibrary ,dll是有注入到程序中的,也运行正常,


freelibrary失败了呗,自己看返回值吧。


freelibrary 返回值是 1 是成功的
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.



用这个试试吧,FreeLibraryAndExitThread。FreeLibrary即使成功了,也只是引用计数减一,如果使用的线程不退出,不会真正的卸载的。
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

dll注入,一般都是ViturlMalloc到对方进程开一个线程,然后在线程中把事先准备好的dll load进对方进程里。
所以,想要把LoadLibrary的效果除去的,需要用对应的FreeLibrary,但参数是一个问题,要得到这个模块的句柄值,即要把LoadLibrary返回的handle值发回来才行,进程间通信的方法还是很多的,简单点的话,可以在LoadLibrary之后把HMoudle的值,写入一个固定位置的txt里,然后要卸载dll的,去读这个txt。
得到HMoudle值后,再用VitrulMalloc开线程调用FreeLibrary即可。当然最好是dll的dllmain做点处理把函数替换回去,防止卸载不掉,或者卸载完成后,目标进程崩溃。


我LoadLibrary 之后挂完钩子之后就已经马上FreeLibrary了


不能马上FreeLibrary的,挂完钩子,你用于替换的函数都是在dll里的吧,你FreeLibrary之后,这些函数不就失效了么,达不到效果。如果这些函数是频繁使用的,那么你调用FreeLibrary时,由于dll中的函数正在使用中,那么FreeLibrary就会失败。
如果是FreeLibrary失败,可以用FreeLibraryAndExitThread强制退出。但也是要在,你不想再hook函数的时候调用,不然不仅hook也随之结束,被hook的进程可能也会立即崩溃。


但是我一直都是hook 之后就 freelibrary ,dll是有注入到程序中的,也运行正常,


freelibrary失败了呗,自己看返回值吧。


freelibrary 返回值是 1 是成功的
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.



用这个试试吧,FreeLibraryAndExitThread。FreeLibrary即使成功了,也只是引用计数减一,如果使用的线程不退出,不会真正的卸载的。

你之前说的保存挂钩LoadLibrary 的那个dll handle ,在卸载钩子之后再去freelibrary 的方法我有试过了,但是效果跟LoadLibrary 之后 立即FreeLibrary 是一样的,
所以感觉应该就是hiroyukki说的情况


随你了,但建议你还是把我好好看看,感觉你根本没仔细看。
[解决办法]
我没说升级重启,我是说重启了再升级。
旧的即然还可以用,为什么不能在这次用完了以后,下次再升级?


引用:
Quote: 引用:

升级不能在开机启动后,钩子函数执行前才更新吗?
下载需要更新的程序,等到重启后判断有程序需要更新,则先执行更新程序,再挂载钩子。

升级重启 很不好啊

[解决办法]
引用:
Quote: 引用:


全局消息钩子会注入GUI进程,在该进程窗口有某些动作时注入,UnhookWindowsHookEx 后,也不是立即就自动释放,而是在被注入窗口有某些动作时才释放。
没有方法能使全局消息钩子注入的DLL能受你控制地被释放,但有一个优化方案,就是你UnhookWindowsHookEx后广播一个消息,这样就能让被注入的进程在未进行任何动作时“尽量地”感知全局钩子已卸载。
但这也不能保证。
而你的需求和这其实没有关系,删除不了,可以改名。你可以尝试:
if (!覆盖成功)
{
原文件 改名为 原文件.old;
更新文件到 原文件;
原文件.old 标记为重启删除;
}

如果只是想更新,根本没必要非把原来的删除。


谢谢,那你说的广播消息是怎么处理的呢,是遍历每个进程发消息?
发的又是什么消息 才能被被注入的进程感知呢?

楼上各楼都答非所问,你的需求不过是更新,何必纠结卸载呢。
况且卸载没有优雅的方式做到,因为你控制不了别的进程的行为,在你的模块注入进别的进程后,发起钩子的进程也没办法控制被注入的其他进程。
有一些做法能“尽量”地做到,如你的DLL里创建线程检查发起钩子的进程是否退出了,如果退出就主动卸载自己,楼上貌似有人说了 FreeLibraryAndExitThread,但这根本没必要,也不是好的风格。
还有方法就是我说的广播消息了 SendMessage(WM_BROADCAST, WM_USER, 0, 0); 就行。因为那些全局钩子的触发机制大多是窗口消息,在你卸载全局钩子后,如果别的进程能再次触发窗口消息就有机会卸载你的DLL了,但这会牵涉到别的问题,如 SendMessage 阻塞,需要用 SendMessageTimeout,或者别的进程已经在处理别的消息,并且长期没返回,或其他的原因导致没收到你的广播消息,都会导致没法成功“通知”到被你注入的进程。
所以不要纠结了,不要偏离你的需求,这没有意义,只想更新的话把原DLL改个名就行。
结贴吧。
[解决办法]
AdjustTokenPrivileges
VirtualProtectEx
WriteProcessMemory

读书人网 >VC/MFC

热点推荐