Pārlūkot izejas kodu

卸载dll成功实现。

Jeff 6 gadi atpakaļ
vecāks
revīzija
1f0b44fefe

+ 33 - 7
source/hook/WeChats/Global.cpp

@@ -5,6 +5,8 @@
 #include <WinVer.h>		
 #pragma comment(lib,"version.lib")
 using namespace std;
+#include <psapi.h>
+#pragma comment(lib,"Psapi.lib")
 
 TCHAR g_szModulePath[MAX_PATH] = _T("");			// 软件目录;
 TCHAR g_szModuleFileName[MAX_PATH] = _T("");		// 软件名称;
@@ -177,15 +179,15 @@ vector<DWORD> FindAllProcess(LPCTSTR lpProName)
 	return vtPID;
 }
 
-MODULEENTRY32 FindModule(LPCTSTR lpModuleName, DWORD dwPID)
+HANDLE FindModule(LPCTSTR lpModuleName, DWORD dwPID)
 {
 	ASSERT(lpModuleName!=NULL);
 
 	DWORD dwMID = 0;
 	MODULEENTRY32 me32 = { 0 };
-	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
+	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, dwPID);
 	if (hSnapshot == NULL)
-		return me32;
+		return NULL;
 
 	me32.dwSize = sizeof(PROCESSENTRY32);
 	if (Module32First(hSnapshot, &me32))
@@ -199,7 +201,34 @@ MODULEENTRY32 FindModule(LPCTSTR lpModuleName, DWORD dwPID)
 	}
 	CloseHandle(hSnapshot);
 
-	return me32;
+	return me32.hModule;
+}
+
+HANDLE FindModuleEx(LPCTSTR lpModuleName, DWORD dwPid)
+{
+	HMODULE hMods[1024] = {0};
+	DWORD cbNeeded = 0;
+	TCHAR szModName[MAX_PATH];
+	BOOL Wow64Process;
+
+	HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPid);
+	IsWow64Process(hProcess, &Wow64Process); //判断是32位还是64位进程
+	if ( EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, Wow64Process?LIST_MODULES_32BIT:LIST_MODULES_64BIT) )
+	{
+		for (UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
+		{
+			GetModuleFileNameEx(hProcess, hMods[i], szModName, _countof(szModName));
+			if (_tcsicmp(lpModuleName, szModName) == 0)
+			{
+				CloseHandle(hProcess);
+				return hMods[i];
+			}
+		}
+	}
+
+	CloseHandle(hProcess);
+
+	return NULL;
 }
 
 // WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理;
@@ -233,13 +262,11 @@ BOOL GetDebugPriv()
 
 	if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
 	{
-		//ShowSystemErrorInfo(_T("升级包OpenProcessToken失败."),GetLastError());
 		return FALSE;
 	}
 
 	if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
 	{
-		//ShowSystemErrorInfo(_T("升级包LookupPrivilegeValue失败."),GetLastError());
 		CloseHandle(hToken);
 		return FALSE;
 	}
@@ -250,7 +277,6 @@ BOOL GetDebugPriv()
 
 	if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
 	{
-		//ShowSystemErrorInfo(_T("升级包AdjustTokenPrivileges失败."),GetLastError());
 		CloseHandle(hToken);
 		return FALSE;
 	}

+ 2 - 1
source/hook/WeChats/Global.h

@@ -34,7 +34,8 @@ extern BOOL g_bStdOut;
 extern int GetIniInfo(LPCTSTR lpIniDir = NULL, LPCTSTR lpIniName = NULL);
 extern DWORD FindProcess(LPCTSTR lpProName);
 extern vector<DWORD> FindAllProcess(LPCTSTR lpProName);
-extern MODULEENTRY32 FindModule(LPCTSTR lpModuleName, DWORD dwPID);
+extern HANDLE FindModule(LPCTSTR lpModuleName, DWORD dwPID);
+extern HANDLE FindModuleEx(LPCTSTR lpModuleName, DWORD dwPid);
 extern BOOL GetDebugPriv();
 
 extern BOOL GetFileVersion( IN HMODULE hModule, IN DWORD (&dwArray)[4]);

+ 65 - 47
source/hook/WeChats/Injection.cpp

@@ -2,11 +2,12 @@
 #include "Injection.h"
 
 CInjection::CInjection(DWORD dwPid, LPCTSTR lpDynamicLibraryPath)
-:m_dwInjectionPID(dwPid),
-m_hInjectionProcess(NULL),
-m_lpPathData(NULL),
+:m_dwInjectPID(dwPid),
+m_hInjectProcess(NULL),
+m_lpInjectData(NULL),
+m_lpEjectData(NULL),
 m_hInjectThread(NULL),
