C语言Convert_to_Hex函数致已转换变量被篡改问题求助
问题排查与解决
问题现象
有三个各32字节的unsigned char数组,尝试将它们分别转换为HEX格式并存入64字节的char数组中。第一个数组ai_values_temp转换后打印正常,但转换第二个数组bi_values_temp后,再打印ai_values_hex_temp,输出结果变成原64字节内容加上bi_values_hex_temp的64字节内容。
代码示例
int main (int argc, char* argv[]) { if (argc != 3) { printf("Usage: %s <GMPMessage.txt> <GMPSeed.txt>\n", argv[0]); return 1; } int gmpMessageLen; unsigned char *message = Read_File(argv[1], &gmpMessageLen); int seedLen; unsigned char *seed = Read_File(argv[2], &seedLen); int n = gmpMessageLen / 32; unsigned char *prnData = PRNG(seed, seedLen, 2 * n * 32); for (int i = 0; i < n; i++) { unsigned char ai_values_temp[32]; unsigned char bi_values_temp[32]; unsigned char mi_values_temp[32]; char ai_values_hex_temp[64]; char bi_values_hex_temp[64]; char mi_values_hex_temp[64]; for (int j = 0; j < 32; j++) { ai_values_temp[j] = prnData[i * 64 + j]; bi_values_temp[j] = prnData[i * 64 + 32 + j]; mi_values_temp[j] = message[i * 32 + j]; } char ai_values_hex_copy[64]; Convert_to_Hex(ai_values_hex_temp, ai_values_temp, 32); printf("Ai value %d %s\n",i, ai_values_hex_temp); // 正常输出 Convert_to_Hex(bi_values_hex_temp, bi_values_temp, 32); printf("Bi value %s\n", bi_values_hex_temp); printf("Ai value %d %s\n",i, ai_values_hex_temp); // 输出原内容+bi的内容 } return 0; } void Convert_to_Hex (char output[], unsigned char input[], int inputlength) { memset(output, 0, 2 * inputlength + 1); for (int i = 0 ; i < inputlength ; i++) { sprintf(&output[2*i], "%02x", input[i]); } //printf("Hex format: %s\n", output); }
问题原因
- 字符串结束符缺失导致越界读取:32字节二进制数据转HEX字符串需要64个字符,但C语言字符串必须以
'\0'(空字符)作为结束标记,否则printf等函数会持续读取内存直到遇到'\0',从而读到相邻变量的内容。 - 内存越界写入:
Convert_to_Hex函数中memset(output, 0, 2 * inputlength + 1)的操作长度为65字节(当inputlength=32时),但你定义的HEX数组仅64字节,这会导致越界写入,破坏栈上相邻变量的内存(比如ai_values_hex_temp与bi_values_hex_temp在栈中连续存放)。
解决方法
- 将存储HEX字符串的数组长度从64改为65,预留字符串结束符的位置:
char ai_values_hex_temp[65]; char bi_values_hex_temp[65]; char mi_values_hex_temp[65]; char ai_values_hex_copy[65]; - 确保
memset操作长度与数组匹配,避免越界:memset(output, 0, 2 * inputlength + 1); // 此时数组长度必须≥2*inputlength+1
验证效果
修改数组长度后,printf读取字符串时会在'\0'处停止,不会再读取相邻变量内容,同时memset也不会越界写入,输出异常问题即可解决。
内容的提问来源于stack exchange,提问作者Murad Bashirli
相关产品推荐
相关产品推荐

