DLL注入实验:
MSDN已经说明了DllMain可以省略,但这里不能省略。
原因很简单,查看DllMain定义的形参就知道是什么回事啦。
当应用程序加载DLL时会发送消息到DllMain函数的第二个参数。
利用这个特性,加载的DLL就可以立刻响应里面的功能函数啦!!
下面是实验的代码:
view plain copy to clipboard print ?
- #include <windows.h>
-
- DWORD WINAPI ThreadProc(PVOID lp);
- BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
- {
- switch(ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- MessageBox(NULL,"DLL_PROCESS_ATTACH","ASDF",0);
- CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
- break;
- case DLL_THREAD_ATTACH:
- MessageBox(NULL,"DLL_THREAD_ATTACH","ASDF",0);
- break;
- case DLL_THREAD_DETACH:
- MessageBox(NULL,"DLL_THREAD_DETACH","ASDF",0);
- break;
- case DLL_PROCESS_DETACH:
- MessageBox(NULL,"DLL_PROCESS_DETACH","ASDF",0);
- break;
- }
- return TRUE;
- }
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- MessageBox(NULL,"ThreadProc","ASDF",0);
- return 0;
- }
view plain copy to clipboard print ?
- void CInTOprocessDlg::OnBtnIn()
- {
- UpdateData(TRUE);
- HANDLE hRemoteProcess;
- hRemoteProcess=OpenProcess(
- PROCESS_CREATE_THREAD |
- PROCESS_VM_OPERATION |
- PROCESS_VM_WRITE ,
- FALSE,m_pid);
- if(!hRemoteProcess)
- {
- MessageBox("can't not open the process");
- }
- char *pszLibFileName="my.dll";
- int cb = (1 + lstrlenA(pszLibFileName)) * sizeof(char);
-
- char *pszLibFileRemote=(char *)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
-
- if(!pszLibFileRemote)
- {
- MessageBox("VirtualAllocEx error!");
- }
-
- if(!WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(PVOID)pszLibFileName,cb,NULL))
- {
- VirtualFreeEx(pszLibFileRemote);
- MessageBox("WriteProcessMemory error!");
- }
-
- HANDLE hThread=CreateRemoteThread( hRemoteProcess, NULL, 0,(PTHREAD_START_ROUTINE)LoadLibraryA, pszLibFileRemote, 0, NULL)
- if(!hThread)
- {
- VirtualFreeEx(pszLibFileRemote);
- CloseHandle(hThread);
- MessageBox("CreateRemoteThread error!");
- }
- VirtualFreeEx(pszLibFileRemote);
- CloseHandle(hThread);
- }
今天用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 plain copy to clipboard print ?
-
- DWORD GetProcessPID(char *ProcessName)
- {
- CString Name;
- Name.Format("%s",ProcessName);
-
- HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
- PROCESSENTRY32 lppe;
- lppe.dwSize=sizeof(PROCESSENTRY32);
-
- Process32First(hSnapshot,&lppe);
- if(Name=="")
- {
- CloseHandle(hSnapshot);
- return 1;
- }
- do
- {
- TRACE(lppe.szExeFile);
- if(Name==lppe.szExeFile)
- {
- CloseHandle(hSnapshot);
- return lppe.th32ProcessID;
- }
- }
- while(Process32Next(hSnapshot,&lppe));
- if(Name!=lppe.szExeFile)
- {
- TRACE("_______________");
- TRACE(lppe.szExeFile);
- TRACE("_______________");
- CloseHandle(hSnapshot);
- return 2;
- }
- return 0;
-
- }
view plain copy to clipboard print ?
-
- char UnLoadDll(char *ProcessName,char *DllPath)
- {
-
- DWORD ProcessPID=GetProcessPID(ProcessName);
- if(ProcessPID==1)
- {
- return 1;
- }
- if(ProcessPID==2)
- {
- TRACE("_______________");
- TRACE(ProcessName);
- TRACE("_______________");
- return 2;
- }
-
-
- HANDLE hProcess;
- hProcess=OpenProcess(
- PROCESS_CREATE_THREAD |
- PROCESS_VM_OPERATION |
- PROCESS_VM_WRITE ,
- FALSE,ProcessPID);
- if(!hProcess)
- {
- TRACE("打开目标进程失败");
- CloseHandle(hProcess);
- return 3;
- }
-
- int allocSize=(strlen(DllPath)+1)*sizeof(char);
-
- char *pLibFileName=(char*)VirtualAllocEx(hProcess,NULL,allocSize,MEM_COMMIT,PAGE_READWRITE);
-
- if(!pLibFileName)
- {
- TRACE("申请目标进程内存失败");
- CloseHandle(hProcess);
- return 4;
- }
- if(!WriteProcessMemory(hProcess,pLibFileName,(PVOID)DllPath, allocSize, NULL))
- {
- TRACE("写目标进程内存失败");
- VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);
- CloseHandle(hProcess);
- return 5;
- }
-
- while(1)
- {
-
- HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,(PTHREAD_START_ROUTINE)GetModuleHandle,pLibFileName,0,NULL);
- if(!hThread)
- {
- TRACE("创建目标线程运行GetModuleHandle失败");
- VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return 6;
- }
-
- WaitForSingleObject(hThread,INFINITE);
- DWORD hDll;
- GetExitCodeThread(hThread,&hDll);
- if(!hDll)
- {
- TRACE("卸载DLL成功");
- VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return 7;
- }
- CloseHandle(hThread);
- hThread=NULL;
-
-
-
- hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)FreeLibrary,(LPVOID)hDll,0,NULL);
- if(!hThread)
- {
- TRACE("创建远程线程运行FreeLibrary失败");
- VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return 8;
- }
- WaitForSingleObject(hThread,INFINITE);
-
- DWORD FreeLibInfo;
- GetExitCodeThread(hThread,&FreeLibInfo);
- if(!FreeLibInfo)
- {
- TRACE("FreeLibrary失败");
- VirtualFreeEx(hProcess,pLibFileName,allocSize,MEM_RELEASE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- return 9;
- }
- }
- return 0;
- }