# 卸载DLL模块

> 来源：梦飞idc云平台 | 原文：https://www.mfisp.com/15128.html | 发布：2022-12-30 | 更新：2022-12-30 | 分类：建站教程、投稿分享

卸载dll模块可以用于杀毒程序中

 

// 程序功能：结束进程中的一个模块。  
// 程序日期：2006.10.8   
// 程序说明：这个程序写于2003年，主要针对一些木马注入程序。以往结束远程注入木马(dll)时需要   
// 结束进程，这个程序不用结束进程而直接结束单个DLL。结束后会出现一些问题，某些情况  
// 下会导致整个进程异常，这是很正常的，例如结束了一个进程需要调用的DLL；或者结束后DLL  
// 又被主进程加载，例如mfc42.dll。  
// 程序原理：根据DLL地址范围找到进程用的DLL线程，结束这个线程即DLL。  
// 调试参数：explorer.exe secur32.dll  
#include <windows.h>  
#include <stdio.h>  
#include <TlHelp32.h>  
#pragma warning(disable:4996)  
#define OS_SDK 0  
#define BUFSIZE 80  
typedef enum _THREAD_INFORMATION_CLASS {  
 ThreadBasicInformation,  
 ThreadTimes,  
 ThreadPriority,  
 ThreadBasePriority,  
 ThreadAffinityMask,  
 ThreadImpersonationToken,  
 ThreadDescriptorTableEntry,  
 ThreadEnableAlignmentFaultFixup,  
 ThreadEventPair,  
 ThreadQuerySetWin32StartAddress,  
 ThreadZeroTlsCell,  
 ThreadPerformanceCount,  
 ThreadAmILastThread,  
 ThreadIdealProcessor,  
 ThreadPriorityBoost,  
 ThreadSetTlsArrayAddress,  
 ThreadIsIoPending,  
 ThreadHideFromDebugger  
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;  
typedef DWORD (CALLBACK* NTQUERYINFORMATIONTHREAD)(HANDLE,DWORD,PVOID,DWORD,PDWORD);  
int GetVersionInfo()  
{  
 OSVERSIONINFOEX osvi;  
 BOOL bOsVersionInfoEx;  
 // Try calling GetVersionEx using the OSVERSIONINFOEX structure.  
 // If that fails, try using the OSVERSIONINFO structure.  
 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));  
 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);  
 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )  
 {  
 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);  
 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )   
 return FALSE;  
 }  
 switch (osvi.dwPlatformId)  
 {  
 // Test for the Windows NT product family.  
 case VER_PLATFORM_WIN32_NT:  
 // Test for the specific product family.  
 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )  
 printf ("Microsoft Windows .NET Server 2003 family, ");  
 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )  
 printf ("Microsoft Windows XP ");  
 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )  
 printf ("Microsoft Windows 2000 ");  
 if ( osvi.dwMajorVersion <= 4 )  
 printf("Microsoft Windows NT ");  
 // Test for specific product on Windows NT 4.0 SP6 and later.  
 if( bOsVersionInfoEx )  
 {  
#if OS_SDK   
 // Test for the workstation type.  
 if ( osvi.wProductType == VER_NT_WORKSTATION )  
 {  
 if( osvi.dwMajorVersion == 4 )  
 printf ( "Workstation 4.0 " );  
 else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )  
 printf ( "Home Edition " );  
 else  
 printf ( "Professional " );  
 }  
 // Test for the server type.  
 else if ( osvi.wProductType == VER_NT_SERVER )  
 {  
 if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )  
 {  
 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
 printf ( "Datacenter Edition " );  
 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
 printf ( "Enterprise Edition " );  
 else if ( osvi.wSuiteMask == VER_SUITE_BLADE )  
 printf ( "Web Edition " );  
 else  
 printf ( "Standard Edition " );  
 }  
 else if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )  
 {  
 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )  
 printf ( "Datacenter Server " );  
 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
 printf ( "Advanced Server " );  
 else  
 printf ( "Server " );  
 }  
 else // Windows NT 4.0   
 {  
 if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )  
 printf ("Server 4.0, Enterprise Edition " );  
 else  
 printf ( "Server 4.0 " );  
 }  
 }  
