从零开始学习破解(第四天)

发布于 2022-04-27  58 次阅读 百度未收录


前面已经解决了调用敌人的功能,以及让敌人调用我们的功能。

其实到这里基本上就没啥可以搞得了,只剩下实战了。

不过前面找地址都是依赖vs,实战中就比较麻烦,所以今天解决一下代码搜索的问题。

前面已经了解到,我们可以通过ReadProcessMemory来读取代码区的内容。

那么只需要写个循环查找就好啦。

#include <Psapi.h>

BOOL strToByte(const char* pStr, BYTE* pByte)
{
	int nLen = strlen(pStr);
	// 必须是偶数mx
	if (nLen % 2 || nLen == 0)
	{
		return FALSE;
	}
	memset(pByte, 0, nLen/2);
	for (int i = 0; i < nLen; i++)
	{
		int a = 0;
		if (pStr[i] < 58)
		{
			a += pStr[i] - '0';
		}
		else
		{
			a += pStr[i] - 'A' + 10;
		}

		if (i % 2 == 0)
		{
			a *= 16;
			pByte[i / 2] = a;
		}
		else
		{
			pByte[i / 2] += a;
		}
	}
	return TRUE;
}


DWORD findaddr(const char *pModuleName, const char *pToken)
{
	HMODULE hModule = GetModuleHandle(pModuleName);
	if (!hModule)
	{
		return FALSE;
	}

	MODULEINFO dllInfo = { 0 };
	GetModuleInformation(GetCurrentProcess(), hModule, &dllInfo, sizeof(dllInfo));
	DWORD dwSize = dllInfo.SizeOfImage;
	DWORD dwBaseAddr = (DWORD)hModule;

	// 转化特征码 每2个是一个十六进制
	int nLen = strlen(pToken);
	BYTE* pByte = new BYTE[nLen / 2];
	strToByte(pToken, pByte);

	BYTE *pMemoryData = new BYTE[1024];
	while (dwBaseAddr < ((DWORD)hModule + dwSize))
	{
		// 读取内容
		SIZE_T sReadSize = 0;
		ReadProcessMemory(GetCurrentProcess(), (LPVOID)(dwBaseAddr), pMemoryData, 1024, &sReadSize);
		
		if (sReadSize <= 0)
		{
			break;
		}

		BYTE* pPos = (BYTE*)pMemoryData;
		BYTE* pEnd = pPos + sReadSize - nLen / 2;
		while (pPos <= pEnd)
		{
			bool bFind = true;
			for (int i = 0; i < nLen / 2; ++i)
			{
				if (pPos[i] != pByte[i])
				{
					bFind = false;
					break;
				}
			}
			if (bFind)
			{
				DWORD dwRes = (DWORD)dwBaseAddr + (pPos - pMemoryData);
				delete[]pMemoryData;
				delete[]pByte;
				return dwRes;
			}
			pPos++;
		}

		dwBaseAddr += 1024 - nLen/2;
	}
	
	delete[]pMemoryData;
	delete[]pByte;
	return 0;  
}

然后使用方式如下:

	const char* pToken = "83C001A35C632C016A048D4DDCE89C62FDFF8D4DDCE8BAE8FBFFC745FC000000008D45DC5068E80300008B4DE8E85A85FCFF6890151E018D45DC50E8C769FCFF83C4080FB6C885C9745F6A048D4DD0E85A62FDFF8D4DD0";

	DWORD x = findaddr("login.exe", pToken);
	if (x == 0)
	{
		MessageBox(0, "查找特征码失败!", "报告主人", NULL);
		return 0;
	}
	else
	{
		char szmsg[64];
		sprintf_s(szmsg,64, "地址为%X", x);
		MessageBox(0, szmsg, "报告主人", NULL);
	}
	ModMemory2(x + 45);

其中pToken 是从OD中抓取的,直接复制二进制,然后去掉空格就可以用了。

x+45是因为需要的地址,在特征码中的45位

F3试一下,没有问题。

地址正确且功能正确。

好啦,我要找工作去了。


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。