首页 C/C++修行正文

C/C++ 写的CE,进程内存的读取与修改、特征码搜索、DLL注入、获取模块地址

欲儿 C/C++修行 2022-07-10 1827 0

效果图:

image.png

编译环境:Unicode字符集


目录结构:

-----Getmod.h

-----yu.h

-----源.cpp


编译代码:

Getmod.h

#pragma once
// 尝试 将 delphi 翻译成 c++
#include<Windows.h>
#include<Tlhelp32.h>
class TToolhelp
{
public:
	TToolhelp(DWORD dwFlags = 0, DWORD dwProcessID = 0);
	~TToolhelp();
	BOOL CreateSnapshot(DWORD dwFlags, DWORD dwProcessID = 0);
	BOOL ProcessFirst(PPROCESSENTRY32 ppe);
	BOOL ProcessNext(PPROCESSENTRY32 ppe);
	BOOL ProcessFind(DWORD dwProcessId, PPROCESSENTRY32 ppe);
	BOOL ModuleFirst(PMODULEENTRY32 pme);
	BOOL ModuleNext(PMODULEENTRY32 pme);
	BOOL ModuleFind_BaseAddr(void *pvBaseAddr, PMODULEENTRY32 pme);
	BOOL ModuleFind_ModName(WCHAR * pszModName, PMODULEENTRY32 pme);
	BOOL ThreadFirst(PTHREADENTRY32  pte);
	BOOL ThreadNext(PTHREADENTRY32 pte);
	BOOL HeapListFirst(PHEAPLIST32 phl);
	BOOL HeapListNext(PHEAPLIST32 phl);
	int HowManyHeaps();
	BOOL HeapFirst(PHEAPENTRY32 phe, DWORD dwProcessID, DWORD dwHeapID);
	BOOL HeapNext(PHEAPENTRY32 phe);
	int HowManyBlocksInHeap(DWORD dwProcessID, DWORD dwHeapId);
	BOOL IsAHeap(HANDLE hProcess, void * pvBlock, DWORD * pdwFlags);
	BOOL EnableDebugPrivilege(BOOL fEnable = TRUE);
	BOOL ReadProcessMemory(DWORD dwProcessID, void* pvBaseAddress, void* pvBuffer,
		DWORD cbRead, DWORD *pdwNumberOfBytesRead = NULL);
private:
	HANDLE m_hSnapshot;
};
//构造函数
TToolhelp::TToolhelp(DWORD dwFlags, DWORD dwProcessID)
{
	m_hSnapshot = INVALID_HANDLE_VALUE;
	CreateSnapshot(dwFlags, dwProcessID);
}
//析构函数
TToolhelp::~TToolhelp()
{
	if (m_hSnapshot != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hSnapshot);
	}
}
// 建立快照
BOOL TToolhelp::CreateSnapshot(DWORD dwFlags, DWORD dwProcessID)
{
	if (m_hSnapshot != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hSnapshot);
	}
	if (dwFlags == 0)
		m_hSnapshot = INVALID_HANDLE_VALUE;
	else
		m_hSnapshot = CreateToolhelp32Snapshot(dwFlags, dwProcessID);
	return m_hSnapshot != INVALID_HANDLE_VALUE;
}
// 进程枚举
BOOL TToolhelp::ProcessFirst(PPROCESSENTRY32 ppe)
{
	if (Process32First(m_hSnapshot, ppe) && ppe->th32ProcessID == 0)
	{
		return ProcessNext(ppe);
	}
}
BOOL TToolhelp::ProcessNext(PPROCESSENTRY32 ppe)
{
	if (Process32First(m_hSnapshot, ppe) && ppe->th32ProcessID == 0)
	{
		return ProcessNext(ppe);
	}
}
BOOL TToolhelp::ProcessFind(DWORD dwProcessId, PPROCESSENTRY32 ppe)
{
	BOOL R = ProcessFirst(ppe);
	while (R)
	{
		if (ppe->th32ProcessID == dwProcessId)
			break;
		R = ProcessNext(ppe);
	}
	return R;
}
// 模块枚举
BOOL TToolhelp::ModuleFirst(PMODULEENTRY32 pme)
{
	return Module32First(m_hSnapshot, pme);
}
BOOL TToolhelp::ModuleNext(PMODULEENTRY32 pme)
{
	return Module32Next(m_hSnapshot, pme);
}
BOOL TToolhelp::ModuleFind_BaseAddr(void *pvBaseAddr, PMODULEENTRY32 pme)
{
	BOOL R = ModuleFirst(pme);
	while (R)
	{
		if (pme->modBaseAddr == pvBaseAddr)
			break;
		R = ModuleNext(pme);
	}
	return R;
}
BOOL TToolhelp::ModuleFind_ModName(WCHAR *pszModName, PMODULEENTRY32 pme)
{
	BOOL R = ModuleFirst(pme);
	while (R)
	{
		if (lstrcmpi(pme->szModule, pszModName) == 0 ||
			lstrcmpi(pme->szExePath, pszModName) == 0) break;
		R = ModuleNext(pme);
	}
	return R;
}
// 线程枚举
BOOL TToolhelp::ThreadFirst(PTHREADENTRY32 pte)
{
	return Thread32First(m_hSnapshot, pte);
}
BOOL TToolhelp::ThreadNext(PTHREADENTRY32 pte)
{
	return Thread32Next(m_hSnapshot, pte);
}
// 内存枚举
int TToolhelp::HowManyHeaps()
{
	HEAPLIST32 hl;
	BOOL fOK;
	int R = 0;
	hl.dwSize = sizeof(HEAPLIST32);
	fOK = HeapListFirst(&hl);
	while (fOK)
	{
		R++;
		fOK = HeapListNext(&hl);
	}
	return R;
}
int TToolhelp::HowManyBlocksInHeap(DWORD dwProcessID, DWORD dwHeapId)
{
	HEAPENTRY32 he;
	BOOL fOK;
	int	R = 0;
	he.dwSize = sizeof(he);
	fOK = HeapFirst(&he, dwProcessID, dwHeapId);
	while (fOK)
	{
		R++;
		fOK = HeapNext(&he);
	}
	return R;
}
BOOL TToolhelp::HeapListFirst(PHEAPLIST32 phl)
{
	return Heap32ListFirst(m_hSnapshot, phl);
}
BOOL TToolhelp::HeapListNext(PHEAPLIST32 phl)
{
	return Heap32ListNext(m_hSnapshot, phl);
}
BOOL TToolhelp::HeapFirst(PHEAPENTRY32 phe, DWORD dwProcessID, DWORD dwHeapID)
{
	return Heap32First(phe, dwProcessID, dwHeapID);
};
BOOL TToolhelp::HeapNext(PHEAPENTRY32 phe)
{
	return Heap32Next(phe);
}
BOOL TToolhelp::IsAHeap(HANDLE hProcess, void *pvBlock, DWORD *pdwFlags)
{
	HEAPLIST32 hl;
	HEAPENTRY32 he;
	MEMORY_BASIC_INFORMATION  mbi;
	BOOL fOkHL, fOkHE;
	BOOL R = FALSE;
	hl.dwSize = sizeof(HEAPLIST32);
	he.dwSize = sizeof(HEAPENTRY32);
	fOkHL = HeapListFirst(&hl);
	while (fOkHL)
	{
		fOkHE = HeapFirst(&he, hl.th32ProcessID, hl.th32HeapID);
		while (fOkHE)
		{
			VirtualQueryEx(hProcess, &he.dwAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
			if (DWORD(mbi.AllocationBase) <= DWORD(pvBlock) &&
				DWORD(pvBlock) <= DWORD(mbi.AllocationBase) + mbi.RegionSize)
			{
				*pdwFlags = hl.dwFlags;
				R = TRUE;
				return R;
			};
			fOkHE = HeapNext(&he);
		}
		fOkHL = HeapListNext(&hl);
	}
}
// 提升权限
BOOL TToolhelp::EnableDebugPrivilege(BOOL fEnable)
{
	HANDLE	hToken;
	TOKEN_PRIVILEGES  tp;
	BOOL R = FALSE;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		if (fEnable)
			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		else
			tp.Privileges[0].Attributes = 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
		R = GetLastError() == ERROR_SUCCESS;
		CloseHandle(hToken);
	}
	return R;
}
// 内存读取
BOOL TToolhelp::ReadProcessMemory(DWORD dwProcessID, void * pvBaseAddress, void * pvBuffer,
	DWORD cbRead, DWORD *pdwNumberOfBytesRead)
{
	return Toolhelp32ReadProcessMemory(dwProcessID, pvBaseAddress, pvBuffer, cbRead, pdwNumberOfBytesRead);
}

