吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1250|回复: 14
收起左侧

[求助] 各位老师,C++代码输出出现如下错误提示,是啥原因呢??

[复制链接]
jtwc 发表于 2022-4-20 12:02
各位老师,C++代码输出出现如下错误提示,是啥原因呢?谢谢了
1.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wuai习 发表于 2022-4-20 12:07
提示已经指明了:vector subscript out of range,超出存储范围,越界。
xfmjn 发表于 2022-4-20 12:13
seawaycao 发表于 2022-4-20 12:16
 楼主| jtwc 发表于 2022-4-20 12:33
wuai习 发表于 2022-4-20 12:07
提示已经指明了:vector subscript out of range,超出存储范围,越界。

谢谢老师,源码如下,如何修改呢?谢谢了
[C++] 纯文本查看 复制代码
#include <Windows.h>

#include <tchar.h>

#include <stdio.h>

#include <Psapi.h>

#include <iostream>

#include <vector>

#include <string>

#include <map>

#include <ctime>



using namespace std;


/// 字符转字节

int ctoh(char hex)

{

	if (hex >= '0' && hex <= '9') return hex - '0';

	if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10;

	if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10;

	return 0;

}



/// 十六进制字符串转字节数组

std::vector<BYTE> HexStringToBytes(std::string str)

{

	std::vector<BYTE> Bytes;

	for (SIZE_T i = 0; i < str.size(); i++)

	{

		if (str[i] == ' ')

		{

			continue;

		}

		if (str[i] == '?')

		{

			Bytes.insert(Bytes.end(), '?');

			// 兼容OD模式的特征码

			if (str[i + 1] == '?')

				i++;

		}

		else if (str[i] == '*') {

			Bytes.insert(Bytes.end(), '*');

		}

		else {

			Bytes.insert(Bytes.end(), 0x10 * ctoh(str[i]) + ctoh(str[i + 1]));

			i++;

		}

	}

	return Bytes;

}

// 获取进程模块句柄

HMODULE GetProcessModuleHandle(DWORD ProcessId, CONST TCHAR* ModuleName)

{

	HMODULE hMods[1024];

	DWORD cbNeeded;

	TCHAR szModName[MAX_PATH];
	

	HANDLE ProcessHandle = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
	

	if (EnumProcessModulesEx(ProcessHandle, hMods, sizeof(hMods), &cbNeeded, 0x1))

	{

		for (size_t i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)

		{
			
			GetModuleFileNameEx(ProcessHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR));

			if (_tcscmp(szModName, ModuleName)) {

				return hMods[i];

			}

		}

	}

	CloseHandle(ProcessHandle);

	return NULL;

}



// 读字节数组

std::vector<BYTE> ReadBytes(HANDLE ProcessHandle, DWORD_PTR Address, SIZE_T Size)

{

	std::vector<BYTE> Bytes = {};

	Bytes.resize(Size);

	BYTE* Buffer = new BYTE[Size];

	// HANDLE ProcessHandle = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);

	ReadProcessMemory(ProcessHandle, (LPCVOID)Address, Buffer, Size, NULL);

	for (size_t i = 0; i < Size; i++)

	{

		Bytes[i] = Buffer[i];

	}

	delete[]Buffer;

	// CloseHandle(ProcessHandle);

	return Bytes;

}

// 用来保存模块内存数据

static std::map<CONST TCHAR*, std::map<DWORD_PTR, std::vector<BYTE>>> g_ModuleMemorys;


//256 表示 0x00~0xff 特征码长度不要超过 256

static int maxByteSize = 256;

static int shift[256] = { 0 };

long Sunday(std::vector<byte> T, std::vector<byte> P)

{

	int n = T.size();

	int m = P.size();
	
	// 默认值,移动m+1位 256 表示 0x00~0xff

	for (int i = 0; i < maxByteSize; i++) {

		shift[i] = m + 1;

	}

	// 模式串P中每个字母出现的最后的下标

	// 所对应的主串参与匹配的最末位字符的下一位字符移动到该位,所需要的移动位数

	for (int i = 0; i < m; i++) {

		shift[P[i]] = m - i;

	}

	// 模式串开始位置在主串的哪里

	int s = 0;

	// 模式串已经匹配到的位置

	int j;

	while (s <= n - m) {

		j = 0;

		while (P[j] == '*' || P[j] == '?' || T[s + j] == P[j]) {

			j++;

			// 匹配成功

			if (j >= m) {

				return s;

			}

		}

		// 找到主串中当前跟模式串匹配的最末字符的下一个字符

		// 在模式串中出现最后的位置

		// 所需要从(模式串末尾+1)移动到该位置的步数

		s += shift[T[s + m]];

	}

	return -1;

}



DWORD_PTR FindFeatureCode(DWORD ProcessId, CONST TCHAR* ModuleName, std::string FeatureCodeString)