#endif  
 }  
 else // Test for specific product on Windows NT 4.0 SP5 and earlier  
 {  
 HKEY hKey;  
 char szProductType[BUFSIZE];  
 DWORD dwBufLen=BUFSIZE;  
 LONG lRet;  
 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
 "SYSTEM//CurrentControlSet//Control//ProductOptions",  
 0, KEY_QUERY_VALUE, &hKey );  
 if( lRet != ERROR_SUCCESS )  
 return FALSE;  
 lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,  
 (LPBYTE) szProductType, &dwBufLen);  
 if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )  
 return FALSE;  
 RegCloseKey( hKey );  
 if ( lstrcmpi( "WINNT", szProductType) == 0 )  
 printf( "Workstation " );  
 if ( lstrcmpi( "LANMANNT", szProductType) == 0 )  
 printf( "Server " );  
 if ( lstrcmpi( "SERVERNT", szProductType) == 0 )  
 printf( "Advanced Server " );  
 printf( "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion );  
 }  
 // Display service pack (if any) and build number.  
 if( osvi.dwMajorVersion == 4 &&   
 lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 )  
 {  
 HKEY hKey;  
 LONG lRet;  
 // Test for SP6 versus SP6a.  
 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,  
 "SOFTWARE//Microsoft//Windows NT//CurrentVersion//Hotfix//Q246009",  
 0, KEY_QUERY_VALUE, &hKey );  
 if( lRet == ERROR_SUCCESS )  
 printf( "Service Pack 6a (Build %d)/n", osvi.dwBuildNumber & 0xFFFF );   
 else // Windows NT 4.0 prior to SP6a  
 {  
 printf( "%s (Build %d)/n",  
 osvi.szCSDVersion,  
 osvi.dwBuildNumber & 0xFFFF);  
 }  
 RegCloseKey( hKey );  
 }  
 else // Windows NT 3.51 and earlier or Windows 2000 and later  
 {  
 printf( "%s (Build %d)/n",  
 osvi.szCSDVersion,  
 osvi.dwBuildNumber & 0xFFFF);  
 }

 