yu.h

#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <Tlhelp32.h>
#include <string>
#include "Getmod.h"
using namespace std;
//参数分别为:进程句柄、特征码、偏移、读取长度、开始扫描位地置、扫描结束位置
uintptr_t hanshu_dizhi; //记录特征码对应的地址
uintptr_t ScanAddress(HANDLE process, char *markCode, int nOffset, unsigned long dwReadLen = 4, uintptr_t StartAddr = 0x400000, uintptr_t EndAddr = 0x7FFFFFFF, int InstructionLen = 0)
{
	//************处理特征码,转化成字节*****************
	if (strlen(markCode) % 2 != 0) return 0;
	//特征码长度
	int len = strlen(markCode) / 2;  //获取代码的字节数

	//将特征码转换成byte型 保存在m_code 中
	BYTE *m_code = new BYTE[len];
	for (int i = 0; i < len; i++)
	{
		//定义可容纳单个字符的一种基本数据类型。
		char c[] = { markCode[i * 2], markCode[i * 2 + 1], '\0' };
		//将参数nptr字符串根据参数base来转换成长整型数
		m_code[i] = (BYTE)::strtol(c, NULL, 16);
	}
	//每次读取游戏内存数目的大小
	const DWORD pageSize = 4096;

	// 查找特征码 /
	//每页读取4096个字节
	BYTE *page = new BYTE[pageSize];
	uintptr_t tmpAddr = StartAddr;
	//定义和特征码一样长度的标识
	int compare_one = 0;

	while (tmpAddr <= EndAddr)
	{
		::ReadProcessMemory(process, (LPCVOID)tmpAddr, page, pageSize, 0); //读取0x400000的内存数据,保存在page,长度为pageSize

		//在该页中查找特征码
		for (int i = 0; i < pageSize; i++)
		{
			if (m_code[0] == page[i])//有一个字节与特征码的第一个字节相同,则搜索
			{
				for (int j = 0; j<len - 1; j++)
				{
					if (m_code[j + 1] == page[i + j + 1])//比较每一个字节的大小,不相同则退出
					{
						compare_one++;
					}
					else
					{
						compare_one = 0;
						break;
					}//如果下个对比的字节不相等,则退出,减少资源被利用
				}

				if ((compare_one + 1) == len)
				{
					// 找到特征码处理
					//赋值时要给初始值,避免冲突
					uintptr_t dwAddr = tmpAddr + i + nOffset;
					uintptr_t ullRet = 0;
					::ReadProcessMemory(process, (void*)dwAddr, &ullRet, dwReadLen, 0);
					//cout<<dwAddr<<endl;
					//这里的dwAddr已经对应的是搜索到的地址
					//地址输出的也是10进制    需要转化为16进制 
					hanshu_dizhi = dwAddr;//记录地址
					if (InstructionLen)
					{
						ullRet += dwAddr + dwReadLen;
					}

					return ullRet;
				}
			}
		}

		tmpAddr = tmpAddr + pageSize - len;//下一页搜索要在前一页最后长度len 开始查找,避免两页交接中间有特征码搜索不出来
	}

	return 0;
}

