Win32 API(使用定时器 挂接主线程)

上一篇文章介绍了DLL注入的方法,本次的实验内容是向游戏中注入我们自己的DLL,在游戏中有很多线程,每个线程的内存是不同的,所以读取内存的时候,一定要确定 读的是哪个线程的内存,注入的时候也需要注意,我们使用定时器的方法,将DLL注入到主线程

找到我们需要调用的函数地址

	__asm
	{
		push avg1
		call wow.60c1f0
		add esp, 4
		mov res, eax
	}

准备DLL

//MFC_DLL.cpp

//显示我的窗口
DWORD WINAPI showmywindow(LPVOID arg)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CPAGE0 p0;			//创建一个窗口
	p0.DoModal();		//以模态方式显示窗口
	return 0;
}

BOOL CMFCDLLApp::InitInstance()
{
	CWinApp::InitInstance();
	//新起一个线程 防止主线程卡死
	::CreateRemoteThread(GetCurrentProcess(),0,0,showmywindow,0,0,0);
	return TRUE;
}
//CPAGE0.cpp

//读取四字节的内存地址
int R4(UINT_PTR paddr)
{
	HWND hwindow = FindWindowA("GxWindowClassD3d", "魔兽世界");
	DWORD pid = 0, tid = 0;
	tid = GetWindowThreadProcessId(hwindow,&pid);
	HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS,0,pid);
	unsigned int res = 0;
	ReadProcessMemory(hp,(LPCVOID)paddr,&res,4,0);
	return res;
}

//定时器回调函数
VOID CALLBACK time_fun(HWND h, UINT arg2, UINT_PTR arg3_id, DWORD time)
{
	KillTimer(h, 1111); // 关闭定时器 不然会每毫秒执行一次

	//获取主线程ID  
	DWORD main_THid = GetCurrentThreadId();
	printf("主线程id:%d \n", main_THid);
	const char* avg1 = "player";
	UINT_PTR hujia_base = 0;
	UINT_PTR get_hujia = 0x60C1F0;

    //调用游戏中的函数
	__asm
	{
		push avg1
		call get_hujia
		add esp, 4
		mov hujia_base, eax
	}

	//读取四个字节
	DWORD hujia = R4(R4(hujia_base + 0xD0) + 0x174);
	printf("护甲值为%d \n",hujia);
}

//获取护甲按钮
void CPAGE0::OnBnClickedButton1()
{
	HWND hwindow = FindWindowA("GxWindowClassD3d","魔兽世界");
	printf("窗口句柄:%p \n", hwindow);

	//使用计时器 将DLL挂在主线程上
	::SetTimer( hwindow			//窗口句柄
				,1111			//定时器ID  随便给一个就行
				,1				//每隔1毫秒执行一次 time_fun
				,time_fun );    //回调函数
}

//显示控制台按钮
void CPAGE0::OnBnClickedButton2()
{
	AllocConsole();
    //输出重定向到控制台  CONOUT$=控制台屏幕输出
    FILE *pfile = NULL;
	freopen_s(&pfile,"CONOUT$","w+t",stdout);
}

注入程序

int main()
{
	char wind_title[] = "魔兽世界";
	char DLL_PATH[] = "D:\\CODE\\YJX\\030\\mfc\\MFC_DLL\\Debug\\MFC_DLL.dll";
	//根据窗口标题 找到窗口句柄
	HWND h = FindWindowA(NULL, wind_title); 
	printf("窗口句柄为:%p \n",h);

	//根据窗口句柄 找到进程PID
	DWORD PID = 0;
	GetWindowThreadProcessId(h,&PID); //结果写入PID  第二个参数为输出参数
	printf("进程PID:%d \n",PID);

	//获取目标进程的权限
	HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS,0,PID);  

	//在目标进程中分配内存空间
	void* mem = VirtualAllocEx(ph,NULL,4*1024,MEM_COMMIT,0x40);
	printf("分配内存:%d \n", mem);

	//向目标进程注入DLL
	bool ret = WriteProcessMemory(ph, mem, DLL_PATH,0x300,0);
	printf("注入结果:%d \n", ret);

	//调用注入的代码
	CreateRemoteThread(ph,0,0,(LPTHREAD_START_ROUTINE)LoadLibraryA, mem,0,0);//LoadLibraryA 为  DLL 的地址,也是线程被创建之后 所要执行的内容
	printf("调用完成 \n");

	getchar();
	return 0;
}

结果展示

Win32 API(使用定时器 挂接主线程)_第1张图片

 

你可能感兴趣的:(Win32API,mfc,c++,windows)