小弟利用远程线程注入DLL,DLL内创建新的线程,新的线程内创建了一个窗口,有消息循环并响应WM_TIMER消息,代码如下:
case WM_TIMER:
Nwnd = FindWindow("D3D Window", "Target");
if(Nwnd == NULL )
{ //停止投递WM_TIMER消息
::KillTimer(hwnd,1);
                        dwHandle = GetModuleHandle(NULL);
 

// 使目标进程调用FreeLibrary,卸载DLL
hModule=GetModuleHandle("kernel32.dll");
                   pFunc  = GetProcAddress(hModule, "FreeLibrary");
hThread = CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID );
if(hThread == NULL)
MessageBox( NULL, _T("返回值有错误"), _T("信息"), MB_ICONINFORMATION );
// 等待FreeLibrary卸载完毕
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread ); }
如果没有发现Target窗口就撤消一个已经安装的定时器1并创建一个线程用于释放自身DLL.
测试DLL运行后发现不能释放自身DLL,系统也没有提示什么错误,我感到摸不着头脑,希望大牛们给个建议怎么做可以让DLL内释放自身DLL,帮忙啊,我实在想不出方法,深感自己知识不够深入,希望大牛们不要吝惜给建议和批评.

解决方案 »

  1.   

    这种做法不能释放自身,原因说来话长,就不提了。
    对于远程线程,可以在DllMain最后return FALSE,这样会自动卸载。
      

  2.   

    首先dwHandle = GetModuleHandle(NULL)不是获取DLL的句柄,
    而是GetModuleHandle("dll名字"),
    最好直接用全局变量将DllMain的第一个参数(DLL的句柄)保存起来
    既然是卸载了,后面就不要执行DLL里的代码了DLL创建的窗口一直运行在线程中吧
    如果没有发现Target窗口就KillTimer(hwnd,1)
    然后发消息或之类操作去关闭DLL创建的窗口
    在执行到线程的return前
    __asm
    {
    mov eax, offset lparam
    mov eax, [eax - 4]
    push hInstDLL
    push eax
    push FreeLibrary
    retn
    }
    一种思路而已,没测试过,看情况修改MS是外挂,没什么好隐瞒的,好好学,不要干坏事
      

  3.   

    谢谢stjay给详细的提示
    发消息关闭窗口后代码可以执行到线程的return处,我把DLL的句柄保存了下来后,在return前把汇编代码复制上后提示label 'lparam' was undefined,请这位大牛给看下.
      

  4.   

    to:cnzdgs五星大牛
    怎么做可以释放DLL自身?
      

  5.   

    2#不知道是从哪里复制来的代码,搞得新手都不懂了。LZ那样是不能释放自身的,因为自身还在一个PE的内存空间中,怎么可能自己把自己干掉?那部分内存不是由dll管理,而是由进程管理的,应该由进程来Free的。
    用FreeLibraryAndExitThread这个函数
      

  6.   

    怎么可能,你要获得创建时的句柄再利用这个句柄来释放地,胡乱获得一个句柄来释放只要句柄不是无效当然能通过,但根本就没有释放宿主程序拥有的DLL句柄.
      

  7.   

    to:biweilun大牛
    恩,我查了下FreeLibraryAndExitThread这个函数的用法,可以结束自身的DLL,我试下下...你先不要走开...
      

  8.   

    to:biweilun大牛
    果然简单实用