break;  
 // Test for the Windows 95 product family.  
 case VER_PLATFORM_WIN32_WINDOWS:  
 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)  
 {  
 printf ("Microsoft Windows 95 ");  
 if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )  
 printf("OSR2 " );  
 return 0;  
 }  
 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)  
 {  
 printf ("Microsoft Windows 98 ");  
 if ( osvi.szCSDVersion[1] == 'A' )  
 printf("SE " );  
 return 0;  
 }  
 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)  
 {  
 printf ("Microsoft Windows Millennium Edition/n");  
 return 0;  
 }   
 break;  
 case VER_PLATFORM_WIN32s:  
 printf ("Microsoft Win32s/n");  
 return 0;  
 break;  
 }  
 return TRUE;   
}  
// 函数功能：设置权限  
BOOL SetPrivilege(LPCTSTR Privilege, BOOL bEnablePrivilege)  
{  
 HANDLE hToken, h;   
 TOKEN_PRIVILEGES tkp;  
 // 获得令牌  
 typedef VOID (WINAPI *MYPROC1)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);   
 MYPROC1 ProcAdd1 = (MYPROC1)GetProcAddress(GetModuleHandle(TEXT("Advapi32")), "OpenProcessToken");  
 if (ProcAdd1 == NULL)  
 return FALSE;  
 h = GetCurrentProcess();  
 if (h == NULL)  
 return FALSE;  
 ProcAdd1(h, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);  
 // 开机关机权限  
 typedef VOID (WINAPI *MYPROC2)( LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);   
 MYPROC2 ProcAdd2 = (MYPROC2)GetProcAddress(GetModuleHandle(TEXT("Advapi32")), "LookupPrivilegeValueA");  
 if (ProcAdd2 == NULL)  
 return FALSE;  
 (ProcAdd2)(NULL, Privilege, &tkp.Privileges[0].Luid);  
 // 第一次  
 tkp.PrivilegeCount = 1; // one privilege to set   
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
 typedef VOID (WINAPI *MYPROC3)( HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);   
 MYPROC3 ProcAdd3 = (MYPROC3)GetProcAddress(GetModuleHandle(TEXT("Advapi32")), "AdjustTokenPrivileges");  
 if (ProcAdd3 == NULL)  
 return FALSE;  
 (ProcAdd3)(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);  
 // 第二次  
 tkp.PrivilegeCount = 1; // one privilege to set   
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
 if(bEnablePrivilege)   
 tkp.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);  
 else   
 tkp.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tkp.Privileges[0].Attributes);  
 (ProcAdd3)(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

 

return TRUE;  
}  
// 函数功能：获取关机/重启权限  
BOOL SetPrivilege_ShutDown()  
{  
 return SetPrivilege(SE_SHUTDOWN_NAME,true);  
}  
// 函数功能：获取关闭其它进程权限  
int SetPrivilege_Debug()   
{  
 return SetPrivilege(SE_DEBUG_NAME,true);  
}  
// 函数功能：获取文件的大小  
// 函数返回：文件大小  
DWORD GetFileSize(char *pFileName)  
{  
 FILE *pFile;  
 DWORD dwPos;  
 DWORD dwFileSize;  
 if( (pFile = fopen(pFileName, "rb" )) == NULL )  
 {  
 printf( "The file 'data' was not opened/n" );  
 return 0;  
 }  
 dwPos = ftell(pFile);  
 fseek(pFile, 0, SEEK_END);  
 dwFileSize = ftell(pFile);  
 fseek(pFile, dwPos, SEEK_SET);  
 fclose(pFile);  
 return dwFileSize;  
}  
// 函数功能：杀进程中的模块  
typedef HANDLE (WINAPI *MYPROC1)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);  
int KillModule(char *strPName, char *strMName)  
{  
 char strDllName[MAX_PATH];  
 HANDLE hProcess, hThread;  
 DWORD dwStartAddr = 0;  
 DWORD dwRetLen = 0;  
 DWORD dwDllSize = 0;  
 PWSTR pszLibFileRemote = NULL;  
 int nKilled = 0;  
 BOOL fOk, fOK1;  
 HANDLE hmeSnapshot;  
 BOOL fME;  
 char *pdest;  
 HMODULE hNtdll;  
 int cch;  
 int cb;  
 int nDllKillNum;  
 MYPROC1 ProcAdd1;  
 PTHREAD_START_ROUTINE pfnThreadRtn;  
 NTQUERYINFORMATIONTHREAD NtQueryInformationThread;  
   
 HANDLE hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  
 PROCESSENTRY32 pe = { sizeof(pe) };  
 MODULEENTRY32 me = { sizeof(me) };  
 // 遍历所有进程  
 fOk = Process32First(hthSnapshot, &pe);  
 for (; fOk; fOk = Process32Next(hthSnapshot, &pe))   
 {  
 // 找到远程进程  
 if (stricmp(pe.szExeFile, strPName) == 0)  
 {  
 // 遍历模块  
 hmeSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);  
 fME = Module32First(hmeSnapshot, &me);  
 for (; fME; fME = Module32Next(hmeSnapshot, &me))   
 {  
 strcpy(strDllName, me.szExePath);  
 pdest = strrchr(strDllName, '//');  
 strcpy(strDllName, ++pdest);  
 // 找到远程进程中的模块， 杀之，3个步骤  
 if (stricmp(strDllName, strMName) == 0)  
 {  
 __try   
 {  
 // 1.遍历模块中的线程，如果有结束  
 dwDllSize = GetFileSize(me.szExePath);  
 hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, me.th32ProcessID);  
 if (hthSnapshot == NULL) __leave;  
 THREADENTRY32 te = { sizeof(te) };  
 fOK1 = Thread32First(hthSnapshot, &te);  
 // 遍历线程  
 for (; fOK1; fOK1 = Thread32Next(hthSnapshot, &te))   
 {  
 if (te.th32OwnerProcessID == pe.th32ProcessID)   
 {  
 __try   
 {  
 // 得到线程句柄  
 ProcAdd1 = (MYPROC1)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "OpenThread");  
 if (ProcAdd1 == NULL)  
 return FALSE;  
 hThread = (ProcAdd1(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID));  
 if (hThread == NULL) __leave;  
 // 找到ntdll.dll中函数NtQueryInformationThread地址  
 hNtdll = LoadLibrary( "ntdll.dll" );   
 if (!hNtdll) return 0;  
 NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD)GetProcAddress(hNtdll, "NtQueryInformationThread");  
 // 获取线程入口地址  
 NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &dwStartAddr, 0x4, &dwRetLen);  
 if (dwStartAddr != NULL)  
 {  
 // 判断线程入口地址是否在模块中  
 if ((dwStartAddr - (DWORD)me.hModule) <= dwDllSize)  
 {  
 // 结束线程  
 TerminateThread(hThread, 0);  
 CloseHandle(hThread);  
 }  
 }  
 }  
 // 释放资源  
 __except(EXCEPTION_EXECUTE_HANDLER)   
 {   
 return 0;  
 }  
 }   
 } // for  
 // 2.释放DLL  
 // 获取远程进程中的DLL句柄  
 hProcess = OpenProcess(  
 PROCESS_QUERY_INFORMATION | // Required by Alpha  
 PROCESS_CREATE_THREAD | // For CreateRemoteThread  
 PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx  
 PROCESS_VM_WRITE, // For WriteProcessMemory  
 FALSE, me.th32ProcessID);  
 if (hProcess == NULL) __leave;  
 // 计算DLL名称需要的字节数  
 cch = 1 + strlen(me.szExePath);  
 cb = cch * sizeof(CHAR);  
 // 分配远程进程路径名空间  
 pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);  
 if (pszLibFileRemote == NULL) __leave;  
 // 考贝DLL路径名到远程进程空间  
 if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)me.szExePath, cb, NULL)) __leave;  
 // 得到GetModuleHandle在Kernel32.dll中的地址  
 pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");  
 if (pfnThreadRtn == NULL) __leave;  
 // 创建远程进程，调用GetModuleHandle(DLLPathname)  
 nDllKillNum = (me.GlblcntUsage > me.ProccntUsage) ? me.GlblcntUsage : me.ProccntUsage;   
 if (nDllKillNum == 65535)  
 nDllKillNum = 3;  
 for (int i = 0; i < nDllKillNum; i++)  
 {  
 hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, me.hModule, 0, NULL);  
 if (hThread == NULL) __leave;  
 }  
 // 3.删除DLL  
 //DeleteFile(me.szExePath);  
 CloseHandle(hProcess);  
 CloseHandle(hThread);  
 printf("Killed !!!/n");  
 nKilled = 1;  
 }  
 __finally  
 {  
 if (hthSnapshot != NULL)   
 CloseHandle(hthSnapshot);  
 }  
 }// if  
 } // for  
 }  
 }// for  
 if (nKilled == 0)  
 printf("Sorry, No found!/n");  
   
 return 0;  
}  
int main(int argc, char **argv)  
{  
 printf("KillModule V1.0(2006). Welcome to myblog: www.blog.163.com/lanhai96");  
 if (argc < 3)  
 {  
 printf("Parameter error./n");  
 return 0;  
 }  
 // 看版本号  
 if (!GetVersionInfo())  
 {  
 printf("Don't run at this OS./n");  
 return 0;  
 }  
 // 获得权限  
 SetPrivilege_Debug();  
 // 结束模块  
 KillModule(argv[1], argv[2]);  
 return 0;  
}

---
本页由 梦飞idc云平台（https://www.mfisp.com）提供。站点导航见 https://www.mfisp.com/llms.txt