{

	DWORD_PTR Address = 0;

	DWORD_PTR BeginAddress = 0;

	DWORD_PTR EndAddress = 0;

	HANDLE ProcessHandle = NULL;

	MODULEINFO ModuleInfo;

	MEMORY_BASIC_INFORMATION mbi;

	std::map<DWORD_PTR, std::vector<BYTE>> Memorys;

	std::map<DWORD_PTR, std::vector<BYTE>>::iterator it;
	
	std::vector<BYTE> FeatureCode = HexStringToBytes(FeatureCodeString);
	
	// 这里获取模块内存信息 

	if (g_ModuleMemorys.find(ModuleName) == g_ModuleMemorys.end())

	{

		//printf("%s\n", "123456");

		ProcessHandle = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);



		GetModuleInformation(ProcessHandle, GetProcessModuleHandle(ProcessId, ModuleName), &ModuleInfo, sizeof(ModuleInfo));



		BeginAddress = (DWORD_PTR)ModuleInfo.lpBaseOfDll;

		EndAddress = (DWORD_PTR)ModuleInfo.lpBaseOfDll + ModuleInfo.SizeOfImage;



		while (BeginAddress <= EndAddress)

		{

			::VirtualQueryEx(ProcessHandle, (LPCVOID)BeginAddress, &mbi, sizeof(mbi));



			if (mbi.Protect != 1 && mbi.Protect != 16 && mbi.Protect != 512 && mbi.RegionSize > 1)

			{



				g_ModuleMemorys[ModuleName].insert(std::pair<DWORD_PTR, std::vector<BYTE>>(BeginAddress, ReadBytes(ProcessHandle, BeginAddress, mbi.RegionSize)));

			}



			BeginAddress += mbi.RegionSize;

		}

		CloseHandle(ProcessHandle);

	}



	Memorys = g_ModuleMemorys[ModuleName];



	it = Memorys.begin();



	while (it != Memorys.end())

	{

		long offset = Sunday(it->second, FeatureCode);

		if (offset >= 0)

		{

			Address = it->first + offset;

			goto _exit;

		}

		it++;

	}
	
_exit:

	return Address;

}



int main(int argc, char const* argv[])

{

	clock_t startTime, endTime;

	startTime = clock();//计时开始
	
	// 特征码字符串格式随意  这里是拿网易的有道词典测试的

	ULONG address = 0;//2332, "PlantsVsZombies.exe", " AF 00 00 00 14 00 00 00 C5 15 "
	
	address = FindFeatureCode(2332, "PlantsVsZombies.exe", "3E A0 ?? ?? ?? ?? 3E AC 3E B0 ?? B4 ?? B8 ?? ?? ?? ?? 3E C4 3E C8 3E CC ?? D0 3E D4 ?? D8 3E DC 3E E0 ?? E4 ?? E8 ?? ?? ?? ??  ");
	
	printf("address %x\n", address);
	
	endTime = clock();//计时结束

	printf("运行时间: %f/s\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);

	system("pause");

	return 0;
}


tony666 发表于 2022-4-20 14:25
直接调试运行,报错时候看堆栈,定位到自己的代码,就看出来为什么了
图里这个报错是vector越界
wuai习 发表于 2022-4-20 14:44
jtwc 发表于 2022-4-20 12:33
谢谢老师,源码如下,如何修改呢?谢谢了
[C++] 纯文本查看 复制代码
#include 

#include 
[/quote]

[mw_shl_code=cpp,true]std::vector<BYTE> ReadBytes(HANDLE ProcessHandle, DWORD_PTR Address, SIZE_T Size)

{

    std::vector<BYTE> Bytes = {};

    Bytes.resize(Size);

    BYTE* Buffer = new BYTE[Size];



DWORD_PTR FindFeatureCode(DWORD ProcessId, CONST TCHAR* ModuleName, std::string FeatureCodeString)

{

while (BeginAddress <= EndAddress)

        {

            ::VirtualQueryEx(ProcessHandle, (LPCVOID)BeginAddress, &mbi, sizeof(mbi));



            if (mbi.Protect != 1 && mbi.Protect != 16 && mbi.Protect != 512 && mbi.RegionSize > 1)

            {


                g_ModuleMemorys[ModuleName].insert(std::pair<DWORD_PTR, std::vector<BYTE>>(BeginAddress, ReadBytes(ProcessHandle, BeginAddress, mbi.RegionSize)));

            }


我这边看到的是,你这个mbi.RegionSize的大小是int类型的最大值,ReadBytes函数传入了这个参数作为size,可能是这一块儿导致的,具体原因你自己在调试分析一下。
 楼主| jtwc 发表于 2022-4-20 15:14
wuai习 发表于 2022-4-20 14:44
[mw_shl_code=cpp,true]std::vector ReadBytes(HANDLE ProcessHandle, DWORD_PTR Address, SIZE_T Size)
...

谢谢了,老师,好像是下图红线部分报错,如何改呢?
1.png
wuai习 发表于 2022-4-20 15:55
我查了一下你这个源代码是CSDN上的吧,这个大体思路是对的。
但是由于MEMORY_BASIC_INFORMATION的大小实在是太大了,用readbyte这个函数,这里的size超出了设定。
你可以参考一下这篇文章https://www.cnblogs.com/LyShark/p/15019490.html
采用分割内存的方式进行读取。
hl_ke 发表于 2022-4-20 16:07
没有那么复杂,仔细看下面两行代码
for (SIZE_T i = 0; i < str.size(); i++)

Bytes.insert(Bytes.end(), 0x10 * ctoh(str[i]) + ctoh(str[i + 1]));

str下标已经变成了 str[str.size()],很明显的越界访问。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 14:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表