1. 首页>
  2. 技术文章>
  3. c++注入dll与卸载dll

c++注入dll与卸载dll

8/19/21 3:24:48 PM 浏览 1540 评论 0

注入dll 卸载dll

c++注入dll与卸载dll,

//MyCode.Project.WindowsForm.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "MyCode.Project.WindowsForm.h"
#include <Windows.h>
#include "resource.h"
#include <TlHelp32.h>//系统用<>
#include <stdio.h>
#include <string.h>
#include <iostream>
#define WECHAT_PROCESS_NAME "WeChat.exe"
#define DLL_PATH "E://Git//Debug//MyCode.Project.MyWeChat.dll"
using namespace std;

INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID InjectDLL();
VOID UninjectDll();

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
   
	DialogBox(hInstance, MAKEINTRESOURCE(ID_MAIN), NULL, &DialogProc);
    return 0;
}

INT_PTR  CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	if (uMsg == WM_INITDIALOG)
	{
		//MessageBox(NULL, "首次加载", "标题", 0);
	}

	if (uMsg == WM_CLOSE)
	{
		//MessageBox(NULL, "你点击了关闭", "标题", 0);
		EndDialog(hwndDlg,0);
	}

	//所有界面上按钮事件都是走的这个宏
	if (uMsg == WM_COMMAND)
	{
		if (wParam == btn_injectdll)
		{
			//MessageBox(NULL, "点击了注入按钮", "标题", 0);
			InjectDLL();
		}

		if (wParam == btn_undll)
		{
			UninjectDll();
			//MessageBox()
		}
	}

	return FALSE;
}

//第一步,要拿到微信的进程句柄,有句柄才能操作微信内存
//通过微信的进程名称去找到微信pid,然后通过PID去打开微信进程获取到进程句柄
DWORD ProcessNameFindPID(LPCSTR ProcessName)
{
	//第一步获取到整个进程快照
	HANDLE ProcessAll =  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);//获取整个进程快照

	//第二步在快照中对比ProcessName进程名称
	PROCESSENTRY32 processInfo = { 0 };
	processInfo.dwSize = sizeof(PROCESSENTRY32);
	do{
	
		if (strcmp(ProcessName, processInfo.szExeFile) == 0)
		{
			return processInfo.th32ProcessID;
		}
	}
	while(Process32Next(ProcessAll,&processInfo));

	//第三步用找到的PID打开进程得到句柄
	return 0;
}

//第二步,要再微信内部申请一块内存用来放dll的路径
VOID InjectDLL()
{
	CHAR pathStr[0x100] = { DLL_PATH };

	//第一步 我们先获取到微信的句柄
	DWORD PID = ProcessNameFindPID(WECHAT_PROCESS_NAME);
	if (PID == 0)
	{
		MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0);
		return;
	}
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID);
	if (hProcess == NULL)
	{
		MessageBox(NULL, "进程打开失败,可能权限不足或者关闭了应用", "错误", 0);
		return;
	}

	//第二步申请内存,返回写入的地址
	LPVOID dllAdd =  VirtualAllocEx(hProcess, NULL,sizeof(pathStr),MEM_COMMIT,PAGE_READWRITE);
	if (dllAdd == NULL)
	{
		MessageBox(NULL, "内存分配失败", "错误", 0);
		return;
	}

	//写入DLL路径到上面地址
	if (WriteProcessMemory(hProcess, dllAdd, pathStr, strlen(pathStr), NULL) == 0)
	{
		MessageBox(NULL, "路径写入失败", "错误", 0);
		return;
	}

	CHAR test[0x100] = {0};
	sprintf_s(test, "写入的地址为:%p", dllAdd);
	 
	//OutputDebugString(test);              
	HMODULE k32 = GetModuleHandle("Kernel32.dll");

	//LoadlibraryW或LoadlibraryA
	LPVOID loadAdd = GetProcAddress(k32, "LoadLibraryA");

	//通过远程线程执行函数,去执行LoadLiabray这个函数来加载我们写入那个路径的DLL
	HANDLE exec = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadAdd, dllAdd, 0, NULL);

	if (exec == NULL)
	{
		MessageBox(NULL, "远程注入失败", "错误", 0);
	}
	else
	{
		MessageBox(NULL, "远程注入成功", "成功", 0);
	}
}


VOID UninjectDll()
{
	CHAR szDllName[0x100] = { DLL_PATH };

	DWORD dwPid = ProcessNameFindPID(WECHAT_PROCESS_NAME);

	if (dwPid == 0)
	{
		MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0);
		return;
	}

	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);

	MODULEENTRY32 me32;
	me32.dwSize = sizeof(me32);

	//查找匹配的进程名称
	BOOL bRet = Module32First(hSnap, &me32);
	BOOL hasFind = false;
	while (bRet)
	{
		string s = me32.szExePath;
		string::size_type position = s.find("MyCode.Project.MyWeChat");

		//找到
		if (position != s.npos)
		{
			hasFind = true;
			break;
		}
		
		bRet = Module32Next(hSnap, &me32);
	}

	if (!hasFind)
	{
		MessageBox(NULL, "找不到注入的DLL,可能没有注入", "错误", 0);
		return;
	}

	CloseHandle(hSnap);

	char *pFunName = "FreeLibrary";

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);

	if (hProcess == NULL)
	{
		return;
	}

	FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), pFunName);

	HANDLE exec = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunAddr, me32.hModule, 0, NULL);

	if (exec == NULL)
	{
		MessageBox(NULL, "卸载失败", "错误", 0);
	}
	else
	{
		MessageBox(NULL, "卸载成功", "成功", 0);
	}

}


网友讨论