-m_hUnInjectThread(NULL),
+m_hEjectThread(NULL),
 m_dwPathLen(0)
 {
 	ASSERT(dwPid!=0);
@@ -14,74 +15,91 @@ m_dwPathLen(0)
 
 	memset(m_szDllPath, 0, sizeof(m_szDllPath));
 	_tcscpy_s(m_szDllPath,lpDynamicLibraryPath);
-	m_hInjectionProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwInjectionPID);
+	
+	m_hInjectProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwInjectPID);
+	//m_hInjectProcess = OpenProcess(PROCESS_CREATE_THREAD	| PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwInjectPID);
 }
 
 CInjection::~CInjection(void)
 {
-	FreeInjection();
+	// 卸载dll;
+	EjectDynamicLibrary();
+
+	// 释放所有资源;
+	if (m_hInjectThread)
+		CloseHandle(m_hInjectThread);
+	m_hInjectThread = NULL;
+
+	if (m_hEjectThread)
+		CloseHandle(m_hEjectThread);
+	m_hEjectThread = NULL;
+
+	if (m_lpInjectData)
+		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, m_dwPathLen, MEM_RELEASE);
+	m_lpInjectData = NULL;
+
+	if (m_lpEjectData)
+		VirtualFreeEx(m_hInjectProcess, m_lpEjectData, m_dwPathLen, MEM_RELEASE);
+	m_lpEjectData = NULL;
+
+	if (m_hInjectProcess)
+		CloseHandle(m_hInjectProcess);
+	m_hInjectProcess = NULL;
 }
 
-int CInjection::ProcessInjection()
+BOOL CInjection::InjectDynamicLibrary()
 {
-	ASSERT(m_hInjectionProcess!=NULL);
+	ASSERT(m_hInjectProcess!=NULL);
 
-	m_dwPathLen = _tcslen(m_szDllPath)*sizeof(TCHAR);
-	m_lpPathData = VirtualAllocEx(m_hInjectionProcess,NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
-	if (NULL == m_lpPathData)
-		return -1;
+	m_dwPathLen = _tcslen(m_szDllPath)*sizeof(TCHAR)+1;
+	m_lpInjectData = VirtualAllocEx(m_hInjectProcess,NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
+	if (NULL == m_lpInjectData)
+		return FALSE;
 
-	if (WriteProcessMemory(m_hInjectionProcess, m_lpPathData, m_szDllPath, m_dwPathLen, NULL) == 0)
+	if (WriteProcessMemory(m_hInjectProcess, m_lpInjectData, m_szDllPath, m_dwPathLen, NULL) == 0)
 	{
-		VirtualFreeEx(m_hInjectionProcess, m_lpPathData, m_dwPathLen, MEM_DECOMMIT);
-		return -1;
+		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, 0, MEM_RELEASE);
+		return FALSE;
 	}
 
 	HMODULE hk32 = GetModuleHandle(_T("kernel32.dll"));
 	// 注意:微信使用的是W版本;
 	LPVOID lpAddr = GetProcAddress(hk32,"LoadLibraryW");
 
-	m_hInjectThread = CreateRemoteThread(m_hInjectionProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, m_lpPathData, 0, NULL);
+	m_hInjectThread = CreateRemoteThread(m_hInjectProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, m_lpInjectData, 0, NULL);
 	if (NULL == m_hInjectThread)
-		return -1;
+	{
+		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, 0, MEM_RELEASE);
+		return FALSE;
+	}
 
-	return 0;
+	if (m_hInjectThread)
+		CloseHandle(m_hInjectThread);
+	m_hInjectThread = NULL;
+	
+	/* 注入成功后,不能释放内存否则微信会挂;
+	if (m_lpInjectData != NULL)
+		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, 0, MEM_RELEASE);
+	*/
+
+	return TRUE;
 }
 