//10到16 用法在下面
/*
int ret = 10;
string result = tentosixteen(ret);
cout << result << endl;
*/

int quzheng(unsigned int tendoc)
{
	int qian = tendoc / 16;
	return qian;
}

string huanzhi(int numtype)
{
	string us = std::to_string(numtype);
	if (us == "0")
	{
		string result = "0";
		return result;
	}
	else if (us == "1")
	{
		string result = "1";
		return result;
	}
	else if (us == "2")
	{
		string result = "2";
		return result;
	}
	else if (us == "3")
	{
		string result = "3";
		return result;
	}
	else if (us == "4")
	{
		string result = "4";
		return result;
	}
	else if (us == "5")
	{
		string result = "5";
		return result;
	}
	else if (us == "6")
	{
		string result = "6";
		return result;
	}
	else if (us == "7")
	{
		string result = "7";
		return result;
	}
	else if (us == "8")
	{
		string result = "8";
		return result;
	}
	else if (us == "9")
	{
		string result = "9";
		return result;
	}
	else if (us == "10")
	{
		string result = "A";
		return result;
	}
	else if (us == "11")
	{
		string result = "B";
		return result;
	}
	else if (us == "12")
	{
		string result = "C";
		return result;
	}
	else if (us == "13")
	{
		string result = "D";
		return result;
	}
	else if (us == "14")
	{
		string result = "E";
		return result;
	}
	else if (us == "15")
	{
		string result = "F";
		return result;
	}
	else if (us == "16")
	{
		string result = "10";
		return result;
	}
}

