各位老师,C++代码输出出现如下错误提示,是啥原因呢??
各位老师,C++代码输出出现如下错误提示,是啥原因呢?谢谢了 提示已经指明了:vector subscript out of range,超出存储范围,越界。 嗯,越界访问。 越界了。是不是定义的空间不够。 wuai习 发表于 2022-4-20 12:07提示已经指明了:vector subscript out of range,超出存储范围,越界。
谢谢老师,源码如下,如何修改呢?谢谢了#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 == ' ')
{
continue;
}
if (str == '?')
{
Bytes.insert(Bytes.end(), '?');
// 兼容OD模式的特征码
if (str == '?')
i++;
}
else if (str == '*') {
Bytes.insert(Bytes.end(), '*');
}
else {
Bytes.insert(Bytes.end(), 0x10 * ctoh(str) + ctoh(str));
i++;
}
}
return Bytes;
}
// 获取进程模块句柄
HMODULE GetProcessModuleHandle(DWORD ProcessId, CONST TCHAR* ModuleName)
{
HMODULE hMods;
DWORD cbNeeded;
TCHAR szModName;
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, szModName, sizeof(szModName) / sizeof(TCHAR));
if (_tcscmp(szModName, ModuleName)) {
return hMods;
}
}
}
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;
// HANDLE ProcessHandle = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
ReadProcessMemory(ProcessHandle, (LPCVOID)Address, Buffer, Size, NULL);
for (size_t i = 0; i < Size; i++)
{
Bytes = Buffer;
}
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 = { 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 = m + 1;
}
// 模式串P中每个字母出现的最后的下标
// 所对应的主串参与匹配的最末位字符的下一位字符移动到该位,所需要的移动位数
for (int i = 0; i < m; i++) {
shift] = m - i;
}
// 模式串开始位置在主串的哪里
int s = 0;
// 模式串已经匹配到的位置
int j;
while (s <= n - m) {
j = 0;
while (P == '*' || P == '?' || T == P) {
j++;
// 匹配成功
if (j >= m) {
return s;
}
}
// 找到主串中当前跟模式串匹配的最末字符的下一个字符
// 在模式串中出现最后的位置
// 所需要从(模式串末尾+1)移动到该位置的步数
s += shift];
}
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.insert(std::pair<DWORD_PTR, std::vector<BYTE>>(BeginAddress, ReadBytes(ProcessHandle, BeginAddress, mbi.RegionSize)));
}
BeginAddress += mbi.RegionSize;
}
CloseHandle(ProcessHandle);
}
Memorys = g_ModuleMemorys;
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;
}
直接调试运行,报错时候看堆栈,定位到自己的代码,就看出来为什么了
图里这个报错是vector越界 jtwc 发表于 2022-4-20 12:33
谢谢老师,源码如下,如何修改呢?谢谢了#include
#include
std::vector<BYTE> ReadBytes(HANDLE ProcessHandle, DWORD_PTR Address, SIZE_T Size)
{
std::vector<BYTE> Bytes = {};
Bytes.resize(Size);
BYTE* Buffer = new BYTE;
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.insert(std::pair<DWORD_PTR, std::vector<BYTE>>(BeginAddress, ReadBytes(ProcessHandle, BeginAddress, mbi.RegionSize)));
}
我这边看到的是,你这个mbi.RegionSize的大小是int类型的最大值,ReadBytes函数传入了这个参数作为size,可能是这一块儿导致的,具体原因你自己在调试分析一下。 wuai习 发表于 2022-4-20 14:44
std::vector ReadBytes(HANDLE ProcessHandle, DWORD_PTR Address, SIZE_T Size)
...
谢谢了,老师,好像是下图红线部分报错,如何改呢? 我查了一下你这个源代码是CSDN上的吧,这个大体思路是对的。
但是由于MEMORY_BASIC_INFORMATION的大小实在是太大了,用readbyte这个函数,这里的size超出了设定。
你可以参考一下这篇文章https://www.cnblogs.com/LyShark/p/15019490.html
采用分割内存的方式进行读取。 没有那么复杂,仔细看下面两行代码
for (SIZE_T i = 0; i < str.size(); i++)
Bytes.insert(Bytes.end(), 0x10 * ctoh(str) + ctoh(str));
str下标已经变成了 str,很明显的越界访问。
页:
[1]
2