DLL注入与卸载(用于hook api)

DLL注入与卸载

代码参考网上,最后做个小工具可以加载dll并注入到目标进程

1、判断系统版本,winxp win7 win vista win10

DWORD checkOS()
{
	OSVERSIONINFO os_version;

	os_version.dwOSVersionInfoSize = sizeof(os_version);

	if (GetVersionEx(&os_version))
	{
		if (os_version.dwMajorVersion == 5)
		{

			//wprintf(TEXT("[+] OS version: Windows XP\n"));
			return(1);
		}
		if (os_version.dwMajorVersion == 6 && os_version.dwMinorVersion == 0)
		{
			//wprintf(TEXT("[+] OS version: Windows Vista\n"));
			return(2);
		}
		if (os_version.dwMajorVersion == 6 && os_version.dwMinorVersion == 1)
		{
			//wprintf(TEXT("[+] OS version: Windows 7\n"));
			return(3);
		}
		if (os_version.dwMajorVersion == 6 && os_version.dwMinorVersion == 2)
		{
			//wprintf(TEXT("[+] OS version: Windows 10\n"));
			return(4);
		}
	}
	//else
		//printf("[-] OS version detect failed.\n");

	return(0);
}

2、win7、win vista注入dll

DWORD demoNtCreateThreadEx(PCWSTR pszLibFile, DWORD dwProcessId)
{
	HANDLE hRemoteThread = NULL;
	NtCreateThreadExBuffer ntbuffer;
	LARGE_INTEGER dwTmp1 = { 0 };
	LARGE_INTEGER dwTmp2 = { 0 };
	char cTmp[100] = { 0x00 };
	memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));

	DWORD dwSize = (lstrlenW(pszLibFile) + 1) * sizeof(wchar_t);

	HANDLE hProcess = OpenProcess(
		PROCESS_QUERY_INFORMATION |
		PROCESS_CREATE_THREAD |
		PROCESS_VM_OPERATION |
		PROCESS_VM_WRITE,
		FALSE, dwProcessId);

	if (hProcess == NULL)
	{
		return(1);
	}

	LPVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (pszLibFileRemote == NULL)
	{
		return(2);
	}

	int n = WriteProcessMemory(hProcess, pszLibFileRemote, (LPVOID)pszLibFile, dwSize, NULL);
	if (n == 0)
	{
		return(3);
	}

	PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
	if (pfnThreadRtn == NULL)
	{
		return(4);
	}

	PTHREAD_START_ROUTINE ntCreateThreadExAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtCreateThreadEx");
	if (pfnThreadRtn == NULL)
	{
		return(5);
	}

	if (ntCreateThreadExAddr)
	{
		ntbuffer.Size = sizeof(struct NtCreateThreadExBuffer);
		ntbuffer.Unknown1 = 0x10003;
		ntbuffer.Unknown2 = 0x8;
		ntbuffer.Unknown3 = (DWORD*)&dwTmp2;
		ntbuffer.Unknown4 = 0;
		ntbuffer.Unknown5 = 0x10004;
		ntbuffer.Unknown6 = 4;
		ntbuffer.Unknown7 = (DWORD*)&dwTmp1;
		ntbuffer.Unknown8 = 0;

		LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)ntCreateThreadExAddr;

		NTSTATUS status = funNtCreateThreadEx(
			&hRemoteThread,
			0x1FFFFF,
			NULL,
			hProcess,
			pfnThreadRtn,
			(LPVOID)pszLibFileRemote,
			FALSE,
			NULL,
			NULL,
			NULL,
			NULL
		);

#ifdef _DEBUG
		//wprintf(TEXT("[+] Status: %s\n"), status);
#endif
		if (status != NULL)		// FIXME: always returns NULL even when it suceeds. Go figure.
		{
			return(6);
		}
		else
		{
			WaitForSingleObject(hRemoteThread, INFINITE);
		}
	}

	if (pszLibFileRemote != NULL)
		VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

	if (hRemoteThread != NULL)
		CloseHandle(hRemoteThread);

	if (hProcess != NULL)
		CloseHandle(hProcess);

	return(0);
}

3、win10注入dll

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath) 
{
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL;  // 存储在目标进程申请的内存地址  
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);  // 存储DLL文件路径所需的内存空间大小  
	LPTHREAD_START_ROUTINE pThreadProc;
	char cTmp[100] = { 0x00 };

	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) {
		return FALSE;
	}

	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);  // 在目标进程空间中申请内存  
	if (pRemoteBuf == NULL)
	{
		return FALSE;
	}
	if (!WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL))  // 向在目标进程申请的内存空间中写入DLL文件的路径  
	{
		return FALSE;
	}

	hMod = GetModuleHandle(L"kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");  // 获得LoadLibraryW()函数的地址  
	if (pThreadProc == NULL)
	{
		return FALSE;
	}

	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
	if (hThread == NULL)
	{
		return FALSE;
	}
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;
}

4、卸载dll

BOOL UnInjectDll(DWORD dwPID, LPCTSTR szDllPath, int & nError)
{
	nError = 0;
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL;  // 存储在目标进程申请的内存地址  
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);  // 存储DLL文件路径所需的内存空间大小  
	LPTHREAD_START_ROUTINE pThreadProc;

	WCHAR * pDllName = (WCHAR *)wcsrchr(szDllPath, '\\');
	pDllName = pDllName + 1;
	//创建进程快照
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
	MODULEENTRY32 ME32 = { 0 };
	ME32.dwSize = sizeof(MODULEENTRY32);
	BOOL isNext = Module32First(hSnap, &ME32);
	BOOL flag = FALSE;
	while (isNext)
	{
		if (wcscmp(ME32.szModule, pDllName) == 0)
		{
			flag = TRUE;
			break;
		}
		isNext = Module32Next(hSnap, &ME32);
	}
	if (flag == FALSE)
	{
		AfxMessageBox(L"找不到目标模块");
		nError = 1;
		return FALSE;

	}

	// 获取目标进程句柄
	hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwPID);
	if (NULL == hProcess)
	{
		return false;
	}

	pThreadProc = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");
	if (pThreadProc == NULL)
	{
		nError = 2;
		return FALSE;
	}

	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, ME32.modBaseAddr, 0, NULL);
	if (hThread == NULL)
	{
		nError = 3;
		return FALSE;
	}
	WaitForSingleObject(hThread, INFINITE);

	CloseHandle(hThread);
	CloseHandle(hProcess);
	return TRUE;
}

实验结果

DLL注入与卸载(用于hook api)_第1张图片
DLL注入与卸载(用于hook api)_第2张图片

你可能感兴趣的:(C++,工具)