string daoxu(string sixteendoc)
{
	int length = strlen(sixteendoc.c_str());
	int i = 0;
	string ret;
	string result;
	while (i < length || i == length)
	{
		ret = sixteendoc.substr(length - i, 1);
		result = result + ret;
		//cout << ret << endl;
		i = i + 1;
	}
	return result;
}

string tentosixteen(unsigned int tendoc)
{
	//int tendoc = 426;
	int zhengshu = quzheng(tendoc);
	string sixteendoc = "";
	while (true)
	{
		if (zhengshu > 16)
		{
			int cha = tendoc - zhengshu * 16;
			tendoc = zhengshu;
			//cout << cha << endl;
			string result = huanzhi(cha);
			sixteendoc = sixteendoc + result;
			zhengshu = quzheng(tendoc);
		}
		else if (zhengshu == 16)
		{
			int cha = tendoc - zhengshu * 16;
			tendoc = zhengshu;
			//cout << cha << endl;
			string result = huanzhi(cha);
			sixteendoc = sixteendoc + result;
			zhengshu = quzheng(tendoc);
		}
		else
		{
			int cha = tendoc - zhengshu * 16;
			tendoc = zhengshu;
			//cout << cha << endl;
			//cout << zhengshu << endl;//最后一个整数也是差值
			string result1 = huanzhi(cha);
			string result2 = huanzhi(zhengshu);
			sixteendoc = sixteendoc + result1 + result2;
			break;
		}
	}
	string oversixdoc = daoxu(sixteendoc);//这个时候sixteendoc是反着的所以倒序倒为正了
	//cout << "oversixdoc:" << oversixdoc << endl;
	int length = strlen(oversixdoc.c_str());
	string tianchong;
	//cout <<"length:"  <<  length << endl;
	int i = 8 - length;
	while (true)
	{
		if (i > 0)
		{
			tianchong = tianchong + "0";
		}
		else
		{
			break;
		}
		i = i - 1;
	}
	//cout << "tianchong" << tianchong << endl;
	string result = tianchong + oversixdoc;
	//string result = tianchong + oversixdoc;
	return result;
}


