{"id":"3bf4f95b-5fc1-42ee-b703-4b736056fc6e","arxiv_id":"1908.03819","paper_version":1,"verdict":"CONDITIONAL","confidence":"MODERATE","novelty_score":6.0,"correctness_risk":"medium","formal_verification":"none","parameter_count":0,"one_line_summary":"Alphanumeric-plus-one-character RISC-V shellcodes that achieve arbitrary code execution were designed, generated by a new automated tool, and executed on QEMU and HiFive Unleashed hardware.","lead":"This paper shows how to write RISC-V attack programs, called shellcodes, that look like ordinary text (letters, digits, and one extra character) and still run any code. It is the first such technique for RISC-V, an open chip standard that is spreading into phones and embedded devices.","discovery_kind":"new_application","skeptic_critique":{"model":"deepseek-v4-flash","headline":"The tick-variant completeness assumption is the weakest load-bearing point: Section 5.6 admits the floating-point equations are not guaranteed solvable, and Algorithm 1 gives no termination or coverage proof, yet the abstract claims a complete framework for arbitrary code.","rationale":"The reader's weakest_assumption identifies the same point: the floating-point solver in Section 5.6 is a randomized search without a proof of termination or success. I agree that this is the most load-bearing concern. The paper's contribution is not merely three hand-crafted shellcodes but a 'complete framework' for automatic generation. If Algorithm 1 can fail for a legitimate payload, then the tick variant is not complete, and the Section 1.2 claim of three constructions, one for each choice of additional character, is overstated. The paper itself flags the limitation ('not guaranteed to always have solutions', 'hoping to find one'), so the gap is explicit rather than an artifact of the review pipeline. This does not undermine the hash or slash variants, nor the successful executions on QEMU and the HiFive Unleashed board; those are real positive results with reproducible code. The 'only possible' impossibility remark is also under-supported, but it is not load-bearing for the construction: the paper could simply rephrase it and the central framework claim would stand. The proposed concrete test would either reveal an actual failure mode or show that the solver is robust in practice. Until then, a conditional verdict is appropriate, and no adjustment to the reader's verdict is needed.","tokens_in":13935,"tokens_out":15177,"duration_ms":168775,"concrete_test":"Run the released generator on a diverse set of payloads (e.g., 100 randomly generated payloads with sizes 1, 8, 64, 200, and 512 bytes, plus the three original demos) for the 'RV64IDC variant, using a budget comparable to the paper's (about 2.3e11 iterations or 1.5 CPU-hours per payload). Record the success rate of Algorithm 1 and any dependence on payload size. If any payload fails or times out, the 'complete framework' claim is false for the tick variant; if all succeed, the concern is reduced to a missing formal guarantee rather than an observed failure.","verdict_should_be":"UNCHANGED","load_bearing_attack":"Section 5.6 and Algorithm 1 make the 'RV64IDC construction depend on solving equations of the form ri = ai * b + ci (via fmadd) under the constraint that ai, bi, and ci are alphanumeric floating-point constants. The text explicitly states that 'these equations are not guaranteed to always have solutions' and that the authors address this by generating polymorphic stage-2 instances and 'hoping to find one' satisfying all equations. The reported run of about 2.3e11 iterations found several instances for the paper's demonstration payloads, which is genuine evidence for those cases, but it does not establish that a new payload (with different pointer and length constants baked into stage 2) will be handled. Termination is controlled only by an ad hoc iteration cap, and coverage of the roughly 6 million polymorphic stage-2 instances is not analyzed. Because the abstract promises 'a complete framework for automatically generating alphanumeric (+1 character) shellcodes' capable of 'arbitrary code execution', the tick variant's completeness rests on an unproven heuristic. The hash and slash variants, which use deterministic store/atomic instructions assembled from the 96% table in Section 5.1.3, do not share this particular gap.","agreement_with_reader":"agree"},"referee_report":{"model":"deepseek-v4-flash","summary":"The paper presents a methodology for constructing RISC-V shellcodes whose binary representation contains only alphanumeric ASCII characters plus one additional character: '#', '/', or '''. The construction is three-staged: a first-stage unpacker written in a highly constrained alphanumeric instruction subset unpacks a second-stage decoder, which in turn decodes and executes an arbitrary third-stage payload. The authors enumerate the available alphanumeric instructions in the RV64GC ISA, give a table-based method for loading arbitrary 2-byte values in the '#RV64IC' and '/RV64IAC' variants, and use floating-point fused-multiply-add equations in the '''RV64IDC' variant. They report successful execution of three payloads (printf/write \"Hello world\", execve(\"/bin/sh\"), and an /etc/shadow leak) on both QEMU and a HiFive Unleashed board, and provide the generated shellcodes in the appendix.","tokens_in":14196,"tokens_out":3751,"duration_ms":42930,"significance":"If the results hold, this is the first published construction of alphanumeric shellcode for RISC-V and a useful extension of the ARMv8 methodology from Barral et al. The paper's strengths include real-hardware validation on a HiFive Unleashed board, reproducibly printed shellcodes, and a publicly available toolchain with three distinct variants. The central packing design is sound, and the hash and slash variants are demonstrated with deterministic store/atomic instruction sequences. However, the abstract's 'complete framework' wording overstates what is proved for the tick variant, whose solvability depends on an unproven heuristic search.","major_comments":[{"comment":"The completeness of the '''RV64IDC variant rests on an unproven existence assumption. The text explicitly states that the floating-point equations ri = ai*b + ci are 'not guaranteed to always have solutions' and that the authors generate polymorphic stage-2 instances 'hoping to find one' for which all equations are solvable. Algorithm 1 has no termination proof, and the reported 2.3e11-iteration run with an ad hoc 2,000,000-iteration cap does not provide coverage over the roughly 6 million polymorphic instances. Since the abstract promises 'a complete framework' for automatic generation of shellcodes for arbitrary code, this is a load-bearing gap. The authors should either prove or analytically bound the existence of at least one solvable stage-2 instance for any payload, or explicitly qualify the completeness claim as conditional on the randomized search succeeding for the payload at hand.","section":"Section 5.6, Algorithm 1"},{"comment":"The 2-byte-load table covers only 96% of possible 16-bit values for '#RV64IC' and 88% for '/RV64IAC'. For the claimed 'complete framework', the paper must explain how the generator guarantees that every 16-bit chunk of stage 2 lies in the supported set. The text only states that stage 2 is designed 'so that every pair of bytes in stage 2 could be loaded from an instruction sequence in the table' and reports success for the three demonstration payloads. This is not a defect in the demonstrated artifacts, but it is another point where the word 'complete' exceeds what is formally established.","section":"Section 5.1.3 and Section 5.5"}],"minor_comments":[{"comment":"The phrase 'whose ASCII binary representation use only' should be 'whose ASCII binary representation uses only', and the term 'alphanumeric (+1 character)' should be defined at its first occurrence.","section":"Abstract"},{"comment":"The empirical validation would be more useful if the paper stated whether NX/DEP or other executable-memory protections were disabled on the HiFive test environment, since the attack assumes executable memory for the unpacked shellcode.","section":"Section 6.2"},{"comment":"The statement that the search required '1.5 execution hours' on a 4-core Atom 2GHz CPU should specify whether this is wall-clock time or CPU time, especially since Algorithm 1 is described as parallelized.","section":"Section 5.6"},{"comment":"The shellcode listings rely on color coding that is not reproducible in print; a textual annotation or a table mapping each colored region to its high-level role would make the appendix self-contained.","section":"Appendix A"}],"recommendation":"major_revision","confidential_remarks":null},"author_rebuttal":null,"desk_editor":{"model":"deepseek-v4-flash","letter":"Worth knowing: this is the first published alphanumeric shellcode work for RISC-V, and it actually runs. Three filter sets (#, /, ') each get a full chain from constrained stage-1 unpacker to arbitrary payload, validated on QEMU and a HiFive Unleashed board. The shellcodes are printed, source is linked, and the table-driven 2-byte load construction is a real piece of engineering. That is more than a slideware contribution; the reproducibility bar is met.\n\nWhat is new is mostly the ISA port plus the three-way construction. The hash variant is the cleanest: no store exists in the base alphanumeric set, so they add # to get sd/sw, then use a precomputed table to load arbitrary 2-byte chunks. Slash uses atomic amoor.d with a block layout. Tick uses fmadd/fsd and is the cleverest and the least settled.\n\nThe soft spots are where the text already admits them. Section 5.6 says the floating-point equations are not guaranteed solvable, and Algorithm 1 is a randomized search with an iteration cap; the authors \"hope\" to find a polymorphic stage 2 instance that works, and 2.3e11 iterations found several for the demo payloads. That is evidence, not a proof. If the paper's selling point is \"a complete framework for automatically generating\" shellcodes for arbitrary payloads, the tick variant does not support that claim as written. Also, the introduction's \"only possible\" phrasing about needing one extra character is asserted rather than proven; they show three choices work, not that no other choice does. Both overclaims are fixable: soften the wording, or add a deterministic solver or guarantee for tick, or explicitly limit the completeness claim to the hash and slash variants. In practice, the hash variant already delivers the abstract's promise if you pick #, so this is not a load-bearing flaw for the whole paper.\n\nMinor: the coverage tables are 96% and 88%, and stage 2 is chosen to fit the table; that is okay for a proof-of-concept but \"arbitrary\" should be qualified.\n\nWho should read it: people working on shellcode generation, constrained-ISA code, or RISC-V exploitation. It is a solid workshop-tier paper with working artifacts, not a foundational result. It deserves serious referee time; with the completeness claims rephrased and the tick search either tightened or explicitly labeled heuristic, I would take it.","headline":"First working RISC-V alphanumeric shellcodes with real-hardware validation; the tick variant's unproven solver is the main soft spot, but the hash and slash routes stand.","tokens_in":14722,"tokens_out":2577,"would_cite":true,"duration_ms":28628,"reading_group":"maybe","serious_thinker":"yes","would_accept_peer_review":true},"rs_alignment":null,"lean_confirmation":null,"pith_extraction":{"msc":[],"pacs":[],"model":"deepseek-v4-flash","headline":"This paper demonstrates that RISC-V systems can be made to execute arbitrary code from shellcodes restricted to alphanumeric ASCII characters plus one of #, /, or ', and validates the approach with three payloads on an emulator and a…","keywords":["alphanumeric shellcode","RISC-V","shellcode generation","packing","exploit development","floating-point encoding","ASCII payload encoding","text-based filter bypass"],"falsifier":"Run the paper's own generator on a fixed 512-byte payload and let Algorithm 1 test every stage-2 instance; if every instance leaves some equation unsolved, the tick variant cannot encode that payload and the 'arbitrary payload' claim fails for this construction.","tokens_in":13730,"feed_emoji":"🐚","tokens_out":12097,"duration_ms":120447,"temperature":0.7,"pith_summary":"This paper establishes that RISC-V, a young open-source instruction set heading into embedded devices, is vulnerable to alphanumeric shellcoding: a short injected program whose binary representation uses only letters a–z, A–Z, digits 0–9, and one extra character chosen from #, /, or '. The authors build a three-stage packing framework—an unrolled first-stage unpacker, a tiny looping decoder, and the final payload—that turns arbitrary compiled C code into such an ASCII-restricted shellcode. This matters because text-based applications (SMS, chat, URLs, QR codes) commonly filter out binary-looking bytes, and RISC-V has had no published alphanumeric shellcode analysis before this paper. The claim is backed by executing three payloads (a 'Hello world' write, an execve('/bin/sh') spawn, and an /etc/shadow leak) on QEMU and on a HiFive Unleashed board running Linux.","feed_headline":"RISC-V shellcodes run arbitrary code from alphanumeric bytes","feed_subtitle":"Three-stage packer stitches together payloads from letters, digits, and one extra character.","key_machinery":"The mechanism that carries the argument is the three-stage packer combined with a precomputed load table and a 4-bit-per-byte XOR decoder. Stage 1's load table is built by depth-first search over the # alphanumeric subset and yields shortest sequences for 63,448 of 65,536 possible 16-bit values, enough to write any needed stage-2 instruction into memory two bytes at a time. The decoder itself is the identity $A[0:3] = L[0:3] \\oplus L[4:7]$, $A[4:7] = K[0:3] \\oplus L[4:7]$, with a closed-form rule choosing alphanumeric $K$ and $L$ for every byte $A$; this keeps the loop to five instructions. For the tick variant, the store is replaced by floating-point fused-multiply-add equations $r = a \\times b + c$, and Algorithm 1 searches over roughly six million register-renamed or reordered stage-2 instances until all equations have alphanumeric solutions.","core_discovery":"The central claim is that RV64GC's alphanumeric instruction subset, although it contains no stores and no backward jumps, is expressive enough for arbitrary code execution through packing. Stage 1 is a straight-line unpacker that uses the one allowed extra character to obtain a store instruction (sw/sd for #, amoor.d for /, or fsd for ') and writes a minimal stage 2 into memory next to itself. Stage 2, only 40 bytes long, runs a five-instruction loop that decodes two alphanumeric bytes into one payload byte and jumps to the decoded payload after a fence.i cache flush. The authors present this as the first analysis of alphanumeric code on RISC-V and the first complete framework for automatically generating such shellcodes, with all three constructions executed on a real board.","pith_inferences":["A reader could reasonably infer that RISC-V text-processing applications (URL, SMS, chat, QR-code handlers) inherit a new injection surface: printable-looking content should be treated as executable data, not inert text.","The floating-point variant's reliance on search rather than proof suggests an adversarial stress test: choose a payload designed so every polymorphic stage-2 instance leaves an unsolvable equation; success would show the tick route is not universal.","The 63-symbol alphabet could in principle encode nearly six bits per byte, so a denser encoder than the paper's four-bit scheme would make shellcodes shorter at the cost of a longer decoder, a trade-off the paper leaves for future work."],"forward_implications":["An input sanitizer that keeps only letters, digits, and one of #, /, or ' still leaves a RISC-V process open to arbitrary code execution.","The three-stage packer runs end to end from C source, so a new RISC-V payload does not require hand-written assembly; the same skeleton can be reused across the three constructions.","The 4-bit-per-byte encoding keeps the decoder to five instructions and stage 2 to 40 bytes, so the practical size of a shellcode is dominated by the encoded payload, which is demonstrated up to the 512-byte cap.","The absence of backwards branches in the base alphanumeric subset is not a blocker: stage 1 is a straight-line unrolled unpacker that jumps forward over the payload pool."],"supporting_citations":[{"why":"Supplies the instruction-clustering methodology (control-flow, data-processing, memory) and the generic approach that the paper transfers from ARMv8 to RISC-V.","marker":"[3]"},{"why":"Defines the RISC-V instruction encodings, opcode constraints, and the RV64GC extension set used to enumerate the alphanumeric instruction subset.","marker":"[22]"},{"why":"Documents the earlier interpreter/bytecode approach for ARM filter-resistant code injection that the paper replaces with a packing approach.","marker":"[23]"},{"why":"Contextualizes automatic generation of compact alphanumeric shellcodes for x86, the baseline the RISC-V generators extend.","marker":"[4]"},{"why":"Provides the emulator used to run all three shellcode variants and reproduce the Hello-world experiments.","marker":"[5]"},{"why":"Gives the register naming convention (ra, sp, t0, etc.) used throughout the generated code and the stage-2 snippets.","marker":"[6]"},{"why":"Supports the choice of RV64GC as the standard RISC-V Unix profile, hence the attack surface considered.","marker":"[7]"}],"fun_headline_variants":["RISC-V shellcode from letters, digits, # / ' only","Alphanumeric RISC-V shellcode: arbitrary code via packing","No stores, no backward jumps, RISC-V alphanumeric exec still works","Packing RISC-V shellcode into alphanumeric bytes","RISC-V gets alphanumeric shellcode with three extra chars"],"cache_read_input_tokens":3200,"weakest_assumption_plain":"The floating-point variant's load-bearing premise is that at least one register-renamed or reordered instance of stage 2 satisfies every equation $r = a \\times b + c$ with alphanumeric $a,b,c$; the authors find such instances by search and give no proof that one exists for every payload.","fun_headline_variants_meta":{"raw":{"variants":["RISC-V shellcode from letters, digits, # / ' only","Alphanumeric RISC-V shellcode: arbitrary code via packing","No stores, no backward jumps, RISC-V alphanumeric exec still works","Packing RISC-V shellcode into alphanumeric bytes","RISC-V gets alphanumeric shellcode with three extra chars"]},"model":"deepseek-v4-flash","effort":"low","cost_usd":0.00078,"raw_usage":{"total_tokens":3333,"prompt_tokens":718,"completion_tokens":2615,"prompt_tokens_details":{"cached_tokens":384},"prompt_cache_hit_tokens":384,"prompt_cache_miss_tokens":334,"completion_tokens_details":{"reasoning_tokens":2521}},"tokens_in":334,"tokens_out":2615,"duration_ms":21662,"temperature":1.0,"reasoning_tokens":2521,"cache_read_input_tokens":384,"cache_creation_input_tokens":0},"cache_creation_input_tokens":0},"created_at":"2026-08-14T14:00:50.188344+00:00","model_set":{"reader":"deepseek-v4-flash"},"falsifier":"Run the paper's own generator on a fixed 512-byte payload and let Algorithm 1 test every stage-2 instance; if every instance leaves some equation unsolved, the tick variant cannot encode that payload and the 'arbitrary payload' claim fails for this construction.","supporting_citations":[{"cited_title":"ARMv8 Shellcodes from ‘A’to ‘Z’","cited_arxiv_id":null,"evidence_quote":"Supplies the instruction-clustering methodology (control-flow, data-processing, memory) and the generic approach that the paper transfers from ARMv8 to RISC-V."},{"cited_title":"url: https://www.gaisler.com/doc/sparcv8.pdf","cited_arxiv_id":null,"evidence_quote":"Defines the RISC-V instruction encodings, opcode constraints, and the RV64GC extension set used to enumerate the alphanumeric instruction subset."},{"cited_title":"2017.url: https://content.riscv.org/wp-content/uploads/2017/05/ riscv-spec-v2.2.pdf","cited_arxiv_id":null,"evidence_quote":"Documents the earlier interpreter/bytecode approach for ARM filter-resistant code injection that the paper replaces with a packing approach."},{"cited_title":"QEMU, a Fast and Portable Dynamic Translator","cited_arxiv_id":null,"evidence_quote":"Provides the emulator used to run all three shellcode variants and reproduce the Hello-world experiments."},{"cited_title":"RISC-V ELF psABI Specifcation","cited_arxiv_id":null,"evidence_quote":"Gives the register naming convention (ra, sp, t0, etc.) used throughout the generated code and the stage-2 snippets."},{"cited_title":null,"cited_arxiv_id":null,"evidence_quote":"Supports the choice of RV64GC as the standard RISC-V Unix profile, hence the attack surface considered."}],"review_version":1}