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

寻求可触发C代码崩溃(段错误)的输入字符串及排查方案

寻找触发C代码段错误的输入字符串及排查思路

问题描述

我编写了如下C语言代码,希望找到能触发代码崩溃(如Segmentation Fault段错误)的输入字符串。已尝试过长字符输入但未成功,恳请提供可行的输入示例及故障排查思路。

代码示例

#define POLYNOMIAL 0x04c11db7L
uint32_t crc_table[256];

int win()
{
  printf("Great Job\n");
  exit(0);
}


void gen_crc_table()
{
 uint16_t i, j;
 uint32_t crc_accum;

 for (i=0; i<256; i++)
  {
    crc_accum = ((uint32_t)i << 24);
    for (j = 0;j < 8; j++)
    {
        if (crc_accum & 0x80000000L)
            crc_accum = (crc_accum << 1) ^ POLYNOMIAL;
        else
            crc_accum = (crc_accum << 1);
    }
    crc_table[i] = crc_accum;
   } 
}

uint32_t update_crc(uint32_t crc_accum, uint8_t *data_blk_ptr, uint32_t data_blk_size)
{
 uint32_t i, j;

for (j=0; j < data_blk_size; j++)
{
    i = ((int) (crc_accum >> 24) ^ *data_blk_ptr++) & 0xFF;
    crc_accum = (crc_accum << 8) ^ crc_table[i];
 }
  crc_accum = ~crc_accum;
  return crc_accum;
}


int main()
{
  char buffer[256];
  unsigned long long target;

  scanf("%256s", buffer);
  gen_crc_table();
  if (update_crc(-1, buffer, sizeof(buffer)) == 0x4920cbc3)
  {
    memcpy(buffer + 128, buffer, sizeof(buffer));
  }
  exit(1);
 }

已尝试输入

abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ


可行输入示例

要触发段错误,必须先满足CRC校验条件进入危险分支:

  1. 计算CRC条件的逆向值:update_crc返回值为0x4920cbc3,意味着取反前的CRC累加值是~0x4920cbc3 = 0xb6df343c。
  2. 构造256字节的字符串,使得以0xFFFFFFFF(即-1的无符号表示)为初始值,使用多项式0x04c11db7计算的CRC32结果等于0xb6df343c。

你可以通过CRC逆向工具或编写简单脚本生成该字符串。一旦输入满足条件,程序会执行memcpy(buffer + 128, buffer, 256):该操作会将256字节数据复制到buffer+128起始的位置,而buffer仅256字节,复制过程会直接溢出栈空间,触发段错误。

故障排查思路

  • 定位危险操作:代码中的memcpy是直接触发崩溃的原因——目标区域buffer+128到buffer+255仅128字节可用,却要复制256字节,必然越界覆盖栈上其他数据(如返回地址、栈帧信息)。
  • 分析分支触发条件:崩溃前提是进入if分支,即update_crc的返回值等于0x4920cbc3。理解CRC计算逻辑是关键:
    • 初始CRC累加值为0xFFFFFFFF(-1的无符号表示)
    • 处理完256字节数据后对结果取反,得到返回值
    • 因此需要满足~CRC32(0xFFFFFFFF, buffer, 256) = 0x4920cbc3,即原始CRC结果为0xb6df343c
  • 解释长输入无效原因:scanf("%256s", buffer)限制最多读取256个非空白字符,长输入会被截断,且未满足CRC校验条件,无法进入危险分支,因此不会崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:04:54