You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于snprintf操作字符数组触发栈内存缓冲区溢出的技术问询

分析这段MD5校验和格式化代码的栈溢出问题

先把有问题的代码贴出来,方便咱们一起拆解:

char checksumBuffer[MD5_DIGEST_LENGTH*2+2] = {0};
int writeIndex = 0;
for(int i=0; i<MD5_DIGEST_LENGTH; i++, writeIndex+= 2) {
    snprintf(&checksumBuffer[writeIndex],sizeof(checksumBuffer), "%02x", *checksum++);
}

问题核心:缓冲区越界写入

咱们一步步捋清楚:

  • 先算缓冲区容量:MD5_DIGEST_LENGTH是16,所以这个缓冲区总大小是16*2+2=34字节(初始化时全部设为0)。
  • 循环执行16次,每次writeIndex加2,到最后一次循环时,writeIndex的值是30——也就是&checksumBuffer[writeIndex]指向缓冲区起始位置偏移30字节的位置。
  • 这里调用snprintf犯了关键错误:第二个参数传的是整个缓冲区的大小(34字节),但实际上从当前写入位置开始,剩余可用空间只有34-30=4字节。
  • 这就导致snprintf误以为自己有34字节的空间可以写入,最终会写到缓冲区起始位置偏移63字节的地方——远远超出了34字节的缓冲区容量,直接在栈内存上触发溢出。

修复方案

核心是给snprintf传入当前剩余的可用缓冲区大小,而不是整个缓冲区的大小。修改后的代码如下:

char checksumBuffer[MD5_DIGEST_LENGTH*2+2] = {0};
int writeIndex = 0;
for(int i=0; i<MD5_DIGEST_LENGTH; i++, writeIndex+= 2) {
    // 每次计算剩余可用空间:总大小减去已经占用的writeIndex长度
    snprintf(&checksumBuffer[writeIndex], sizeof(checksumBuffer) - writeIndex, "%02x", *checksum++);
}

这样每次调用snprintf时,它都明确知道自己最多能写多少字节,不会再越界写入栈上的其他内存区域。

内容的提问来源于stack exchange,提问作者niketa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:52:26