//16到10 用法在下面
/*
string typesixteen = "ABCDEFAB";
unsigned int result =  sixteentoten(typesixteen);
cout << "结果:" << result << endl;
*/

int beishu(int length)
{
	int ji = 1;
	int length1 = 7 - length;
	int i = 0;
	while (true)
	{
		if (i < length1)
		{
			ji = ji * 16;
		}
		else
		{
			break;
		}
		i = i + 1;
	}
	//cout << "ji : " << ji << endl;
	return ji;
}

int callback(string ret, int i)
{
	unsigned int callback = 1;
	//cout << "i:" << i << "ret" << ret << endl;
	//cout << "beishu : " << beilv << endl;
	if (ret == "0")
	{
		int beilv = beishu(i);
		callback = beilv * 0;
	}
	else if (ret == "1")
	{
		int beilv = beishu(i);
		callback = beilv * 1;
	}
	else if (ret == "2")
	{
		int beilv = beishu(i);
		callback = beilv * 2;
	}
	else if (ret == "3")
	{
		int beilv = beishu(i);
		callback = beilv * 3;
	}
	else if (ret == "4")
	{
		int beilv = beishu(i);
		callback = beilv * 4;
	}
	else if (ret == "5")
	{
		int beilv = beishu(i);
		callback = beilv * 5;
	}
	else if (ret == "6")
	{
		int beilv = beishu(i);
		callback = beilv * 6;
	}
	else if (ret == "7")
	{
		int beilv = beishu(i);
		callback = beilv * 7;
	}
	else if (ret == "8")
	{
		int beilv = beishu(i);
		callback = beilv * 8;
	}
	else if (ret == "9")
	{
		int beilv = beishu(i);
		callback = beilv * 9;
	}
	else if (ret == "A" || ret == "a")
	{
		int beilv = beishu(i);
		callback = beilv * 10;
	}
	else if (ret == "B" || ret == "b")
	{
		int beilv = beishu(i);
		callback = beilv * 11;
	}
	else if (ret == "C" || ret == "c")
	{
		int beilv = beishu(i);
		callback = beilv * 12;
	}
	else if (ret == "D" || ret == "d")
	{
		int beilv = beishu(i);
		callback = beilv * 13;
	}
	else if (ret == "E" || ret == "e")
	{
		int beilv = beishu(i);
		callback = beilv * 14;
	}
	else if (ret == "F" || ret == "f")
	{
		int beilv = beishu(i);
		callback = beilv * 15;
	}
	return callback;
}

int sixteentoten(string ten)
{
	int length = strlen(ten.c_str());
	int i = 0;
	int answer = 0;
	int reback;
	string ret;
	while (true)
	{
		if (i < length)
		{
			ret = ten.substr(i, 1);//获取到了每一个位数上的具体值
			reback = callback(ret, i);
			answer = answer + reback;
		}
		else
		{
			break;
		}
		i = i + 1;
	}



	string result = "1";
	return answer;
}




/*Char*转TCHAR*/
LPWSTR ConvertCharToLPWSTR(const char* szString)

{

	int dwLen = strlen(szString) + 1;

	int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度

	LPWSTR lpszPath = new WCHAR[dwLen];

	MultiByteToWideChar(CP_ACP, 0, szString, dwLen, lpszPath, nwLen);

	return lpszPath;

}

/*string转LPCWSTR*/
LPCWSTR stringToLPCWSTR(std::string orig)
{
	size_t origsize = orig.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
	return wcstring;
}


