操作系统与网络 2019-1-30

深入解析任务管理器的内存搜索与修改功能
本文详细介绍了如何在任务管理器中实现内存搜索和修改功能。从给第一次搜索按钮添加事件处理函数,到实现内存查找、显示查找结果、第二次查找功能,再到设计修改内存值的函数,最后涵盖清空操作。通过C++编程实现,包括对进程地址空间的读取和写入,以及利用链表存储查找结果。

1.继续任务管理器

1.1 给 第一次搜索 按钮添加事件处理函数 CTaskManagerDlg::OnBnClickedButton5 ;

1.给 CModifyMemory 类添加函数: void FirstFind(DWORD nFindValue) ; void FindOnePage(DWORD dwPageBeginAddr, DWORD nFindValue) ;
2.在 void FirstFind(DWORD nFindValue) 函数中首先查找虚拟空间中前2GB的地址,定义查找的起始位置: DWORD dw_begin_addr = 64 * 1024 ;
3.定义查找结束的地址: ULONG dw_end_addr = (ULONG)(2UL * 1024UL * 1024UL * 1024UL) ;
4.定义一页的大小: DWORD dw_one_page = 4096 ;
5.开始查找

void CModifyMemory::FirstFind(DWORD nFindValue)
{
	DWORD dw_begin_addr = 64 * 1024;					// 开始查找的地址
	ULONG dw_end_addr = (ULONG)(2UL * 1024UL * 1024UL * 1024UL);			// 结束查找的地址
	DWORD dw_one_page = 4096;							// 一页的大小

	// 进行一页一页地查找
	for(; dw_begin_addr<dw_end_addr; dw_begin_addr+=dw_one_page)
		this->FindOnePage(dw_begin_addr, nFindValue);
}

6.完成 FindOnePage 函数,首先用一个数组来存储查找到的内容: DWORD sz_buffer[1024] = {0} ;
7.读进程地址空间的内容,读失败则返回: if(0 == ::ReadProcessMemory(m_hOpenPracess, (LPCVOID)dwPageBeginAddr, (LPVOID)sz_buffer, 4096, 0)) return ;
8.读取成功则查找偏移量,创建一个成员 list m_lst_addr 来存储与查找值相同的地址;

// 读取一页的内容
void CModifyMemory::FindOnePage(DWORD dwPageBeginAddr, DWORD nFindValue)
{
	// 用一个数组来存储读到的内容
	DWORD sz_buffer[1024] = {0};
	
	// 读进程地址空间的内容
	// 读取失败则返回
	if(0 == ::ReadProcessMemory(m_hOpenPracess, (LPCVOID)dwPageBeginAddr, (LPVOID)sz_buffer, 4096, 0))
		return;
	// 读取成功则查找偏移量
	for(int i=0; i<1024; i++)
	{
		if(sz_buffer[i] == nFindValue)
		{
			// 将其地址插入到链表中
			m_lst_addr.push_back(dwPageBeginAddr + i * 4);
		}
	}
}

1.2 给 CModifyMemory 类添加函数 ShowAllAddr

1.该函数的功能就是在右侧的 List 控件中显示与要查找值相同的地址;
2.遍历 m_lst_addr 中的元素,并在 List 控件中显示地址;

void CModifyMemory::ShowAllAddr(CListCtrl* pListCtrl)
{
	list<DWORD>::iterator ite = m_lst_addr.begin();
	while (ite != m_lst_addr.end())
	{
		CString str_addr;
		str_addr.Format(L"%d", (*ite));
		pListCtrl->InsertItem(pListCtrl->GetItemCount(), str_addr);
		++ite;
	}
}

3.在 第一次查找 按钮中进行调用该函数

// 第一次查找按钮
void CTaskManagerDlg::OnBnClickedButton5()
{
	m_ls_showaddr.DeleteAllItems();
	// 取得要查找的值
	UpdateData(TRUE);

	// 开始查找
	mm.FirstFind(m_dw_findvalue);
	if(mm.m_lst_addr.empty() == false)
	{
		// 将所有查找结果进行显示
		mm.ShowAllAddr(&m_ls_showaddr);
	}
}

1.3 完成 第二次查找 按钮的消息处理函数

1.给类 CModifyMemory 添加一个 void SecondFind(DWORD nFindValue) 函数;
2.在该函数中,我们首先遍历存储第一次查找结果的链表,其次读取每个地址的值,读取成功则与第二次要查找的值进行比较,否则删除链表中的节点;

void CModifyMemory::SecondFind(DWORD nFindValue)
{
	list<DWORD>::iterator ite = m_lst_addr.begin();
	while (ite != m_lst_addr.end())
	{
		// 读取4个字节
		DWORD n_value = 0;
		if(::ReadProcessMemory(m_hOpenPracess, (LPCVOID)(*ite), (LPVOID)&n_value, 4, 0) == TRUE)
		{
			// 读取成功则判断是不是要找的值
			if(n_value != nFindValue)
			{
				// 若不是要查找的值,则删除这个节点
				ite = m_lst_addr.erase(ite);
			}
			else
			{
				++ite;
			}
		}
		else
		{
			// 读取失败也要删除该节点
			ite = m_lst_addr.erase(ite);
		}
	}
}

3.在 第二次查找 按钮的消息处理函数中调用上述函数;

// 第二次查找按钮
void CTaskManagerDlg::OnBnClickedButton6()
{
	m_ls_showaddr.DeleteAllItems();
	// 取得要查找的值
	UpdateData(TRUE);

	// 开始查找
	mm.SecondFind(m_dw_findvalue);
	if(mm.m_lst_addr.empty() == false)
	{
		// 将所有查找结果进行显示
		mm.ShowAllAddr(&m_ls_showaddr);
	}
}

1.4 修改钱币的值

1.在 CModifyMemory 类中添加一个 bool ModifyMemory(DWORD mModifyAddr, DWORD mModifyValue) 函数;
2.在 CModifyMemory::ModifyMemory 函数中进行写内存的操作;

bool CModifyMemory::ModifyMemory(DWORD mModifyAddr, DWORD mModifyValue)
{
	if(::WriteProcessMemory(m_hOpenPracess, (LPVOID)mModifyAddr, (LPCVOID)&mModifyValue, 4, 0) == TRUE)
	{
		return true;
	}
	else
	{
		return false;
	}
}

3.在 修改 按钮处进行调用该函数;

// 修改值的按钮
void CTaskManagerDlg::OnBnClickedButton8()
{
	// 取得要查找的值
	UpdateData(TRUE);
	if(mm.ModifyMemory(m_dw_changeaddr, m_dw_changevalue) == true)
	{
		MessageBox(L"修改成功");
	}
	else
	{
		MessageBox(L"修改失败");
	}
}

1.5 清空 按钮

// 清空 按钮
void CTaskManagerDlg::OnBnClickedButton7()
{
	// 清空链表
	mm.m_lst_addr.clear();
	m_ls_showaddr.DeleteAllItems();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值