Browse Source

完成微信多开,使用未公开的Win API关闭互斥句柄。

Jeff 6 years ago
parent
commit
14d51ded1a

+ 83 - 3
source/hook/WeChats/Global.cpp

@@ -255,10 +255,10 @@ BOOL GetDebugPriv()
 	LUID	sedebugnameValue;
 	// 新特权信息的指针(结构体);
 	TOKEN_PRIVILEGES tkp;
-	DWORD	dwCurProcId = GetCurrentProcessId();
+	//DWORD	dwCurProcId = GetCurrentProcessId();
 	// 要修改访问权限的进程句柄;
-	HANDLE	hCurProc;
-	hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
+	HANDLE	hCurProc = ::GetCurrentProcess();
+	//hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
 
 	if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
 	{
@@ -846,3 +846,83 @@ BOOL MySystemShutdown()
 
 	return TRUE;
 }
+
+BOOL getWeChatPath()
+{
+	// 通过注册表获取微信安装目录;
+	HKEY hKey = NULL;
+	if(ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Tencent\\WeChat"), &hKey))
+	{
+		return FALSE;
+	}
+
+	DWORD Type = REG_SZ;
+	DWORD cbData = MAX_PATH*sizeof(WCHAR);
+	if(ERROR_SUCCESS != RegQueryValueEx(hKey, _T("InstallPath"), 0, &Type, (LPBYTE)g_szWeChatPath, &cbData))
+	{
+		RegCloseKey(hKey);
+		return FALSE;
+	}
+
+	PathAppend(g_szWeChatPath, _T("WeChat.exe"));
+
+	return TRUE;
+}
+
+BOOL OpenWeChat()
+{
+	STARTUPINFO si;
+	PROCESS_INFORMATION pi;
+	ZeroMemory(&si, sizeof(si));
+	si.cb = sizeof(si);
+	ZeroMemory(&pi, sizeof(pi));
+
+	si.dwFlags = STARTF_USESHOWWINDOW;  // 指定wShowWindow成员有效
+	si.wShowWindow = TRUE;				// 此成员设为TRUE的话则显示新建进程的主窗口,
+	// 为FALSE的话则不显示
+	BOOL bRet = ::CreateProcess (
+		g_szWeChatPath,		// 不在此指定可执行文件的文件名
+		NULL,				// 命令行参数
+		NULL,				// 默认进程安全性
+		NULL,				// 默认线程安全性
+		FALSE,				// 指定当前进程内的句柄不可以被子进程继承
+		//CREATE_SUSPENDED,	// 挂起进程;CREATE_SUSPENDED
+		NULL,
+		NULL,				// 使用本进程的环境变量
+		NULL,				// 使用本进程的驱动器和目录
+		&si,
+		&pi);
+
+	if(bRet)
+	{
+		// 进程挂起后,仍能成功注入dll;
+// 		TCHAR szDllPath[MAX_PATH];
+// 		ZeroMemory(szDllPath,MAX_PATH);
+// 		_stprintf_s(szDllPath, _T("%shook.dll"), g_szModulePath);
+// 		for (int i = 0; i < 10; i++)
+// 		{
+// 			CInjection inject(pi.dwProcessId,szDllPath);
+// 			inject.InjectDynamicLibrary();
+// 			inject.EjectDynamicLibrary();
+// 		}
+
+		//不sleep就会出现读取不到的297错误
+		//Sleep(5000);				
+
+		//获取线程上下文
+// 		CONTEXT ct = { 0 };
+// 		ct.ContextFlags = CONTEXT_CONTROL;
+// 		GetThreadContext(pi.hThread, &ct);
+// 
+// 		::ResumeThread(pi.hThread);	
+
+		// 既然我们不使用两个句柄,最好是立刻将它们关闭
+		::CloseHandle (pi.hThread);
+		::CloseHandle (pi.hProcess);
+
+		// 当进程挂起时,是无法修改关闭微信句柄;
+		PatchWeChat();
+	}
+
+	return TRUE;
+}

+ 5 - 0
source/hook/WeChats/Global.h

@@ -28,6 +28,7 @@ extern TCHAR g_szWeChatPath[MAX_PATH];
 extern TCHAR g_szCacheDir[MAX_PATH];	
 extern TCHAR g_szDynamicLibraryPath[MAX_PATH];
 
+
 // ¿ØÖÆÌ¨Êä³ö;
 extern BOOL g_bStdOut;
 
@@ -55,4 +56,8 @@ extern BOOL PreventSystemShutdown();
 extern BOOL MySystemShutdown();
 
 
+//////////////////////////////////////////////////////////////////////////
+extern BOOL getWeChatPath();
+extern BOOL OpenWeChat();
+
 #endif

+ 148 - 49
source/hook/WeChats/WeChats.cpp

@@ -35,6 +35,143 @@ CWeChatsApp theApp;
 
 // CWeChatsApp 初始化
 
+//////////////////////////////////////////////////////////////////////////
+// BEGIN
+// killWeChatMutex函数用到的未公开的声明;
+
+typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;  
+
+
+// 以下声明,都是系统未公开的定义;
+
+typedef enum {
+	ProcessBasicInformation = 0,
+	ProcessDebugPort = 7,
+	ProcessWow64Information = 26,
+	ProcessImageFileName = 27,
+	ProcessBreakOnTermination = 29,
+	ProcessProtectionInformation = 61,
+}PROCESSINFOCLASS;
+
+typedef struct _PEB_LDR_DATA {
+	BYTE       Reserved1[8];
+	PVOID      Reserved2[3];
+	LIST_ENTRY InMemoryOrderModuleList;
+} PEB_LDR_DATA, *PPEB_LDR_DATA;
+
+typedef struct _LDR_DATA_TABLE_ENTRY {
+	PVOID Reserved1[2];
+	LIST_ENTRY InMemoryOrderLinks;
+	PVOID Reserved2[2];
+	PVOID DllBase;
+	PVOID EntryPoint;
+	PVOID Reserved3;
+	UNICODE_STRING FullDllName;
+	BYTE Reserved4[8];
+	PVOID Reserved5[3];
+	union {
+		ULONG CheckSum;
+		PVOID Reserved6;
+	};
+	ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
+
+typedef struct _RTL_USER_PROCESS_PARAMETERS {
+	BYTE           Reserved1[16];
+	PVOID          Reserved2[10];
+	UNICODE_STRING ImagePathName;
+	UNICODE_STRING CommandLine;
+} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
+
+// 32位下的结构;
+typedef struct _PEB {
+	BYTE                          Reserved1[2];
+	BYTE                          BeingDebugged;
+	BYTE                          Reserved2[1];
+	PVOID                         Reserved3[2];
+	PPEB_LDR_DATA                 Ldr;
+	PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
+	PVOID                         Reserved4[3];
+	PVOID                         AtlThunkSListPtr;
+	PVOID                         Reserved5;
+	ULONG                         Reserved6;
+	PVOID                         Reserved7;
+	ULONG                         Reserved8;
+	ULONG                         AtlThunkSListPtr32;
+	PVOID                         Reserved9[45];
+	BYTE                          Reserved10[96];
+	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
+	BYTE                          Reserved11[128];
+	PVOID                         Reserved12[1];
+	ULONG                         SessionId;
+} PEB, *PPEB;
+// 64位下的结构;
+typedef struct _PEBX64 {
+	BYTE Reserved1[2];
+	BYTE BeingDebugged;
+	BYTE Reserved2[21];
+	PPEB_LDR_DATA LoaderData;
+	PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+	BYTE Reserved3[520];
+	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
+	BYTE Reserved4[136];
+	ULONG SessionId;
+} PEBX64;
+
+typedef struct _PROCESS_BASIC_INFORMATION {
+	PVOID Reserved1;
+	PPEB PebBaseAddress;
+	PVOID Reserved2[2];
+	ULONG_PTR UniqueProcessId;
+	PVOID Reserved3;
+} PROCESS_BASIC_INFORMATION;
+
+// 声音函数指针;
+typedef NTSTATUS (WINAPI *pfZwQueryInformationProcess)(
+	_In_      HANDLE           ProcessHandle,
+	_In_      PROCESSINFOCLASS ProcessInformationClass,
+	_Out_     PVOID            ProcessInformation,
+	_In_      ULONG            ProcessInformationLength,
+	_Out_opt_ PULONG           ReturnLength
+	);
+
+// END
+//////////////////////////////////////////////////////////////////////////
+
+NTSTATUS GetProcessModules(HANDLE hProcess, LPCTSTR lpTypName, LPCTSTR lpName)
+{
+	NTSTATUS Status = 0;
+	pfZwQueryInformationProcess ZwQueryInformationProcess = NULL;
+
+	PROCESS_BASIC_INFORMATION ProcessInfo;
+	PPEB	pPeb;
+
+	ZwQueryInformationProcess = (pfZwQueryInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQueryInformationProcess");
+	if (ZwQueryInformationProcess == NULL)
+	{
+		WriteTextLog(_T("查找进程模块名称失败"));
+		return Status;
+	}
+
+	Status = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL);
+	if (NT_SUCCESS(Status))
+	{
+		pPeb = (PPEB)ProcessInfo.PebBaseAddress;
+
+		for (PLIST_ENTRY pListEntry = pPeb->Ldr->InMemoryOrderModuleList.Flink;pListEntry != &pPeb->Ldr->InMemoryOrderModuleList;pListEntry = pListEntry->Flink)
+		{
+			//PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, pListEntry);
+			//wprintf(L"%s\n", pEntry->FullDllName.Buffer);
+			WriteTextLog(_T("模块名称"));
+		}
+	}
+	else
+		WriteTextLog(_T("查找进程模块名称失败1"));
+
+	CloseHandle(hProcess);
+	return Status;
+}
+
 BOOL CWeChatsApp::InitInstance()
 {
 	// 如果一个运行在 Windows XP 上的应用程序清单指定要
@@ -54,58 +191,20 @@ BOOL CWeChatsApp::InitInstance()
 	// 获取配置信息;
 	GetIniInfo();
 	GetDebugPriv();
+// 	HANDLE hObject = CreateMutex(NULL, FALSE, _T("CYLGLAppXiao"));
+// 	if (GetLastError() == ERROR_ALREADY_EXISTS)
+// 	{
+// 		return FALSE;
+// 	}
+// 	GetProcessModules(::GetCurrentProcess(), _T("Mutant"), _T("_WeChat_Instance_Identity_Mutex_Name"));
 
+	
 #if _DEBUG // 创建进程,并挂起;
-	STARTUPINFO si;
-	PROCESS_INFORMATION pi;
-	ZeroMemory(&si, sizeof(si));
-	si.cb = sizeof(si);
-	ZeroMemory(&pi, sizeof(pi));
-
-	si.dwFlags = STARTF_USESHOWWINDOW;  // 指定wShowWindow成员有效
-	si.wShowWindow = TRUE;				// 此成员设为TRUE的话则显示新建进程的主窗口,
-	// 为FALSE的话则不显示
-	BOOL bRet = ::CreateProcess (
-		_T("C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe"),				// 不在此指定可执行文件的文件名
-		NULL,				// 命令行参数
-		NULL,				// 默认进程安全性
-		NULL,				// 默认线程安全性
-		FALSE,				// 指定当前进程内的句柄不可以被子进程继承
-		CREATE_SUSPENDED,	// 挂起进程;
-		NULL,				// 使用本进程的环境变量
-		NULL,				// 使用本进程的驱动器和目录
-		&si,
-		&pi);
-
-	if(bRet)
-	{
-		// 进程挂起后,仍能成功注入dll;
-		TCHAR szDllPath[MAX_PATH];
-		ZeroMemory(szDllPath,MAX_PATH);
-		_stprintf_s(szDllPath, _T("%shook.dll"), g_szModulePath);
-		for (int i = 0; i < 10; i++)
-		{
-			CInjection inject(pi.dwProcessId,szDllPath);
-			inject.InjectDynamicLibrary();
-			inject.EjectDynamicLibrary();
-			Sleep(3000);
-		}
 
-		//不sleep就会出现读取不到的297错误
-		Sleep(5000);				
-
-		//获取线程上下文
-		CONTEXT ct = { 0 };
-		ct.ContextFlags = CONTEXT_CONTROL;
-		GetThreadContext(pi.hThread, &ct);
-
-		::ResumeThread(pi.hThread);	
-
-		// 既然我们不使用两个句柄,最好是立刻将它们关闭
-		::CloseHandle (pi.hThread);
-		::CloseHandle (pi.hProcess);
-
-	}
+	getWeChatPath();
+	for (int i = 0; i < 10; i++)
+		OpenWeChat();
+	
 #endif
 
 #if !_DEBUG

+ 204 - 0
source/hook/WeChats/stdafx.cpp

@@ -6,3 +6,207 @@
 #include "stdafx.h"
 
 
+HANDLE DuplicateHandleEx(DWORD pid, HANDLE h, DWORD flags)
+{
+	HANDLE hHandle = NULL;
+	HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+	if(hProc)
+	{
+		if(!DuplicateHandle(hProc,(HANDLE)h, GetCurrentProcess(),&hHandle, 0, FALSE, flags))
+		{
+			hHandle = NULL;
+		}
+	}
+
+	CloseHandle(hProc);
+	return hHandle;
+}
+
+
+int GetProcIds(LPWSTR Name, DWORD* Pids)
+{
+	PROCESSENTRY32 pe32 = {sizeof(pe32)};
+	int num = 0;
+
+	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+	if(hSnap)
+	{
+		if(Process32First(hSnap, &pe32))
+		{
+			do {
+				if(!wcsicmp(Name, pe32.szExeFile))
+				{
+					if(Pids)
+					{
+						Pids[num++] = pe32.th32ProcessID;
+					}
+				}
+			} while(Process32Next(hSnap, &pe32));
+		}
+		CloseHandle(hSnap);
+	}
+
+	return num;
+}
+
+BOOL IsTargetPid(DWORD Pid, DWORD* Pids, int num)
+{
+	for(int i=0; i<num; i++)
+	{
+		if(Pid == Pids[i])
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+int PatchWeChat()
+{
+	DWORD dwSize = 0;
+	POBJECT_NAME_INFORMATION pNameInfo;
+	POBJECT_NAME_INFORMATION pNameType;
+	PVOID pbuffer = NULL;
+	NTSTATUS Status;
+	int nIndex = 0;
+	DWORD dwFlags = 0;
+	char szType[128] = {0};
+	char szName[512] = {0};
+
+	DWORD Pids[100] = {0};
+
+	DWORD Num = GetProcIds(L"WeChat.exe", Pids);
+	if(Num == 0)
+	{
+		return 0;
+	}
+
+	if(!ZwQuerySystemInformation)
+	{
+		goto Exit0;
+	}
+
+	pbuffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE);
+
+	if(!pbuffer)
+	{
+		goto Exit0;
+	}
+
+	Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, 0x1000, &dwSize);
+
+	if(!NT_SUCCESS(Status))
+	{
+		if (STATUS_INFO_LENGTH_MISMATCH != Status)
+		{
+			goto Exit0;
+		}
+		else
+		{
+			// 这里大家可以保证程序的正确性使用循环分配稍好
+			if (NULL != pbuffer)
+			{
+				VirtualFree(pbuffer, 0, MEM_RELEASE);
+			}
+
+			if (dwSize*2 > 0x4000000)  // MAXSIZE
+			{
+				goto Exit0;
+			}
+
+			pbuffer = VirtualAlloc(NULL, dwSize*2, MEM_COMMIT, PAGE_READWRITE);
+
+			if(!pbuffer)
+			{
+				goto Exit0;
+			}
+
+			Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, dwSize*2, NULL);
+
+			if(!NT_SUCCESS(Status))
+			{
+				goto Exit0;    
+			}
+		}
+	}
+
+	PSYSTEM_HANDLE_INFORMATION1 pHandleInfo = (PSYSTEM_HANDLE_INFORMATION1)pbuffer;
+
+	for(nIndex = 0; nIndex < pHandleInfo->NumberOfHandles; nIndex++)
+	{
+		if(IsTargetPid(pHandleInfo->Handles[nIndex].UniqueProcessId, Pids, Num))
+		{
+			//
+			HANDLE hHandle = DuplicateHandleEx(pHandleInfo->Handles[nIndex].UniqueProcessId, 
+				(HANDLE)pHandleInfo->Handles[nIndex].HandleValue,
+				DUPLICATE_SAME_ACCESS
+				);
+			if(hHandle == NULL) continue;
+
+			Status = NtQueryObject(hHandle, ObjectNameInformation, szName, 512, &dwFlags);
+
+			if (!NT_SUCCESS(Status))
+			{
+				CloseHandle(hHandle);
+				continue;
+			}
+
+			Status = NtQueryObject(hHandle, ObjectTypeInformation, szType, 128, &dwFlags);
+
+			if (!NT_SUCCESS(Status))
+			{
+				CloseHandle(hHandle);
+				continue;
+			}
+
+			pNameInfo = (POBJECT_NAME_INFORMATION)szName;
+			pNameType = (POBJECT_NAME_INFORMATION)szType;
+
+			WCHAR TypName[1024] = {0};
+			WCHAR Name[1024] = {0};
+
+			wcsncpy(TypName, (WCHAR*)pNameType->Name.Buffer, pNameType->Name.Length/2);
+			wcsncpy(Name, (WCHAR*)pNameInfo->Name.Buffer, pNameInfo->Name.Length/2);
+
+			// 匹配是否为需要关闭的句柄名称
+			if (0 == wcscmp(TypName, L"Mutant"))
+			{
+				//WeChat_aj5r8jpxt_Instance_Identity_Mutex_Name
+				//if (wcsstr(Name, L"_WeChat_App_Instance_Identity_Mutex_Name"))
+				if (wcsstr(Name, L"_WeChat_") &&
+					wcsstr(Name, L"_Instance_Identity_Mutex_Name"))
+				{
+					CloseHandle(hHandle);
+
+					hHandle = DuplicateHandleEx(pHandleInfo->Handles[nIndex].UniqueProcessId, 
+						(HANDLE)pHandleInfo->Handles[nIndex].HandleValue,
+						DUPLICATE_CLOSE_SOURCE
+						);
+
+					if(hHandle)
+					{
+						printf("+ Patch wechat success!\n");
+						CloseHandle(hHandle);
+					}
+					else
+					{
+						printf("- Patch error: %d\n", GetLastError());
+					}
+
+					goto Exit0;
+				}
+			}
+
+			CloseHandle(hHandle);
+		}
+
+	}
+
+Exit0:
+	if (NULL != pbuffer)
+	{
+		VirtualFree(pbuffer, 0, MEM_RELEASE);
+	}
+
+	return 0;
+}

+ 212 - 0
source/hook/WeChats/stdafx.h

@@ -58,3 +58,215 @@
 #endif
 
 
+
+//////////////////////////////////////////////////////////////////////////
+
+typedef LONG NTSTATUS;
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
+
+typedef enum _SYSTEM_INFORMATION_CLASS {
+	SystemBasicInformation,              // 0        Y        N
+	SystemProcessorInformation,          // 1        Y        N
+	SystemPerformanceInformation,        // 2        Y        N
+	SystemTimeOfDayInformation,          // 3        Y        N
+	SystemNotImplemented1,               // 4        Y        N
+	SystemProcessesAndThreadsInformation, // 5       Y        N
+	SystemCallCounts,                    // 6        Y        N
+	SystemConfigurationInformation,      // 7        Y        N
+	SystemProcessorTimes,                // 8        Y        N
+	SystemGlobalFlag,                    // 9        Y        Y
+	SystemNotImplemented2,               // 10       Y        N
+	SystemModuleInformation,             // 11       Y        N
+	SystemLockInformation,               // 12       Y        N
+	SystemNotImplemented3,               // 13       Y        N
+	SystemNotImplemented4,               // 14       Y        N
+	SystemNotImplemented5,               // 15       Y        N
+	SystemHandleInformation,             // 16       Y        N
+	SystemObjectInformation,             // 17       Y        N
+	SystemPagefileInformation,           // 18       Y        N
+	SystemInstructionEmulationCounts,    // 19       Y        N
+	SystemInvalidInfoClass1,             // 20
+	SystemCacheInformation,              // 21       Y        Y
+	SystemPoolTagInformation,            // 22       Y        N
+	SystemProcessorStatistics,           // 23       Y        N
+	SystemDpcInformation,                // 24       Y        Y
+	SystemNotImplemented6,               // 25       Y        N
+	SystemLoadImage,                     // 26       N        Y
+	SystemUnloadImage,                   // 27       N        Y
+	SystemTimeAdjustment,                // 28       Y        Y
+	SystemNotImplemented7,               // 29       Y        N
+	SystemNotImplemented8,               // 30       Y        N
+	SystemNotImplemented9,               // 31       Y        N
+	SystemCrashDumpInformation,          // 32       Y        N
+	SystemExceptionInformation,          // 33       Y        N
+	SystemCrashDumpStateInformation,     // 34       Y        Y/N
+	SystemKernelDebuggerInformation,     // 35       Y        N
+	SystemContextSwitchInformation,      // 36       Y        N
+	SystemRegistryQuotaInformation,      // 37       Y        Y
+	SystemLoadAndCallImage,              // 38       N        Y
+	SystemPrioritySeparation,            // 39       N        Y
+	SystemNotImplemented10,              // 40       Y        N
+	SystemNotImplemented11,              // 41       Y        N
+	SystemInvalidInfoClass2,             // 42
+	SystemInvalidInfoClass3,             // 43
+	SystemTimeZoneInformation,           // 44       Y        N
+	SystemLookasideInformation,          // 45       Y        N
+	SystemSetTimeSlipEvent,              // 46       N        Y
+	SystemCreateSession,                 // 47       N        Y
+	SystemDeleteSession,                 // 48       N        Y
+	SystemInvalidInfoClass4,             // 49
+	SystemRangeStartInformation,         // 50       Y        N
+	SystemVerifierInformation,           // 51       Y        Y
+	SystemAddVerifier,                   // 52       N        Y
+	SystemSessionProcessesInformation    // 53       Y        N
+} SYSTEM_INFORMATION_CLASS;
+
+typedef struct _CLIENT_ID
+{
+	HANDLE UniqueProcess;
+	HANDLE UniqueThread;
+}CLIENT_ID,*PCLIENT_ID;
+
+typedef struct
+{
+	USHORT Length;
+	USHORT MaxLen;
+	USHORT *Buffer;
+}UNICODE_STRING, *PUNICODE_STRING;
+
+typedef struct _OBJECT_ATTRIBUTES 
+{
+	ULONG Length;
+	HANDLE RootDirectory;
+	PUNICODE_STRING ObjectName;
+	ULONG Attributes;
+	PVOID SecurityDescriptor;
+	PVOID SecurityQualityOfService;
+} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 
+
+typedef struct _IO_COUNTERSEX {
+	LARGE_INTEGER ReadOperationCount;
+	LARGE_INTEGER WriteOperationCount;
+	LARGE_INTEGER OtherOperationCount;
+	LARGE_INTEGER ReadTransferCount;
+	LARGE_INTEGER WriteTransferCount;
+	LARGE_INTEGER OtherTransferCount;
+} IO_COUNTERSEX, *PIO_COUNTERSEX;
+
+typedef enum {
+	StateInitialized,
+	StateReady,
+	StateRunning,
+	StateStandby,
+	StateTerminated,
+	StateWait,
+	StateTransition,
+	StateUnknown
+} THREAD_STATE;
+
+typedef struct _VM_COUNTERS {
+	SIZE_T PeakVirtualSize;
+	SIZE_T VirtualSize;
+	ULONG PageFaultCount;
+	SIZE_T PeakWorkingSetSize;
+	SIZE_T WorkingSetSize;
+	SIZE_T QuotaPeakPagedPoolUsage;
+	SIZE_T QuotaPagedPoolUsage;
+	SIZE_T QuotaPeakNonPagedPoolUsage;
+	SIZE_T QuotaNonPagedPoolUsage;
+	SIZE_T PagefileUsage;
+	SIZE_T PeakPagefileUsage;
+} VM_COUNTERS;
+typedef VM_COUNTERS *PVM_COUNTERS;
+
+typedef struct _SYSTEM_THREADS {
+	LARGE_INTEGER KernelTime;
+	LARGE_INTEGER UserTime;
+	LARGE_INTEGER CreateTime;
+	ULONG WaitTime;
+	PVOID StartAddress;
+	CLIENT_ID ClientId;
+	ULONG Priority;
+	ULONG BasePriority;
+	ULONG ContextSwitchCount;
+	THREAD_STATE State;
+	ULONG WaitReason;
+} SYSTEM_THREADS, *PSYSTEM_THREADS;
+
+typedef struct _SYSTEM_PROCESSES { // Information Class 5
+	ULONG NextEntryDelta;
+	ULONG ThreadCount;
+	ULONG Reserved1[6];
+	LARGE_INTEGER CreateTime;
+	LARGE_INTEGER UserTime;
+	LARGE_INTEGER KernelTime;
+	UNICODE_STRING ProcessName;
+	ULONG BasePriority;
+	ULONG ProcessId;
+	ULONG InheritedFromProcessId;
+	ULONG HandleCount;
+	ULONG Reserved2[2];
+	VM_COUNTERS VmCounters;
+	IO_COUNTERSEX IoCounters;  // Windows 2000 only
+	SYSTEM_THREADS Threads[1];
+} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
+
+typedef struct _SYSTEM_HANDLE_INFORMATION
+{
+	ULONG            ProcessId;
+	UCHAR            ObjectTypeNumber;
+	UCHAR            Flags;
+	USHORT            Handle;
+	PVOID            Object;
+	ACCESS_MASK        GrantedAccess;
+} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
+	USHORT UniqueProcessId;
+	USHORT CreatorBackTraceIndex;
+	UCHAR ObjectTypeIndex;
+	UCHAR HandleAttributes;
+	USHORT HandleValue;
+	PVOID Object;
+	ULONG GrantedAccess;
+} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
+
+typedef struct _SYSTEM_HANDLE_INFORMATION1 {
+	ULONG NumberOfHandles;
+	SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ];
+} SYSTEM_HANDLE_INFORMATION1, *PSYSTEM_HANDLE_INFORMATION1;
+
+typedef enum _OBJECT_INFORMATION_CLASS {
+	ObjectBasicInformation,
+	ObjectNameInformation,
+	ObjectTypeInformation,
+	ObjectAllInformation,
+	ObjectDataInformation
+} OBJECT_INFORMATION_CLASS;
+
+typedef struct _OBJECT_NAME_INFORMATION {
+	UNICODE_STRING Name;
+} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
+
+typedef NTSTATUS (NTAPI *NTQUERYOBJECT)(
+										_In_opt_   HANDLE Handle,
+										_In_       OBJECT_INFORMATION_CLASS ObjectInformationClass,
+										_Out_opt_  PVOID ObjectInformation,
+										_In_       ULONG ObjectInformationLength,
+										_Out_opt_  PULONG ReturnLength
+										);
+
+
+typedef NTSTATUS
+(NTAPI *ZWQUERYSYSTEMINFORMATION)(
+								  IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+								  OUT PVOID SystemInformation,
+								  IN ULONG SystemInformationLength,
+								  OUT PULONG ReturnLength OPTIONAL
+								  );
+ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQuerySystemInformation");
+NTQUERYOBJECT    NtQueryObject = (NTQUERYOBJECT)GetProcAddress(GetModuleHandleA("ntdll.dll"),"NtQueryObject");
+
+
+extern int PatchWeChat();

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