//DLL注入
/// <summary>
/// 注入DLL文件
/// </summary>
/// <param name="DllFullPath">DLL文件的全路径</param>
/// <param name="dwRemoteProcessId">要注入的程序的PID</param>
/// <returns></returns>
BOOL InjectDLL(const wchar_t* DllFullPath, const DWORD dwRemoteProcessId)
{
	// 计算路径的字节数
	int pathSize = (wcslen(DllFullPath) + 1) * sizeof(wchar_t);
	// 获取句柄后,可以完全控制进程
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId);
	if (hProcess == NULL) {
		//cout << "获取句柄失败" << endl;
		return FALSE;
	}
	// TerminateProcess(hProcess, 0);//关闭句柄对象
	// 实现注入
	// 1.首先要提升权限,打开进程的访问令牌
	// 【参数1】当前程序
	// 【参数2】权限,可添加的权限|可查询的权限
	HANDLE hToken;
	if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
		TOKEN_QUERY, &hToken)) {
		// 权限修改失败
		//cout << "权限修改失败" << endl;
		return FALSE;
	}
	//2.查看与进程相关的特权信息
	LUID luid;
	if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
		// 特权信息查询失败
		//cout << "特权信息查询失败" << endl;
		return FALSE;
	};
	//3.调节进程的访问令牌的特权属性
	// 这几行代码固定不变
	TOKEN_PRIVILEGES tkp;
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Luid = luid;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 打开特权
	// 【参数1】访问令牌
	// 【参数2】是否禁用特权
	// 【参数3】新特权所占的字节数
	// 【参数4】原来的特权是否需要保存
	// 【参数5】原特权的长度
	if (FALSE == AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
	{
		// 提升特权失败
		//cout << "提升特权失败" << endl;
		return FALSE;
	};

	//在远程进程中申请内存空间
	// 【参数1】程序的句柄对象
	// 【参数2】申请的内存地址,由系统分配,所以为NULL
	// 【参数3】申请的内存长度
	// 【参数4】调用物理存储器
	// 【参数5】这块内存可读可写,可执行
	// 【返回】申请到的地址
	LPVOID lpAddr = VirtualAllocEx(hProcess, NULL, pathSize, MEM_COMMIT,
		PAGE_EXECUTE_READWRITE);
	if (lpAddr == NULL) {
		// 在远程进程中申请内存失败
		//cout << "在远程进程中申请内存失败" << endl;
		return FALSE;
	}
	// 把DLL路径写入到远程进程中
	// 强行修改程序的内存
	// 【参数1】程序的句柄
	// 【参数2】申请到的内存首地址
	// 【参数3】写入的内容
	// 【参数4】要写入的字节数
	// 【参数5】
	if (FALSE == WriteProcessMemory(hProcess, lpAddr, DllFullPath,
		pathSize, NULL)) {
		// 在远程进程中写入数据失败
		//cout << "在远程进程中写入数据失败" << endl;
		return FALSE;
	};


	// 调用Kernel32.dll中的LoadLibraryW方法用以加载DLL文件
	PTHREAD_START_ROUTINE pfnStartAssr =
		(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32.dll"),
		"LoadLibraryW");

	// 在远程进程中开辟线程
	// 【参数1】远程线程的句柄
	// 【参数2】线程属性。NULL表示使用默认属性
	// 【参数3】堆栈大小。0代表默认
	// 【参数4】加载DLL文件的对象
	// 【参数5】加载文件的路径
	// 【参数6】延迟时间。0代表立即启动
	// 【参数7】线程ID。为NULL就行了
	HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAssr, lpAddr, 0,
		NULL);
	if (hRemoteThread == NULL) {
		// 创建远程线程失败
		//cout << "创建远程线程失败" << endl;
		// 释放内存
		VirtualFreeEx(hProcess, lpAddr, 0, MEM_FREE);
		return FALSE;
	}
	cout << "注入成功" << endl;
	// 等待线程结束
	WaitForSingleObject(hRemoteThread, -1);
	// 关闭线程
	CloseHandle(hRemoteThread);
	// 释放内存
	VirtualFreeEx(hProcess, lpAddr, 0, MEM_FREE);
}

