fuzzerDriver.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "RyanJsonFuzzer.h"
  2. /**
  3. * @brief 从当前输入稳定生成 PRNG 种子
  4. *
  5. * 这里不追求密码学强度,只要求同一份输入总能得到同一条随机路径,
  6. * 方便 libFuzzer 复现问题并保持覆盖结果稳定。
  7. */
  8. static uint32_t RyanJsonFuzzerSeedFromInput(const uint8_t *data, size_t size)
  9. {
  10. uint32_t seed = 2166136261u;
  11. for (size_t i = 0; i < size; ++i)
  12. {
  13. seed ^= (uint32_t)data[i];
  14. seed *= 16777619u;
  15. }
  16. seed ^= (uint32_t)size;
  17. return 0 == seed ? 0x811C9DC5u : seed;
  18. }
  19. /**
  20. * @brief 初始化 Fuzzer 状态
  21. *
  22. * 使用当前输入数据混合 PRNG 种子,保证同一输入具备稳定路径。
  23. *
  24. * @param data 原始输入数据
  25. * @param size 输入数据大小
  26. */
  27. void RyanJsonFuzzerInit(const uint8_t *data, size_t size)
  28. {
  29. g_fuzzerState.isEnableMemFail = true;
  30. g_fuzzerState.seed = RyanJsonFuzzerSeedFromInput(data, size);
  31. }
  32. /**
  33. * @brief 生成下一个伪随机数 (Xorshift32)
  34. *
  35. * 一个极其快速且轻量级的 PRNG,适合 Fuzzer 环境。
  36. *
  37. * @return uint32_t 随机数
  38. */
  39. uint32_t RyanJsonFuzzerNextRand()
  40. {
  41. uint32_t x = g_fuzzerState.seed;
  42. x ^= x << 13;
  43. x ^= x >> 17;
  44. x ^= x << 5;
  45. g_fuzzerState.seed = x;
  46. return x;
  47. }
  48. /**
  49. * @brief 决定是否应该触发失败
  50. *
  51. * 用于模拟内存分配失败等随机错误路径。
  52. *
  53. * @param probability 概率倒数 (例如 100 表示 1/100 的概率)
  54. * @return RyanJsonBool_e RyanJsonTrue 表示应该触发失败
  55. */
  56. RyanJsonBool_e RyanJsonFuzzerShouldFail(uint32_t probability)
  57. {
  58. if (false == g_fuzzerState.isEnableMemFail) { return RyanJsonFalse; }
  59. if (0 == probability) { return RyanJsonTrue; }
  60. return (0 == RyanJsonFuzzerNextRand() % probability) ? RyanJsonTrue : RyanJsonFalse;
  61. }