以下代码在x64位中崩溃,但在x86构建中不崩溃

时间:2018-12-29 00:01:39

标签: c++ encryption

我一直在为32位应用程序使用xor加密类,但最近我开始处理64位应用程序,并遇到以下崩溃:https://i.stack.imgur.com/jCBlJ.png

这是我正在使用的xor类:

]

当我尝试使用混淆后的字符串时会发生崩溃,但不一定100%的情况发生(但是从来没有发生在32位上)。这是一个64位应用程序的小示例,它将在第二个混淆的字符串上崩溃:

s='''{
"response": 200,
"message": null,
"params": [],
"body": {
    "timestamp": 1546033192,
    "_d": [
            {"id": "FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz"},
            {"id": "FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH"},
            {"id": "Fmfgo9'''

>>> f.complete_json_structure(s)
{'response': 200, 'message': None, 'params': [], 'body': {'timestamp': 1546033192, '_d': [{'id': 'FMfcgxwBTsWRDsWDqgqRtZlLMdpCpTDz'}, {'id': 'FMfcgxwBTkFSKqRrcKzMFvLCjDSSbrJH'}]}}

如果内置32位,则同一应用程序将运行完美。

以下是用于生成混淆字符串的HTML脚本:https://pastebin.com/QsZxRYSH

我需要调整此类以便在64位上工作,因为我已经加密了很多字符串,需要将它们从32位项目导入到当前正在处理的项目中,这就是64位。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:3)

访问冲突是因为0x87E64A05大于一个有符号的32位整数可以容纳的最大值(0x7FFFFFFF)。

由于int可能为32位,因此XREFKILLER无法容纳0x87E64A05,因此其值将由实现定义。

此值随后在 literal xs人工推进通过的指针之后会再次用于从0x87E64A05中减去,{em} longlong long来使值合适,具体取决于long是32位还是更大,因此不会缩小到实现定义的值。

因此,您实际上在xs[i - XREFKILLER]中留有一些随机指针,这很可能会产生未定义的行为,例如访问冲突。

如果针对32位x86进行编译,则可能发生int和指针具有相同的位大小,并且实现定义的上溢/下溢和收窄行为恰好使加法和减法正确抵消的情况。如预期的那样。但是,如果指针类型大于32位,则无法使用。


根本没有指向XREFKILLER的意义。它只会执行一项立即恢复的计算(如果没有上溢/下溢)。


请注意,编译器完全接受template参数中的缩小是一个错误。您的程序格式错误,编译器应给您一条错误消息。 例如,在GCC中,此错误一直持续到8.2版,但已在当前主干(即9版)中修复。


如果XORSTART在平台上恰好是char,则signed也会遇到类似的问题,因为那样您提供的值将不适合它。但是在这种情况下,您将必须启用警告,因为这不会导致程序格式错误。另外,如果系统上的^char,则signed的行为可能与您预期的不一致。


目前尚不清楚

s[BUFLEN - 1] = (2 * 2 - 3) - 1;

是。应该是:

s[BUFLEN - 1] = '\0';

如果结果字符串恰好包含一个printf,它将被解释为格式说明符的引入,则将结果字符串作为第一个参数传递给%会导致虚假的未定义行为。使用std::cout


如果要使用printf,则需要编写std::printf#include<cstdio>以确保它可以使用。但是,由于这是C ++,因此无论如何都应该使用std::cout


从根本上来说,您的输出字符串可能恰好包含一个0,而不是在转换之后的终止符。这将被解释为C样式字符串的结尾。这似乎是一个主要的设计缺陷,出于这个原因(并且因为它是更好的样式),您可能想要使用std::string来代替。