//const wchar_t* 转 char*
char* WcharToChar(const wchar_t* wc)
{
	char* m_char = NULL;
	delete m_char;
	m_char = NULL;
	int len = WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), NULL, 0, NULL, NULL);
	m_char = new char[len + 1];
	WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), m_char, len, NULL, NULL);
	m_char[len] = '\0';
	return m_char;
}

源.cpp

#include "yu.h"

void retisone()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);
	cout << "请输入内存地址16位:";
	string straddress;
	cin >> straddress;
	string name = "0x" + straddress;
	DWORD address = std::strtoul(name.c_str(), NULL, 16);//转换为DWORD类型变量
	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID
	HANDLE hprocess;
	hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
	DWORD value = 0;//用来存原值是多少
	DWORD size = 0;
	if (false == ReadProcessMemory(hprocess, (void*)address, &value, sizeof(DWORD), &size))
	{
		cout << "读取失败" << endl;
	}
	else
	{
		cout << "当前的值(10进制):" << value << endl;
	}
}

void retistwo()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);
	cout << "请输入内存地址16位:";
	string straddress;
	cin >> straddress;
	cout << "请输入修改为多少值(10进制):";
	string newthing;
	cin >> newthing;
	string name = "0x" + straddress;
	DWORD address = std::strtoul(name.c_str(), NULL, 16);//转换为DWORD类型变量
	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID
	HANDLE hprocess;
	hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
	DWORD value = 0;//用来存原值是多少
	DWORD newvalue = std::strtoul(newthing.c_str(), NULL, 10);//转换为DWORD类型变量
	DWORD size = 0;
	if (false == WriteProcessMemory(hprocess, (void*)address, &newvalue, sizeof(DWORD), &size))
	{
		cout << "修改失败" << endl;
	}
	else
	{
		cout << "修改成功" << endl;
	}
}

void retisthree()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);
	cout << "请输入特征码(如果不行可以试试切换大小写):";
	string special;
	cin >> special;
	char * specialcode = const_cast<char*>(special.c_str());
	cout << "请输入偏移量,如果没有请输入0:";
	int move;
	cin >> move;

	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄

	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID

	HANDLE hprocess;
	hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程

	ScanAddress(hprocess, specialcode, 0);//"获取地址值为多少"  如果输出的地址不对,可以试试特征码的大写和小写的替换
	//cout << hanshu_dizhi << endl;//输出地址(10进制)


	unsigned int num = hanshu_dizhi;
	num = num + move;//相对内存地址偏移量(10进制)
	string oversixdoc = tentosixteen(num);//这里已经转换为了16进制的地址
	cout << "地址为:" << oversixdoc << endl;//输出地址(10进制)
}

void retisfour()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);
	cout << "请输入DLL路径:";
	string path;
	cin >> path;
	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄

	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID
	LPCWSTR  newipath = ConvertCharToLPWSTR(path.c_str());
	InjectDLL(newipath, PID);//这个dll你所要注入的dll文件,这个"数字"是你想注入的进程的PID号
}

void retisfive()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);

	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID
	setlocale(LC_ALL, "chs");
	MODULEENTRY32 meme;
	meme.dwSize = sizeof(MODULEENTRY32);
	BOOL fmOk;
	TToolhelp(NULL).EnableDebugPrivilege(TRUE);
	TToolhelp thModules = TToolhelp(TH32CS_SNAPALL, PID);//进程号
	fmOk = thModules.ModuleFirst(&meme);
	// 模块
	while (true)
	{
		if (fmOk == 1)
		{
			//cout << fmOk << endl;
			//模块
			wprintf(L"模块基址:十进制 %d ,十六进制 0x%x ,模块大小:%d,模块名称:%s\n", meme.modBaseAddr, meme.modBaseAddr, meme.modBaseSize, meme.szModule);
			fmOk = thModules.ModuleNext(&meme);
		}
		else
		{
			cout << "over" << endl;
			break;
		}

	}


	TToolhelp(NULL).EnableDebugPrivilege(FALSE);

}