@@ -76,6 +76,46 @@ void WriteTextLog(const TCHAR *format, ...)
 	free(old_locale);//还原区域设定;
 }
 
+// 本函数使用的都是未公开的Win API
+// 即:以后可能会变化的函数;
+void killWeChatMutex()
+{
+}
+
+NTSTATUS GetProcessModules(HANDLE hProcess, LPCTSTR lpTypName, LPCTSTR lpName)
+{
+	NTSTATUS Status = 0;
+	pfZwQueryInformationProcess ZwQueryInformationProcess = NULL;
+
+	PROCESS_BASIC_INFORMATION ProcessInfo;
+	PPEB	pPeb;
+
+	ZwQueryInformationProcess = (pfZwQueryInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQueryInformationProcess");
+	if (ZwQueryInformationProcess == NULL)
+	{
+		WriteTextLog(_T("查找进程模块名称失败"));
+		return Status;
+	}
+
+	Status = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL);
+	if (NT_SUCCESS(Status))
+	{
+		pPeb = (PPEB)ProcessInfo.PebBaseAddress;
+
+		for (PLIST_ENTRY pListEntry = pPeb->Ldr->InMemoryOrderModuleList.Flink;pListEntry != &pPeb->Ldr->InMemoryOrderModuleList;pListEntry = pListEntry->Flink)
+		{
+			//PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, pListEntry);
+			//wprintf(L"%s\n", pEntry->FullDllName.Buffer);
+			WriteTextLog(_T("模块名称"));
+		}
+	}
+	else
+		WriteTextLog(_T("查找进程模块名称失败1"));
+
+	CloseHandle(hProcess);
+	return Status;
+}
+
 BOOL APIENTRY DllMain( HMODULE hModule,
                        DWORD  ul_reason_for_call,
                        LPVOID lpReserved
@@ -86,6 +126,7 @@ BOOL APIENTRY DllMain( HMODULE hModule,
 	{
 	case DLL_PROCESS_ATTACH:
 		WriteTextLog(_T("dll已成功注入"));
+		GetProcessModules(::GetCurrentProcess(), _T("Mutant"), _T("_WeChat_Instance_Identity_Mutex_Name"));
 		break;
 	case DLL_THREAD_ATTACH:
 		break;

+ 111 - 1
source/hook/hook/stdafx.h

@@ -16,4 +16,114 @@
 #include <stdlib.h>
 #include <time.h> //或者 #include <ctime>
 
-// TODO: 在此处引用程序需要的其他头文件
+#include <WinDef.h>
+//#include <ntifs.h>
+//#include <wudfwdm.h> // UNICODE_STRING的头文件;
+
+//////////////////////////////////////////////////////////////////////////
+// BEGIN
+// killWeChatMutex函数用到的未公开的声明;
+typedef LONG	NTSTATUS;
+typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;  
+#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
+
+// 以下声明,都是系统未公开的定义;
+typedef struct _UNICODE_STRING {
+	USHORT Length;
+	USHORT MaximumLength;
+	PWCH   Buffer;
+} UNICODE_STRING;
+
+typedef enum {
+	ProcessBasicInformation = 0,
+	ProcessDebugPort = 7,
+	ProcessWow64Information = 26,
+	ProcessImageFileName = 27,
+	ProcessBreakOnTermination = 29,
+	ProcessProtectionInformation = 61,
+}PROCESSINFOCLASS;
+
+typedef struct _PEB_LDR_DATA {
+	BYTE       Reserved1[8];
+	PVOID      Reserved2[3];
+	LIST_ENTRY InMemoryOrderModuleList;
+} PEB_LDR_DATA, *PPEB_LDR_DATA;
+
+typedef struct _LDR_DATA_TABLE_ENTRY {
+	PVOID Reserved1[2];
+	LIST_ENTRY InMemoryOrderLinks;
+	PVOID Reserved2[2];
+	PVOID DllBase;
+	PVOID EntryPoint;
+	PVOID Reserved3;
+	UNICODE_STRING FullDllName;
+	BYTE Reserved4[8];
+	PVOID Reserved5[3];
+	union {
+		ULONG CheckSum;
+		PVOID Reserved6;
+	};
+	ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
+
+typedef struct _RTL_USER_PROCESS_PARAMETERS {
+	BYTE           Reserved1[16];
+	PVOID          Reserved2[10];
+	UNICODE_STRING ImagePathName;
+	UNICODE_STRING CommandLine;
+} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
+
+// 32位下的结构;
+typedef struct _PEB {
+	BYTE                          Reserved1[2];
+	BYTE                          BeingDebugged;
+	BYTE                          Reserved2[1];
+	PVOID                         Reserved3[2];
+	PPEB_LDR_DATA                 Ldr;
+	PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
+	PVOID                         Reserved4[3];
+	PVOID                         AtlThunkSListPtr;
+	PVOID                         Reserved5;
+	ULONG                         Reserved6;
+	PVOID                         Reserved7;
+	ULONG                         Reserved8;
+	ULONG                         AtlThunkSListPtr32;
+	PVOID                         Reserved9[45];
+	BYTE                          Reserved10[96];
+	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
+	BYTE                          Reserved11[128];
+	PVOID                         Reserved12[1];
+	ULONG                         SessionId;
+} PEB, *PPEB;
+// 64位下的结构;
+typedef struct _PEBX64 {
+	BYTE Reserved1[2];
+	BYTE BeingDebugged;
+	BYTE Reserved2[21];
+	PPEB_LDR_DATA LoaderData;
+	PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+	BYTE Reserved3[520];
+	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
+	BYTE Reserved4[136];
+	ULONG SessionId;
+} PEBX64;
+
+typedef struct _PROCESS_BASIC_INFORMATION {
+	PVOID Reserved1;
+	PPEB PebBaseAddress;
+	PVOID Reserved2[2];
+	ULONG_PTR UniqueProcessId;
+	PVOID Reserved3;
+} PROCESS_BASIC_INFORMATION;
+
+// 声音函数指针;
+typedef NTSTATUS (WINAPI *pfZwQueryInformationProcess)(
+	_In_      HANDLE           ProcessHandle,
+	_In_      PROCESSINFOCLASS ProcessInformationClass,
+	_Out_     PVOID            ProcessInformation,
+	_In_      ULONG            ProcessInformationLength,
+	_Out_opt_ PULONG           ReturnLength
+	);
+
+// END
+//////////////////////////////////////////////////////////////////////////