在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?

Adding memory allocation and memset after a prior call to string::find causes it to return npos. Why?

本文关键字:内存 npos 为什么 返回 find string 调用 添加 在先前 分配      更新时间:2023-10-16

我正在对一款名为《怪物猎人世界》的游戏进行逆向工程,以添加更好的鼠标处理子程序,我的软件中弹出了一个非常奇怪的错误。我不知道究竟是什么原因造成的,但我可以解释一些症状,我强烈怀疑内存损坏。

当我在包含 MonsterHunterWorld 的整个二进制文件的字符串上使用string::find来查找保护机制的字节模式时.exe会出现此问题,该保护机制对文件进行校验和,并在检测到任何修改时故意使程序崩溃。直到最近对我的代码进行了更改,我的软件能够成功找到这些字节模式,对我的代码的以下更改导致string::find函数失败:

char buffer2[5000];
memset(buffer2, 0, sizeof(buffer2));

这是在调用 find 函数之后。如果我从程序中删除它,它会按预期工作(对 string::find 的调用正确找到我搜索的字节模式(。

作为参考,该程序的整个源代码可以在此粘贴箱中找到- https://pastebin.com/7ExgmXNZ

我检查出的其他事情是我决定在 x64dbg 中打开软件,我发现我使用 string::find 搜索的模式实际上在它正在搜索的字符串中,但由于某种原因它还是失败了。

源代码使用 64 位 MingW 版本 8.1.0 编译

编辑:将pastebin更改为重现问题所需的最少代码

更新:我能够为我的特定程序解决问题,但我不满意,因为我不完全理解为什么解决方案有效。在我作为string::findstr参数提供的 char 数组的末尾,我手动添加一个 null 终止0x00。AFAIK 字符数组初始化如下:

char foo[] = {0x68, 0x69}; //"hi"

应该自动添加空终止符吗?如果这是不正确的,请有人纠正我,因为这对我来说是一个非常严重的错误,这意味着该程序之前工作的唯一原因是运气好,与我的字符数组相邻的内存恰好是0x00。

事实证明,发生这种情况的原因是string::find(const CharT* str, size_type pos = 0 );期望str参数有一个空终止符,而我认为我的 char 数组会自动得到一个。

事实并非如此,它之前工作的原因完全是由于运气,相邻内存被0x00,现在我更改了代码,相邻内存更改为0x40并导致 string::find 搜索错误的字符串。