解决DLLMain中创建对话框的问题
编程语言
2020-01-17 16:01:33
阅读次数: 0
做了一个外挂,要远程注入DLL,在目标进程中创建一个对话框,并下钩子,使得按指定按键时,可以显示或者隐藏该对话框。。试验了n久,终于搞定了。
关于注入的部分我就不谈了,貌似大家都知道的事。 关键是在DllMain中,很多人说DllMain中尽量不要创建什么东西,MSDN上也这样说的。反复看了《Windows内核编程》,发现并不完全一点也不能创建,只要运用合理,是可以创建一些东西的。 调用DllMain会有4中情况,当Dll第一次被装入某个进程时,会调用,DLL_PROCESS_ATTACH,当DLL从进程中被卸载时,会调用DLL_PROCESS_DEATCH,当DLL所在进程创建一个线程时,会调用,DLL_THREAD_ATTACH,当撤销一个线程时,会调用,DLL_THREAD_DEATCH,当然,如果创建一个线程之后DLL才被载入的,那么这个DLL不会收到这个线程的DLL_THREAD_DEATCH。DllMain是由引发上述事件的线程调用的,就是说,当你创建一个线程,这个线程会先去挨个调用每个已加载的DLL模块的DllMain函数,DllMain返回之后,该线程才运行自己的代码。
因此,一些会引起阻塞的代码是不能在DllMain中用的,比如下面的代码:
DllMain(......) { switch(....) { case DLL_PROCESS_ATTACH: hThread = CreateThread(.....); WaitForSingleObject(hThread); return TRUE; ....................
这个DllMain永远不会返回。因为,创建一个线程又会引发DLL_THREAD_ATTACH,那么,新创建的线程会调用DllMain,而DllMain却在等待这个线程结束。。。。 当你发现了DisableThreadCalls这个函数,你会觉得在创建线程之前调用这个函数也许会解决这个问题,但事实上还是不行,不知道为什么。
知道了这点,那么创建对话框就容易多了。 case DLL_PROCESS_ATTACH: DialogBox(......); 上面的代码是不可以的。因为DialogBox创建一个模态对话框,当前线程会转去执行Dialog的消息循环(调用DiaolgProc),所以,在对话框结束之前,DllMain不会返回。而调用LoadLibrary函数的线程会处于等待,同时由于Dll没有被完成加载,Dialog中的一些资源也不能被使用,很有可能创建Dialog失败。
所以,我改成了这样: case DLL_PROCESS_ATTACH: hThread = CreateThread(....BeginCreateDialog....) ................. case DLL_PROCESS_DEATCH: EndDialog(...); WaitForSingleObject(hThread); ............. DWORD WINAPI BeginCreateDialog(LPVOID lParam) { DialogBox(...........); MessageBox(_T("DialogEnd.").........); ......... 这样,创建对话框可以了。但新的问题又来了。就是BeginCreateDialog函数中的MessageBox代码永远不会被执行。 具体原因我也没弄清楚,我想大概是调用DllMain的DLL_PROCESS_DEATCH时,进程已经关闭了。于是,我在对话框的OnInitDialog中又添加了一个钩子,在目标进程收到WM_CLOSE或者WM_QUIT时,先结束对话框。
到此,就可以实现本文一开始所说的功能了。有人说不用创建线程,使用CreateDialog不就行了?我试过,不行,具体原因俺也不知道。
本文只为了抛砖引玉,也许俺的方法和代码在高人面前显得那么苍白。。呵呵,请不要笑,如果您知道更好的方法,请跟贴说说。。
谢谢! |
分享:
发布了1 篇原创文章 ·
获赞 0 ·
访问量 303
转载自blog.csdn.net/c2unix/article/details/104020526