我一直在为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位。任何帮助表示赞赏!
答案 0 :(得分:3)
访问冲突是因为0x87E64A05
大于一个有符号的32位整数可以容纳的最大值(0x7FFFFFFF
)。
由于int
可能为32位,因此XREFKILLER
无法容纳0x87E64A05
,因此其值将由实现定义。
此值随后在 literal xs
人工推进通过的指针之后会再次用于从0x87E64A05
中减去,{em} long
或long 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
来代替。