#include "StdAfx.h"
#include "Injection.h"

CInjection::CInjection(DWORD dwPid, LPCTSTR lpDynamicLibraryPath)
:m_dwInjectPID(dwPid),
m_hInjectProcess(NULL),
m_lpInjectData(NULL),
m_lpEjectData(NULL),
m_hInjectThread(NULL),
m_hEjectThread(NULL),
m_dwPathLen(0)
{
	ASSERT(dwPid!=0);
	ASSERT(lpDynamicLibraryPath!=NULL);

	memset(m_szDllPath, 0, sizeof(m_szDllPath));
	_tcscpy_s(m_szDllPath,lpDynamicLibraryPath);
	
	m_hInjectProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwInjectPID);
	if ( m_hInjectProcess == NULL)
	{
		WriteTextLog(_T("打开WeChat.exe进程失败"));
	}
	//m_hInjectProcess = OpenProcess(PROCESS_CREATE_THREAD	| PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwInjectPID);
}

CInjection::~CInjection(void)
{
	// 卸载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;
}

BOOL CInjection::InjectDynamicLibrary()
{
	ASSERT(m_hInjectProcess!=NULL);

	m_dwPathLen = _tcslen(m_szDllPath)*sizeof(TCHAR)+1;
	m_lpInjectData = VirtualAllocEx(m_hInjectProcess,NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == m_lpInjectData)
	{
		WriteTextLog(_T("创建WeChat.exe进程虚拟内存失败"));
		return FALSE;
	}

	if (WriteProcessMemory(m_hInjectProcess, m_lpInjectData, m_szDllPath, m_dwPathLen, NULL) == 0)
	{
		// 注意：MEM_RELEASE释放时第三参数一定要为0，请查看MSDN;
		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_hInjectProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, m_lpInjectData, 0, NULL);
	if (NULL == m_hInjectThread)
	{
		// 注意：MEM_RELEASE释放时第三参数一定要为0，请查看MSDN;
		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, 0, MEM_RELEASE);
		return FALSE;
	}

	if (m_hInjectThread)
		CloseHandle(m_hInjectThread);
	m_hInjectThread = NULL;
	
	/* 注入成功后，不能释放内存否则微信会挂;
	if (m_lpInjectData != NULL)
		VirtualFreeEx(m_hInjectProcess, m_lpInjectData, 0, MEM_RELEASE);
	*/

	return TRUE;
}

BOOL CInjection::EjectDynamicLibrary()
{
	if(m_hInjectProcess==NULL)
		return TRUE;

	// 获取模块句柄;
	HANDLE hModule = FindModuleEx(m_szDllPath, m_dwInjectPID);
	if (hModule == NULL )
	{
		WriteTextLog(_T("获取WeChat.exe进程模块hook.dll失败"));
		return FALSE;
	}

	LPVOID lpAddr = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibraryAndExitThread");//FreeLibraryAndExitThread//FreeLibrary
	if (lpAddr == NULL )
	{
		WriteTextLog(_T("获取kernel32.dll中的FreeLibraryAndExitThread失败"));
		return FALSE;
	}

	m_hEjectThread = CreateRemoteThread(m_hInjectProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, hModule, 0, NULL);
	if ( m_hEjectThread == NULL )
	{
		WriteTextLog(_T("创建WeChat.exe远程线程（FreeLibraryAndExitThread）失败"));
		return FALSE;
	}

	WaitForSingleObject(m_hEjectThread, INFINITE);

	return TRUE;
}

void CInjection::InjectionExistProcess()
{
	// 查找现在的进程;
	vector<DWORD> vtPID = FindAllProcess(WECHAT);
}