void retissix()
{
	cin.ignore();
	cout << "请输入窗口标题:";
	string title;
	getline(cin, title);
	cout << "请输入模块名字:";
	string dllname;
	getline(cin, dllname);
	HWND hWnd;
	LPCWSTR  newititle = ConvertCharToLPWSTR(title.c_str());
	hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
	DWORD PID;
	GetWindowThreadProcessId(hWnd, &PID);//存入PID
	//cout << PID << endl;
	setlocale(LC_ALL, "chs");
	MODULEENTRY32 meme;
	meme.dwSize = sizeof(MODULEENTRY32);
	BOOL fmOk;
	TToolhelp(NULL).EnableDebugPrivilege(TRUE);
	TToolhelp thModules = TToolhelp(TH32CS_SNAPALL, PID);//进程号
	fmOk = thModules.ModuleFirst(&meme);

	while (true)
	{
		if (fmOk == 1)
		{
			//cout << fmOk << endl;
			//模块
			//wprintf(L"模块基址:十进制 %d ,十六进制 0x%x ,模块大小:%d,模块名称:%s\n", meme.modBaseAddr, meme.modBaseAddr, meme.modBaseSize, meme.szModule);
			const wchar_t * havedll;
			havedll = meme.szModule;
			char * chhacedll = WcharToChar(havedll);
			string strhavedll = chhacedll;
			if (strhavedll == dllname)
			{
				unsigned char * sixaddr = meme.modBaseAddr;
				void * addrofwant = meme.modBaseAddr;
				int addr = (int)addrofwant;
				string addrresult = tentosixteen(addr);
				cout << "该模块地址(16进制):" << addrresult << endl;
				break;
			}

			// 下一模块
			fmOk = thModules.ModuleNext(&meme);
		}
		else
		{
			cout << "over" << endl;
			break;
		}

	}



	TToolhelp(NULL).EnableDebugPrivilege(FALSE);

}

void niceui()
{
	cout << "---------Ece程序介绍---------" << endl;
	cout << "----1.读取某进程某地址数据---" << endl;
	cout << "----2.修改某进程某地址数据---" << endl;
	cout << "----3.特征码搜索地址---------" << endl;
	cout << "----4.DLL注入----------------" << endl;
	cout << "----5.获取程序所有模块地址---" << endl;
	cout << "----6.获取程序特定模块地址---" << endl;
	cout << "----7.刷新屏幕内容-----------" << endl;
	cout << "----8.加入QQ群:614815597-----\n\n" << endl;
}

int main()
{
	niceui();
	int ret;
	while (true)
	{
		cout << "你的指令是:";
		cin >> ret;
		if (ret == 1)//根据窗口标题读取某进程的某个地址
		{
			retisone();
		}
		else if (ret == 2)//根据窗口标题修改某个进程的某个地址
		{
			retistwo();
		}
		else if (ret == 3)//特征码搜索
		{
			retisthree();
		}
		else if (ret == 4)//dll注入
		{
			retisfour();
		}
		else if (ret == 5)//获取程序所有模块地址
		{
			retisfive();
		}

		else if (ret == 6)//获取程序特定模块地址
		{
			retissix();
		}
		else if (ret == 7)//清屏
		{
			system("cls");
			niceui();
		}
		else if (ret == 8)//加入Q群
		{
			cout << "请你手动加群啦哈哈哈。官方Q群:614815597" << endl;
		}
		else
		{
			cout << "这是一个无法辨析命令" << endl;
		}
	}

	while (true);
}

如果你实在看不懂,只想要源码和已经编译好的软件


源码链接: https://pan.baidu.com/s/14MgQYNLqoMb3jRkWzBw9Yg?pwd=npn5 提取码: npn5 复制这段内容后打开百度网盘手机App,操作更方便哦

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

评论