DLL注入,卸载

来源:互联网 发布:本地yum配置 编辑:程序博客网 时间:2024/06/07 02:10

 

DLL注入实验:

 

 

MSDN已经说明了DllMain可以省略,但这里不能省略。
原因很简单,查看DllMain定义的形参就知道是什么回事啦。
当应用程序加载DLL时会发送消息到DllMain函数的第二个参数。
利用这个特性,加载的DLL就可以立刻响应里面的功能函数啦!!

下面是实验的代码:

 

view plaincopy to clipboardprint?
  1. #include <windows.h>  
  2.   
  3. DWORD WINAPI ThreadProc(PVOID lp);  
  4. BOOL APIENTRY DllMain(HANDLE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)  
  5. {  
  6.     switch(ul_reason_for_call)  
  7.     {  
  8.     case DLL_PROCESS_ATTACH:  
  9.         MessageBox(NULL,"DLL_PROCESS_ATTACH","ASDF",0);  
  10.         CreateThread(NULL,0,ThreadProc,NULL,0,NULL);  
  11.         break;  
  12.     case DLL_THREAD_ATTACH:  
  13.         MessageBox(NULL,"DLL_THREAD_ATTACH","ASDF",0);  
  14.         break;  
  15.     case DLL_THREAD_DETACH:  
  16.         MessageBox(NULL,"DLL_THREAD_DETACH","ASDF",0);  
  17.         break;  
  18.     case DLL_PROCESS_DETACH:  
  19.         MessageBox(NULL,"DLL_PROCESS_DETACH","ASDF",0);  
  20.         break;  
  21.     }  
  22.     return TRUE;  
  23. }  
  24. DWORD WINAPI ThreadProc(PVOID lp)  
  25. {  
  26.     MessageBox(NULL,"ThreadProc","ASDF",0);  
  27.     return 0;  
  28. }  
 

 

 

view plaincopy to clipboardprint?
  1. void CInTOprocessDlg::OnBtnIn()   
  2. {  
  3.     UpdateData(TRUE);  
  4.     HANDLE hRemoteProcess;  
  5.     hRemoteProcess=OpenProcess(  
  6.                         PROCESS_CREATE_THREAD   |  
  7.                         PROCESS_VM_OPERATION    |  
  8.                         PROCESS_VM_WRITE    ,  
  9.                         FALSE,m_pid);  
  10.     if(!hRemoteProcess)  
  11.     {  
  12.         MessageBox("can't not open the process");  
  13.     }  
  14.     char *pszLibFileName="my.dll";  
  15.     int cb = (1 + lstrlenA(pszLibFileName)) * sizeof(char);   
  16.     //申请内存存放以DLL文件路径名  
  17.     char *pszLibFileRemote=(char *)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);   
  18.     //写DLL文件路径名到远程进程  
  19.     if(!pszLibFileRemote)  
  20.     {  
  21.         MessageBox("VirtualAllocEx error!");  
  22.     }  
  23.           
  24.     if(!WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(PVOID)pszLibFileName,cb,NULL))  
  25.     {  
  26.                 VirtualFreeEx(pszLibFileRemote);  
  27.         MessageBox("WriteProcessMemory error!");          
  28.     }  
  29.     //创建远程线程  
  30.          HANDLE hThread=CreateRemoteThread( hRemoteProcess, NULL, 0,(PTHREAD_START_ROUTINE)LoadLibraryA, pszLibFileRemote, 0, NULL)  
  31.     if(!hThread)  
  32.     {  
  33.                 VirtualFreeEx(pszLibFileRemote);  
  34.                 CloseHandle(hThread);  
  35.         MessageBox("CreateRemoteThread error!");  
  36.     }  
  37.         VirtualFreeEx(pszLibFileRemote);  
  38.         CloseHandle(hThread);  
  39. }  

 

今天用IceSword研究DLL的注入时遇到一个奇怪问题。

当我调用LoadLibrary时,不知道什么原因(后来发现,可能是手痒了,多按了几下),用FreeLibrary,都释放不了DLL。

后来经过我多次试验,发现以下规律:

当我多次调用LoadLibrary时,然后再调用FreeLibrary,最后用IceSword查看了目标进程的模块,发现注入的DLL未Unload!!!

但多次调用FreeLibrary时,DLL能Unload!!最后试验得出,LoadLibrary 与 FreeLibrary调用的次数要相等,才能Unload。

Oh,my god!!! 虽然解决了问题,但不知道根本原因啊!不甘心!为了查出真凶,不得不去查了一下全是英文的MSND。

后来去查了MSDN,发现

以下是MSDN的说明:

 

The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file.

The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.

 

简要的说就是每调用一次LoadLibrary内部计数会加1,每调用一次FreeLibrary内部计数减1,当内部计数为0时释放DLL。

 

卸载:

 

 

知道了注入的原理,对于卸载就很容易学会了!

对于DLL注入型病毒、木马、可以很自己编写一个专杀软件!

下面的写法对于我来说比较新鲜,用的是返回错误代码的写法,有点API的味道!

 

