{
  "schema_version": "r2b.case-study.v1",
  "case_id": "darpa-cgc-pilot",
  "generated_at": "2026-09-02T05:30:00Z",
  "status": "blind loop recorded",
  "dataset": {
    "vendor": "Trail of Bits cb-multios",
    "source": "https://github.com/trailofbits/cb-multios",
    "commit": "810d7b24b1f62f56ef49b148fe155b0d0629cad2",
    "architecture": "i386",
    "platform": "linux/amd64 container on ARM64 Kali Pi",
    "selection": [
      "Palindrome",
      "basic_messaging",
      "ASL6parse",
      "CNMP",
      "FISHYXML",
      "Matchmaker",
      "Overflow_Parking",
      "root64_and_parcour",
      "stream_vm2"
    ],
    "selection_rule": "Palindrome + basic_messaging + every 28th linux-working.txt line from line 8"
  },
  "host": {
    "uname": "Linux kali-raspberry-pi5 6.1.92-v8+ aarch64",
    "cpus": 4,
    "ram_gib": 8,
    "r2b_version": "0.1.0",
    "python": "3.11.13",
    "radare2": "6.0.5",
    "file": "5.47",
    "ghidra": "12.1.2 PUBLIC",
    "java": "Temurin 21.0.5",
    "docker": "28.5.2",
    "flavor": "core; Ghidra headless present, angr not enabled"
  },
  "build": {
    "image": "r2b-cgc-pinned",
    "image_id": "sha256:560a44bea5c9ed4cf3e8eef7ff67341a604e600bebb587a9b9ddc4534245e6aa",
    "os_arch": "linux/amd64",
    "base": "ubuntu:18.04",
    "clang": "6.0.0-1ubuntu2",
    "cmake": "3.10.2",
    "flags": "clang -m32 -O0 -g -fno-stack-protector -z execstack -z norelro",
    "notes": [
      "Upstream Dockerfile retained. cmake/32.cmake uses add_compile_definitions, which CMake 3.10 lacks; the local build used add_definitions(-DX32_COMPILE) with the same X32_COMPILE meaning.",
      "Default 32-bit x86 targets were kept."
    ]
  },
  "subjects": [
    {
      "id": "Palindrome",
      "sha256": "96398b59a75a1cc5266946f0e0f1d7ba4c4abee3d917406be080ee58ba665582",
      "size_bytes": 10452,
      "file": "ELF 32-bit LSB executable, Intel 80386, dynamically linked, with debug_info, not stripped",
      "function_count_radare2": 28,
      "import_count": 5,
      "dangerous_imports": []
    },
    {
      "id": "Palindrome_patched",
      "sha256": "1c0c86076fd149328b96269feebe4424201da2ea623d7d02067a18c1960791ec",
      "size_bytes": 10452,
      "file": "ELF 32-bit LSB executable, Intel 80386, dynamically linked, with debug_info, not stripped",
      "function_count_radare2": 28,
      "import_count": 5,
      "dangerous_imports": []
    },
    {
      "id": "basic_messaging",
      "sha256": "7047c86528d59905b098e2abaf140b6e8671b8fcfd260032d4dc91f5b4982f3e",
      "size_bytes": 35320,
      "file": "ELF 32-bit LSB executable, Intel 80386, dynamically linked, with debug_info, not stripped",
      "function_count_radare2": 101,
      "import_count": 5,
      "dangerous_imports": []
    },
    {
      "id": "basic_messaging_patched",
      "sha256": "a8ced942dd6252d8f938baed04f06d73881c998dcfc5e1ad50e6faa02b5518df",
      "size_bytes": 35276,
      "file": "ELF 32-bit LSB executable, Intel 80386, dynamically linked, with debug_info, not stripped",
      "function_count_radare2": 101,
      "import_count": 5,
      "dangerous_imports": []
    }
  ],
  "brief": {
    "mode": "quick",
    "model_calls": 0,
    "ranked_regions_all_four": ["entry:main"],
    "rank_recall": {
      "k1": "identical across each patched/unpatched pair",
      "k3": "no additional regions",
      "k5": "no additional regions"
    },
    "claim": "Quick ranking did not distinguish either pair. CGC services import libcgc, not strcpy/recv, so the PLT pivot never appears."
  },
  "review": {
    "mode": "rules",
    "model_calls": 0,
    "base_order_all_four": ["entry:main"],
    "dispositions": {
      "entry:main": "needs_confirmation"
    },
    "claim_strength": {
      "entry:main": "lead"
    }
  },
  "localization": {
    "Palindrome": {
      "function": "cgc_check",
      "address": "0x08048a00",
      "radare2_name": "dbg.cgc_check",
      "unpatched": {
        "receive_bound": "0x80",
        "disasm": "0x08048a41  mov ecx, 0x80",
        "decompile": "cgc_receive_delim(0, string, 0x80, '\\n');"
      },
      "patched": {
        "receive_bound": "0x40",
        "disasm": "0x08048a41  mov ecx, 0x40",
        "decompile": "cgc_receive_delim(0, string, 0x40, '\\n');"
      },
      "shared": "char string[64];"
    },
    "basic_messaging": {
      "function": "cgc_list_unread_messages",
      "address": "0x0804a7e0",
      "radare2_name": "dbg.cgc_list_unread_messages",
      "unpatched": {
        "count_type": "uchar",
        "disasm": "mov byte [count], 0; movzx eax, byte [count]",
        "decompile": "uchar count; count = '\\0'; count = count + '\\x01';"
      },
      "patched": {
        "count_type": "uint",
        "disasm": "mov dword [count], 0; mov eax, dword [count]",
        "decompile": "uint count; count = 0; count = count + 1;"
      }
    }
  },
  "targeted_decompile": {
    "tool": "Ghidra 12.1.2 analyzeHeadless + DecompileTargets.java",
    "cli": "After expanding ghidra.project_dir and moving it off ~/.local, r2b decompile of ranked main then of cgc_check succeeded. cgc_list_unread_messages was reached only in a source-guided pass, not the blind loop.",
    "reached": {
      "cgc_check": "via handoff.next_argv plus one callee hop",
      "cgc_list_unread_messages": "source-guided only; not a loop hit"
    }
  },
  "runtime": {
    "isolation": {
      "network": "none",
      "user": "65534:65534",
      "rootfs": "read-only plus tmpfs /tmp",
      "caps": "dropped",
      "no_new_privileges": true,
      "host_mounts": false,
      "notes": "cb-test.py raises RLIMIT_CORE to infinity; nobody cannot raise that limit, so the runner swallowed the setrlimit error. Memory cgroup limits were advertised by Docker but discarded on this host."
    },
    "poll": {
      "Palindrome": {
        "xml": "challenges/Palindrome/poller/for-testing (1 POLL)",
        "unpatched": "pass",
        "patched": "pass"
      },
      "basic_messaging": {
        "xml": "for-release POLL_00000, POLL_00001, POLL_00002",
        "unpatched": "pass",
        "patched": "pass"
      }
    },
    "pov": {
      "Palindrome": {
        "artifact": "pov_1.pov type 1",
        "unpatched_should_core": "not ok - POV type 1 should have cored, and did not",
        "patched_no_core": "pass",
        "gdb": "absent in the builder image; core-register proof was not collected"
      },
      "basic_messaging": {
        "artifact": "pov_1.pov type 1",
        "unpatched_should_core": "not ok - POV type 1 should have cored, and did not",
        "patched_no_core": "pass",
        "gdb": "absent in the builder image; core-register proof was not collected"
      }
    }
  },
  "timing": {
    "warmup_s": {
      "Palindrome": 21.579,
      "Palindrome_patched": 13.595,
      "basic_messaging": 13.537,
      "basic_messaging_patched": 13.278
    },
    "parallel_median_s": {
      "Palindrome": 18.69,
      "Palindrome_patched": 19.593,
      "basic_messaging": 19.667,
      "basic_messaging_patched": 19.297
    },
    "sequential_s": {
      "Palindrome": 14.228,
      "Palindrome_patched": 13.583,
      "basic_messaging": 13.422,
      "basic_messaging_patched": 13.181,
      "total": 54.414
    },
    "parallel_four_together_median_wall_s": 19.667,
    "notes": "Three measured parallel rounds after one unmeasured warmup. GNU time was not installed; wall time is perf_counter around `r2b brief --quick --no-save --json`."
  },
  "ground_truth": {
    "Palindrome": "CWE-121: 64-byte stack buffer; unpatched receives 128 bytes, patched receives 64.",
    "basic_messaging": "CWE-190: unread-message counter is unsigned char unpatched and unsigned int patched."
  },
  "labeled_sources": {
    "Palindrome": {
      "cgc_id": "CADET_00001",
      "role": "official CGC sample, not a high-scoring CQE qualifier in the LL archive index used here",
      "author_label": "CWE-121 stack overflow: 64-byte buffer, read up to 128",
      "sources": [
        "https://github.com/CyberGrandChallenge/samples/tree/master/examples/CADET_00001",
        "https://github.com/angr/angr-doc/blob/master/examples/CADET_00001/solve.py",
        "https://gist.github.com/moyix/71357ca3b4d65c13e8394517e7093e21"
      ],
      "expert_notes": [
        "angr example finds unconstrained EIP from symbolic stdin and the ^ easter egg; DECREE easter-egg address 0x804833E does not match this Linux port.",
        "KLEE on cb-multios Palindrome reports memory error at service.c:65 almost immediately."
      ],
      "r2b_alignment": "brief → decompile main → callee hop decompiles cgc_check and the 0x80 vs 0x40 receive bound; does not emit a crashing input"
    },
    "basic_messaging": {
      "cgc_id": "CROMU_00001",
      "role": "CQE qualifier",
      "author_label": "CWE-190 then CWE-131 then CWE-120 in list_unread_messages(); 8-bit unread count wraps above 255; crash in strlen",
      "sources": [
        "https://archive.ll.mit.edu/cgc/cgc-corpus/challenges/CROMU_00001/"
      ],
      "cqe_scores_max_4": {
        "CodeJitsu": 1.85,
        "CSDS": 0.9,
        "ForAllSecure": 0.58,
        "Shellphish": 0.0,
        "TrailofBits": 0.0
      },
      "cqe_notes": [
        "Trail of Bits proved a reference POV despite a 0 score.",
        "ForAllSecure, CodeJitsu, and CSDS defended 100% against the reference POV.",
        "Author: sending messages to self is not enough to trigger."
      ],
      "r2b_alignment": "blind loop missed; source-guided decompile reaches uchar vs uint count; does not recover the CQE POV or CRS score"
    }
  },
  "fidelity_ladder": [
    {
      "level": "challenge_id",
      "Palindrome": "CADET_00001 sample",
      "basic_messaging": "CROMU_00001 CQE qualifier",
      "r2b": "cb-multios names"
    },
    {
      "level": "cwe",
      "Palindrome": "121",
      "basic_messaging": "190 then 131 then 120",
      "r2b": "not emitted; matched after decompile"
    },
    {
      "level": "author_prose",
      "Palindrome": "64-byte stack, read 128",
      "basic_messaging": "8-bit unread count, wrap >255, crash in strlen; self-send not enough",
      "r2b": "matched after decompile"
    },
    {
      "level": "source_patched_ifdef",
      "Palindrome": "cgc_check: sizeof(string) vs 128",
      "basic_messaging": "cgc_list_unread_messages: unsigned int vs unsigned char count",
      "r2b": "same sites"
    },
    {
      "level": "dwarf_name",
      "Palindrome": "cgc_check @ 0x08048a00",
      "basic_messaging": "cgc_list_unread_messages @ 0x0804a7e0",
      "r2b": "yes"
    },
    {
      "level": "instruction",
      "Palindrome": "mov ecx, 0x80 vs 0x40",
      "basic_messaging": "mov byte [count] vs mov dword [count]",
      "r2b": "yes"
    },
    {
      "level": "poll",
      "Palindrome": "1 XML: race / racecar",
      "basic_messaging": "899 release + 101 testing; protocol only",
      "r2b": "pass on sampled POLLs"
    },
    {
      "level": "official_pov",
      "Palindrome": "type 1 masks 0/0/0; one 147-byte write",
      "basic_messaging": "type 1; userone/usertwo; 256+ sends to the other user (cb-multios pov.c 781 transmits, 259 usertwo writes)",
      "r2b": "patched no core; unpatched core not registered under qemu-user"
    },
    {
      "level": "symbolic_crash_finders",
      "Palindrome": "angr unconstrained EIP; KLEE service.c:65",
      "basic_messaging": "no published tutorial",
      "r2b": "no crashing input generated"
    },
    {
      "level": "cqe_crs_score",
      "Palindrome": "n/a",
      "basic_messaging": "max 1.85/4 CodeJitsu; ForAllSecure 0.58; Shellphish/ToB 0; ToB proved a POV",
      "r2b": "not a CRS score"
    }
  ],
  "replay": [
    "python3 scripts/corpus_intake.py fetch darpa-cgc-multios",
    "python3 scripts/corpus_intake.py verify darpa-cgc-multios",
    "docker build --platform linux/amd64 -t r2b-cgc-pinned .r2b-corpus/darpa-cgc-multios",
    "r2b brief Palindrome --quick --no-save --json",
    "r2b review brief.json --mode rules --json"
  ],
  "blind_loop": {
    "protocol": [
      "r2b brief BINARY --quick --no-save --json",
      "execute handoff.next_argv (r2b decompile ranked address)",
      "up to 2 extra hops: named callees in decompiled C except libcgc I/O, vaddr from r2 isj"
    ],
    "source_consulted_at_runtime": false,
    "all_briefs_ranked": ["entry:main"],
    "site_decompiled": ["Palindrome"],
    "name_on_path_site_not_decompiled": ["CNMP"],
    "miss": [
      "basic_messaging",
      "ASL6parse",
      "FISHYXML",
      "Matchmaker",
      "Overflow_Parking",
      "root64_and_parcour",
      "stream_vm2"
    ],
    "counts": {
      "challenges": 9,
      "binaries": 18,
      "site_decompiled": 1,
      "name_on_path": 2
    },
    "sha256": {
      "Palindrome": "96398b59a75a1cc5266946f0e0f1d7ba4c4abee3d917406be080ee58ba665582",
      "Palindrome_patched": "1c0c86076fd149328b96269feebe4424201da2ea623d7d02067a18c1960791ec",
      "basic_messaging": "7047c86528d59905b098e2abaf140b6e8671b8fcfd260032d4dc91f5b4982f3e",
      "basic_messaging_patched": "a8ced942dd6252d8f938baed04f06d73881c998dcfc5e1ad50e6faa02b5518df",
      "ASL6parse": "a9768a0b81de43bcf1898995ba74773ee9579404e46cd2c763a12e87e055afab",
      "ASL6parse_patched": "9ed8cf34c3de8e2e23f392d90c9024f75a881af2e4943b14be63815e1f5ff945",
      "CNMP": "83c530ed41118edb95c86a9270ad6b4304031fb0c23095f5d907da4472a1f5f3",
      "CNMP_patched": "e6e3d95715ff2e0de2ca5b99c8d12f93efd5e19563067f29b51f8cdecd71e7ef",
      "FISHYXML": "e9ba64afc76e71ca82691394640fae840b1aae901f9944e8c23b3245d034daab",
      "FISHYXML_patched": "19ff425de0331714f7da944ec9c4756e2191e9174911588a9e403d60d59412b8",
      "Matchmaker": "01eff334bdbea35300560be4b5ed74383a3a6c72183cbd976098cff2b7dab432",
      "Matchmaker_patched": "d1a6ed8e9eaf2208f2edb48ad3f16fec9cc6b5d3242ce6397c62c0f8a4305b67",
      "Overflow_Parking": "c4698497bd6ee8d19c74fff6a8bf442206c969c5f57125a5f75f09665338f6d8",
      "Overflow_Parking_patched": "98b140c95dfc961953b2fd9b03fc0efab1d1feca8793862315dd399715d8d3aa",
      "root64_and_parcour": "41e5c714a69d2127ef7c1aed10761464833363b8f1eaa50181a76562971efcf3",
      "root64_and_parcour_patched": "66a60233e812cab319d8295466e011e91153bfee35f90591d54c399f1ca9c4e1",
      "stream_vm2": "683273263feddfd891adff9a1ca1188be2f42484e597127eb87821d6a0f59075",
      "stream_vm2_patched": "1c511d36d039188762967016b29112779d380154f30b1ebb0c55cf1df917efcc"
    },
    "palindrome_site": {
      "function": "cgc_check",
      "address": "0x8048a00",
      "unpatched": "cgc_receive_delim(0, string, 0x80, '\\n'); char string[64];",
      "patched": "cgc_receive_delim(0, string, 0x40, '\\n'); char string[64];",
      "path": "brief ranks main 0x8048880 → decompile main → callee cgc_check → decompile 0x8048a00"
    },
    "tools_alone": {
      "r2_pdf_main": "r2 -qc 'aaa; pdf @ main' already shows call dbg.cgc_check",
      "brief_snippet": "12-line snippet stops on a broken c7 invalid encoding and does not show the call",
      "r2b_extra": "handoff.next_argv decompiles the ranked address to Ghidra C, then hops named callees"
    },
    "decompile_cli": {
      "was": "empty C; analyzeHeadless rc=1",
      "cause": "unexpanded ~ created a cwd-relative ~ tree; Ghidra rejects path elements starting with '.' such as .local",
      "fix": "expanduser on ghidra.project_dir; default ~/r2b/ghidra-projects"
    }
  },
  "limits": [
    "Identical quick ranking across each pair is the recorded result, not a scoring failure. The brief never sees strcpy/recv; the patch lives in libcgc-facing helpers named by DWARF.",
    "Following handoff.next_argv decompiled the planted site on Palindrome only (1/9). CNMP showed cgc_insert_joke as a callee. The other seven missed under a 2-hop budget.",
    "The earlier source-guided decompile of cgc_list_unread_messages is not a loop result.",
    "verify was not forced: there is no relevant external import sink.",
    "Official type 1 POVs did not register a core under qemu-user linux/amd64 without gdb. POLLs passed on both variants. Patched POVs correctly did not core.",
    "Raw target bytes, POLL/POV transcripts, and the builder image stay out of git."
  ]
}
