卸载DLL模块

卸载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;
}

文章链接: https://www.mfisp.com/15128.html

文章标题:卸载DLL模块

文章版权:梦飞科技所发布的内容,部分为原创文章,转载请注明来源,网络转载文章如有侵权请联系我们!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
建站教程投稿分享

递归遍历文件

2022-12-30 0:02:16

建站教程投稿分享

16进制字符串如何转化为数字

2022-12-30 0:06:25

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索

梦飞科技 - 最新云主机促销服务器租用优惠