view plaincopy to clipboardprint?
  1. //获取进程PID  
  2. DWORD GetProcessPID(char *ProcessName)  
  3. {  
  4.     CString Name;  
  5.     Name.Format("%s",ProcessName);  
  6.     //快照进程信息  
  7.     HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);  
  8.     PROCESSENTRY32 lppe;  
  9.     lppe.dwSize=sizeof(PROCESSENTRY32);  
  10.     //获得第一个进程的信息  
  11.     Process32First(hSnapshot,&lppe);  
  12.     if(Name=="")  
  13.     {  
  14.         CloseHandle(hSnapshot);  
  15.         return 1;  
  16.     }  
  17.     do  
  18.     {  
  19.         TRACE(lppe.szExeFile);  
  20.         if(Name==lppe.szExeFile)  
  21.         {  
  22.             CloseHandle(hSnapshot);  
  23.             return lppe.th32ProcessID;  
  24.         }  
  25.     }  
  26.     while(Process32Next(hSnapshot,&lppe));  
  27.     if(Name!=lppe.szExeFile)  
  28.     {  
  29.         TRACE("_______________");  
  30.         TRACE(lppe.szExeFile);  
  31.         TRACE("_______________");  
  32.         CloseHandle(hSnapshot);  
  33.         return 2;  
  34.     }  
  35.     return 0;  
  36.   
  37. }  

 

 

view plaincopy to clipboardprint?
  1. //卸载DLL  
  2. char UnLoadDll(char *ProcessName,char *DllPath)  
  3. {  
  4.     //获取进程PID号  
  5.     DWORD   ProcessPID=GetProcessPID(ProcessName);  
  6.     if(ProcessPID==1)  
  7.     {  
  8.         return 1;  
  9.     }  
  10.     if(ProcessPID==2)  
  11.     {  
  12.         TRACE("_______________");  
  13.         TRACE(ProcessName);  
  14.         TRACE("_______________");  
  15.         return 2;  
  16.     }  
  17.   
  18.     //打开进程  
  19.     HANDLE hProcess;  
  20.     hProcess=OpenProcess(  
  21.                                 PROCESS_CREATE_THREAD   |  
  22.                                 PROCESS_VM_OPERATION    |  
  23.                                 PROCESS_VM_WRITE        ,  
  24.                                 FALSE,ProcessPID);  
  25.     if(!hProcess)  
  26.     {  
  27.         TRACE("打开目标进程失败");  
  28.         CloseHandle(hProcess);  
  29.         return 3;  
  30.     }  
  31.   
  32.     int allocSize=(strlen(DllPath)+1)*sizeof(char);   
  33.     //申请内存存放以DLL文件路径名  
  34.     char *pLibFileName=(char*)VirtualAllocEx(hProcess,NULL,allocSize,MEM_COMMIT,PAGE_READWRITE);   
  35.     //写DLL文件路径名到远程进程  
  36.     if(!pLibFileName)  
  37.     {  
  38.         TRACE("申请目标进程内存失败");  
  39.         CloseHandle(hProcess);  
  40.         return 4;  
  41.     }  
  42.     if(!WriteProcessMemory(hProcess,pLibFileName,(PVOID)DllPath, allocSize, NULL))  
  43.     {  
  44.         TRACE("写目标进程内存失败");  
  45.         VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);  
  46.         CloseHandle(hProcess);  
  47.         return 5;  
  48.     }  
  49.   
  50. while(1)  
  51. {  
  52.     //创建远程线程,GetModuleHandle获取刚刚注入的DLL的句柄  
  53.     HANDLE  hThread=CreateRemoteThread(hProcess,NULL,0,(PTHREAD_START_ROUTINE)GetModuleHandle,pLibFileName,0,NULL);  
  54.     if(!hThread)  
  55.     {  
  56.         TRACE("创建目标线程运行GetModuleHandle失败");  
  57.         VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);  
  58.         CloseHandle(hThread);  
  59.         CloseHandle(hProcess);  
  60.         return 6;  
  61.     }  
  62.   
  63.     WaitForSingleObject(hThread,INFINITE);  
  64.     DWORD hDll;  
  65.     GetExitCodeThread(hThread,&hDll);  
  66.     if(!hDll)  
  67.     {  
  68.         TRACE("卸载DLL成功");//卸载结束!!  
  69.         VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);  
  70.         CloseHandle(hThread);  
  71.         CloseHandle(hProcess);  
  72.         return 7;  
  73.     }  
  74.     CloseHandle(hThread);  
  75.     hThread=NULL;  
  76.   
  77.   
  78.     //创建远程线程,卸载远程DLL  
  79.     hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)FreeLibrary,(LPVOID)hDll,0,NULL);  
  80.     if(!hThread)  
  81.     {  
  82.         TRACE("创建远程线程运行FreeLibrary失败");  
  83.         VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);  
  84.         CloseHandle(hThread);  
  85.         CloseHandle(hProcess);  
  86.         return 8;  
  87.     }  
  88.     WaitForSingleObject(hThread,INFINITE);  
  89.   
  90.     DWORD FreeLibInfo;  
  91.     GetExitCodeThread(hThread,&FreeLibInfo);  
  92.     if(!FreeLibInfo)  
  93.     {  
  94.         TRACE("FreeLibrary失败");  
  95.         VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);  
  96.         CloseHandle(hThread);  
  97.         CloseHandle(hProcess);  
  98.         return 9;  
  99.     }  
  100. }  
  101. return 0;  
  102. }  

 

原创粉丝点击