-int CInjection::FreeInjection()
+BOOL CInjection::EjectDynamicLibrary()
 {
-	ASSERT(m_hInjectionProcess!=NULL);
-
-	TString str = m_szDllPath;
-	int nIndex = str.find_last_of(_T('\\'));
-	if (nIndex != TString::npos)
-		str = str.substr(nIndex+1);
-
-	MODULEENTRY32 me32 = FindModule(str.c_str(), m_dwInjectionPID);
-	if (me32.hModule == NULL )
-	{
-		MessageBox(NULL, _T("xxxxx"), _T("dfdf"), MB_OK);
+	if(m_hInjectProcess==NULL)
 		return -1;
-	}
-
-	LPVOID lpAddr = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibrary");//FreeLibraryAndExitThread//FreeLibrary
 
-	m_hUnInjectThread = CreateRemoteThread(m_hInjectionProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, me32.hModule, 0, NULL);
+	// 获取模块句柄;
+	HANDLE hModule = FindModuleEx(m_szDllPath, m_dwInjectPID);
+	if (hModule == NULL )
+		return FALSE;
 
-	WaitForSingleObject(m_hUnInjectThread, INFINITE);
-
-	// 释放所有资源;
-	if (m_hInjectThread)
-		CloseHandle(m_hInjectThread);
-	if (m_hUnInjectThread)
-		CloseHandle(m_hUnInjectThread);
-	if (m_lpPathData)
-		VirtualFreeEx(m_hInjectionProcess, m_lpPathData, m_dwPathLen, MEM_DECOMMIT);
-	
-	if (m_hInjectionProcess)
-		CloseHandle(m_hInjectionProcess);
+	LPVOID lpAddr = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibraryAndExitThread");//FreeLibraryAndExitThread//FreeLibrary
+	m_hEjectThread = CreateRemoteThread(m_hInjectProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, hModule, 0, NULL);
+	WaitForSingleObject(m_hEjectThread, INFINITE);
 
-	return 0;
+	return TRUE;
 }
 
 void CInjection::InjectionExistProcess()

+ 7 - 6
source/hook/WeChats/Injection.h

@@ -26,23 +26,24 @@ public:
 	CInjection(DWORD dwPid, LPCTSTR lpDynamicLibraryPath);
 	~CInjection(void);
 
-	int ProcessInjection();
-	int FreeInjection();
+	BOOL InjectDynamicLibrary();
+	BOOL EjectDynamicLibrary();
 
 	// 当前注入的进程ID;
-	DWORD			m_dwInjectionPID;
+	DWORD			m_dwInjectPID;
 	// 动态库路径;
 	TCHAR			m_szDllPath[MAX_PATH];
 	// 当前注入的进程句柄;
-	HANDLE			m_hInjectionProcess;
+	HANDLE			m_hInjectProcess;
 	// 路径分配的内存;
-	LPVOID			m_lpPathData;
+	LPVOID			m_lpInjectData;
+	LPVOID			m_lpEjectData;
 	// 路径长度;
 	DWORD			m_dwPathLen;
 	// 注入线程句柄;
 	HANDLE			m_hInjectThread;
 	// 卸载线程句柄;
-	HANDLE			m_hUnInjectThread;
+	HANDLE			m_hEjectThread;
 
 public:
 	// 注入已有的进程;

+ 10 - 5
source/hook/WeChats/WeChats.cpp

@@ -53,17 +53,22 @@ BOOL CWeChatsApp::InitInstance()
 	
 	// 获取配置信息;
 	GetIniInfo();
+	GetDebugPriv();
+
+#if _DEBUG
 	TCHAR szDllPath[MAX_PATH];
 	ZeroMemory(szDllPath,MAX_PATH);
 	DWORD ss = sizeof(szDllPath);
 	DWORD sss = _tcslen(szDllPath)*sizeof(TCHAR);
 	_stprintf_s(szDllPath, _T("%shook.dll"), g_szModulePath);
 	vector<DWORD> vtPID = FindAllProcess(WECHAT);
-	CInjection inject(*vtPID.begin(),szDllPath);
-	inject.ProcessInjection();
-	Sleep(5000);
-
-
+	if (vtPID.size() != 0 )
+	{
+		CInjection inject(*vtPID.begin(),szDllPath);
+		inject.InjectDynamicLibrary();
+		inject.EjectDynamicLibrary();
+	}
+#endif
 
 	// 标准初始化
 	// 如果未使用这些功能并希望减小

+ 5 - 0
source/hook/hook/dllmain.cpp

@@ -10,11 +10,16 @@ BOOL APIENTRY DllMain( HMODULE hModule,
 	{
 	case DLL_PROCESS_ATTACH:
 		MessageBox(NULL, _T("dll已成功注入"), _T("注入"), MB_OK);
+		break;
 	case DLL_THREAD_ATTACH:
+		break;
 	case DLL_THREAD_DETACH:
+		break;
 	case DLL_PROCESS_DETACH:
 		MessageBox(NULL, _T("dll已成功卸载"), _T("注入"), MB_OK);
 		break;
+	default:
+		break;
 	}
 	return TRUE;
 }