{"id":23849,"date":"2026-09-09T18:11:38","date_gmt":"2026-09-09T18:11:38","guid":{"rendered":"https:\/\/scannn.com\/decbench-scoreboard\/"},"modified":"2026-09-09T18:11:38","modified_gmt":"2026-09-09T18:11:38","slug":"decbench-scoreboard","status":"publish","type":"post","link":"https:\/\/scannn.com\/lv\/decbench-scoreboard\/","title":{"rendered":"DecBench Scoreboard"},"content":{"rendered":"\n<div id=\"\">\n<section class=\"view active\" id=\"view-leaderboard\" data-view=\"leaderboard\">\n<h2 class=\"view-title\">leaderboard<\/h2>\n<p class=\"view-desc\">Decompilers have advanced significantly over<br \/>\n<a href=\"https:\/\/mahaloz.re\/dec-history-pt1\">the last 30 years<\/a>, quickly approaching the<br \/>\npoint where they can recover the exact source code from various binaries. This<br \/>\nbenchmark ranks decompilers by their ability to recover exact source code,<br \/>\nmeasured across three metrics. All metrics are shown as the percentage of<br \/>\nfunctions on which a decompiler achieves a perfect score. Decompilers are<br \/>\ninitially ranked by Union \u2014 their ability to score perfectly on<br \/>\n<em>at least one<\/em> of those metrics. Click a column to sort.<\/p>\n<p class=\"view-desc\">AI can also compete on these metrics, as seen on the<br \/>\n<a href=\"https:\/\/decbench.com\/leaderboard\/?dataset=sample-set\">sample-set leaderboard<\/a><br \/>\nwhere Codex and Claude Code take on the traditional decompilers. You can find<br \/>\nmore information about these metrics, datasets, and methodology on the<br \/>\n<a href=\"https:\/\/decbench.com\/about\/\">about page<\/a>. You can also view some sample results<br \/>\non the <a href=\"https:\/\/decbench.com\/view\/?dataset=sample-set&amp;tier=sample-set&amp;dec=codex&amp;metric=ged&amp;fn=base-passwd%2FO0%2Fupdate-passwd%3A%3Aread_shadow\">view page<\/a>.<\/p>\n<\/section>\n<section class=\"view\" id=\"view-data\" data-view=\"data\">\n<h2 class=\"view-title\">data<\/h2>\n<p class=\"view-desc\">Benchmark-run data beyond the leaderboard&#8217;s perfect rates:<br \/>\n<a href=\"#distance\">distance<\/a> from perfection per metric,<br \/>\nhow often decompiled output <a href=\"#compiles\">compiles<\/a> again,<br \/>\n<a href=\"#pipeline-health\">pipeline health<\/a> (what our own tooling loses), and the<br \/>\n<a href=\"#cost\">cost<\/a> of producing each decompiler&#8217;s output.<\/p>\n<h3 class=\"sub\" id=\"distance\">distance<\/h3>\n<p class=\"view-desc\">When a decompiler can&#8217;t yet achieve a perfect score on a function, it can be<br \/>\nhelpful to understand the <em>distance<\/em> it is from perfection. For each<br \/>\nmetric, we measure distance as the number of edits required to convert that<br \/>\nform of data into its source-code equivalent. For <strong>GED<\/strong>, that<br \/>\nis the number of edits to control-flow structures. For<br \/>\n<strong>types<\/strong>, that is the number of type-flips needed to reach<br \/>\nground truth. For <strong>recompilation<\/strong>, that is the number of<br \/>\nassembly lines that must change to convert the recompiled assembly into the<br \/>\nground-truth assembly.<\/p>\n<p class=\"view-desc\">Each cell shows the <em>mean<\/em>, the <em>median<\/em>, and how many functions<br \/>\nare already at distance 0 (perfect), averaged over the functions each<br \/>\ndecompiler was scored on.<\/p>\n<p class=\"view-desc\" id=\"distance-table-note\">Over the selected dataset<br \/>\n    (mean \u00b7 median \u00b7 #at-0 \/ #measured).<\/p>\n<p class=\"view-desc subset-note\" id=\"distance-subset-note\" hidden=\"\">rows below the<br \/>\nbreak are <em>sample-set-only<\/em> backends (LLM coding agents): they are scored<br \/>\nonly on the ~250-function sample-set slice, so on this dataset their numbers<br \/>\ncover just its overlap with that slice \u2014 not directly comparable to the<br \/>\nfull-coverage rows above.<\/p>\n<h3 class=\"sub\" id=\"compiles\">compiles<\/h3>\n<p class=\"view-desc\">The share of each decompiler&#8217;s byte_match-measured functions whose output<br \/>\nactually <em>recompiled<\/em> after the uniform compilability-fixup pass \u2014 a<br \/>\nfairness control, not a metric (type recovery is scored separately). The<br \/>\ndenominator is per-decompiler: functions where byte_match was measurable, so<br \/>\nARM \/ PE targets with no host recompiler never count against it. This rate moves<br \/>\nwith the selected dataset, like the columns on the leaderboard.<\/p>\n<p class=\"view-desc subset-note\" id=\"compile-subset-note\" hidden=\"\">rows below the<br \/>\nbreak: sample-set-only backends \u2014 their rate covers only this dataset&#8217;s<br \/>\noverlap with the sample-set slice.<\/p>\n<h3 class=\"sub\" id=\"pipeline-health\">pipeline health (our own tooling)<\/h3>\n<p class=\"view-desc\">GED depends on Joern parsing both the source and the decompiler output.<br \/>\nWhen Joern fails on the <strong>source<\/strong>, that&#8217;s our tooling \u2014 those<br \/>\nfunctions are excluded from GED for every decompiler (never counted against<br \/>\nthem). When Joern fails on a single decompiler&#8217;s <strong>output<\/strong>,<br \/>\nthat&#8217;s reported here (per decompiler), not folded into the headline score.<\/p>\n<h3 class=\"sub\" id=\"cost\">cost<\/h3>\n<p class=\"view-desc\">What each decompiler&#8217;s output <em>costs<\/em> to produce. The two halves of the table<br \/>\nare <strong>not directly comparable<\/strong>: traditional decompilers are timed from<br \/>\nwhole-binary batch decompilation (a binary&#8217;s wall time divided by its function<br \/>\ncount), while the LLM coding agents are timed per function \u2014 one agentic call<br \/>\neach, including all their tool use (objdump runs, reasoning, retries). The<br \/>\ndollar figures are <strong>estimates<\/strong>: recorded token usage from the sample-set run,<br \/>\npriced at public list prices at render time \u2014 not billed amounts. <code>-<\/code> means<br \/>\nnot applicable or no data (traditional decompilers have no per-token cost;<br \/>\nan unpriced model shows n\/a rather than $0.00).<\/p>\n<\/section>\n<section class=\"view\" id=\"view-view\" data-view=\"view\">\n<h2 class=\"view-title\">view<\/h2>\n<p class=\"view-desc\">Original source next to a decompiler&#8217;s output. <strong>Difficulty<\/strong> is<br \/>\nderived from structural (GED) agreement across decompilers:<br \/>\n<strong>easy<\/strong> \u2014 most decompilers recover the control flow<br \/>\nperfectly; <strong>hard<\/strong> \u2014 the functions farthest from perfect<br \/>\nfor everyone (the old hall of shame); <strong>medium<\/strong> \u2014 in<br \/>\nbetween. Pick a difficulty, a decompiler, and a metric to highlight.<\/p>\n<p>\n    <label for=\"view-difficulty\">difficulty:<\/label><br \/>\n    <select id=\"view-difficulty\"\/><br \/>\n    <label for=\"view-dec\">decompiler:<\/label><br \/>\n    <select id=\"view-dec\"\/><br \/>\n    <label for=\"view-metric\">metric:<\/label><br \/>\n    <select id=\"view-metric\"\/>\n<\/p>\n<p>\n    <label for=\"view-filter\">filter:<\/label><br \/>\n    <input type=\"text\" id=\"view-filter\" placeholder=\"function \/ project \/ binary\" size=\"28\"\/><br \/>\n    <label for=\"view-select\">function:<\/label><br \/>\n    <select id=\"view-select\"\/><br \/>\n    <span class=\"counter\" id=\"view-counter\"\/>\n<\/p>\n<\/section>\n<section class=\"view\" id=\"view-about\" data-view=\"about\">\n<h2 class=\"view-title\">decbench<\/h2>\n<p class=\"view-desc\">Over the last 30 years, binary decompilers have made the steady march towards <em>perfect decompilation<\/em>: where decompilers recover the exact source code.<br \/>\nHowever, that <em>perfect<\/em> has yet to be measured meaningfully, and is often defined across multiple axes.<\/p>\n<p class=\"view-desc\">DecBench is an experimental benchmark for comparing decompilers and modern LLMs on the task of recovering <em>exact<\/em> source code. This benchmark uses new and previously known metrics (perfect match percentage) and datasets that represent the various directions of exactness for decompilers: control flow structure, types, and precise recompilability.<br \/>\nThis benchmark is also <em>living<\/em>: as new decompiler\/LLMs are released, their scores will be added to the leaderboard! Community feedback is welcome!<\/p>\n<p class=\"view-desc\">It is created by the <a href=\"https:\/\/github.com\/Noelo-Lab\">Noelo Lab at the University of Georgia<\/a>, led by <a href=\"https:\/\/www.zionbasque.com\/\">Dr. Zion Leonahenahe Basque<\/a>.<br \/>\nThe project&#8217;s <a href=\"https:\/\/github.com\/noelo-lab\/decbench\">code<\/a> and <a href=\"https:\/\/huggingface.co\/datasets\/noelo-lab\/decbench-dataset\">data<\/a> are open source.<br \/>\nEmail <code><a href=\"https:\/\/decbench.com\/cdn-cgi\/l\/email-protection\" class=\"__cf_email__\" data-cfemail=\"16727375747378757e566c7f79787477656763733875797b\">[email\u00a0protected]<\/a><\/code> to get your decompiler added to the public site.<\/p>\n<h2>why<\/h2>\n<p class=\"view-desc\">There have been two other academic benchmarks in the past for end-to-end decompilers: <a href=\"https:\/\/proceedings.neurips.cc\/paper_files\/paper\/2025\/file\/079cf13ae174c31f148207d94d213bdc-Paper-Datasets_and_Benchmarks_Track.pdf\">Decompile-Bench<\/a> and <a href=\"https:\/\/aclanthology.org\/2025.findings-acl.1194.pdf\">DecompileBench<\/a> (yes, I know the names are confusing).<br \/>\nThese works establish their own take on the problem, and are worth a read.<br \/>\nBoth have limitations: one relies on readability metrics (which we&#8217;ve shown in <a href=\"https:\/\/www.usenix.org\/system\/files\/usenixsecurity24-basque.pdf\">prior work to be flawed<\/a>) the other on metrics that sacrifice correctness for other achievements (passing a subset of testcases on recompilation).<\/p>\n<p class=\"view-desc\">DecBench uses metrics that place correctness as a first-class citizen and attempt to measure perfection on a function-level rather than a macro level.<br \/>\nIdeally, perfect decompilation is that which is <em>correct<\/em>.<br \/>\nEach metric you will find here attempts to measure the correctness across <a href=\"https:\/\/decompilation.wiki\/fundamentals\/overview\/\">three widely explored areas<\/a>.<br \/>\nOnce a decompiler approaches 100% on all three metrics, you can consider that it nearly always recovers perfect decompilation (at least for this dataset!).<\/p>\n<p class=\"view-desc\">DecBench is also a response to static-benchmarks that often get outdated or fail to change when flaws are discovered.<br \/>\nIt is very likely there is bugs in the code that runs DecBench, or there is projects which pull too much weight than others.<br \/>\nDecBench aims to change as the community changes: adding new decompilers, updating versions, and improving supported projects.<br \/>\nAs such, this is a living project, widely different from a paper and more similar to the popular <a href=\"https:\/\/www.swebench.com\/\">SWEBench<\/a>.<\/p>\n<h2>the three metrics<\/h2>\n<p class=\"view-desc\">We define three metrics that explore the three areas we believe are representative of &#8220;perfect&#8221; decompilation.<\/p>\n<ol>\n<li>Code Structure<\/li>\n<li>Types (args and vars)<\/li>\n<li>Byte-match Recompilability<\/li>\n<\/ol>\n<p class=\"view-desc\">There are cases where these three metrics can conflict with each other.<br \/>\nAs such, decompilers are scored by <code>Union<\/code>: the overlap where at least one of these metrics is perfect.<\/p>\n<p class=\"view-desc\">None of these metrics, themselves are <strong>perfect and all come with limitations<\/strong>, ironically.<br \/>\nThat speaks to the difficulty of measuring this field.<br \/>\nFind the extended metrics limitations <a href=\"#metric-limitations\">below<\/a>.<\/p>\n<div class=\"goal\">\n<p><span class=\"num\">[1]<\/span>Control-flow structure correctness<\/p>\n<p>metric: Graph Edit Distance<\/p>\n<div class=\"goal-body\">\n<p>Does the decompiled code branch and loop the same way the source does? We compare the control-flow graphs of the source and the decompilation with a Graph Edit Distance (GED) \u2014 the number of node\/edge insertions, deletions, and substitutions needed to turn one CFG into the other.<\/p>\n<details class=\"metric-viz\" open=\"\">\n<summary>how GED works: source \u2192 CFG \u2192 graph diff<\/summary>\n<div class=\"viz-wrap\">\n<div class=\"viz-row\">\n<p>A \u00b7 lift the source to a control-flow graph<\/p>\n<p>\n<span class=\"viz-chip is-in\">source .c<\/span><br \/>\n<span class=\"viz-parrow\">\u2014<b>\u00a0joern\u00a0<\/b>\u2192<\/span><br \/>\n<span class=\"viz-chip is-out\">control-flow graph<\/span><br \/>\n<span class=\"viz-dim\">\u00a0(same lift is applied to every decompiler&#8217;s C output)<\/span>\n<\/p>\n<div class=\"viz-grid\">\n<div class=\"viz-panel\">\n<p>source.c<\/p>\n<pre class=\"viz-code\" data-lang=\"c\"><code>\/\/ sum of |x[i]|\nint sum_abs(int *x, int n) {\n    int i, s = 0;\n    for (i = 0; i &lt; n; i++) {\n        if (x[i] &lt; 0)\n            s -= x[i];\n        else\n            s += x[i];\n    }\n    return s;\n}<\/code><\/pre>\n<\/div>\n<div class=\"viz-panel\">\n<p>control-flow graph<\/p>\n<p><svg viewbox=\"0 0 360 300\" role=\"img\" aria-label=\"control-flow graph of sum_abs\" style=\"max-width:100%;height:auto;display:block\">\n<defs>\n<marker id=\"ga-g\" markerwidth=\"9\" markerheight=\"9\" refx=\"6\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L6,3 L0,6 Z\" fill=\"var(--text-muted)\"\/><\/marker>\n<\/defs><\/p>\n<line x1=\"180\" y1=\"44\" x2=\"180\" y2=\"79\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#ga-g)\"\/>\n<line x1=\"168\" y1=\"110\" x2=\"112\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#ga-g)\"\/>\n<line x1=\"192\" y1=\"110\" x2=\"248\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#ga-g)\"\/>\n<line x1=\"101\" y1=\"188\" x2=\"160\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#ga-g)\"\/>\n<line x1=\"259\" y1=\"188\" x2=\"200\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#ga-g)\"\/>\n<path d=\"M139,251 C78,250 22,238 22,180 C22,120 74,101 137,101\" fill=\"none\" stroke=\"var(--text-muted)\" stroke-width=\"1.2\" stroke-dasharray=\"4 3\" marker-end=\"url(#ga-g)\"\/>\n<text x=\"68\" y=\"130\" font-size=\"9.5\" fill=\"var(--text-muted)\" text-anchor=\"middle\">loop<\/text>\n<text x=\"104\" y=\"139\" font-size=\"9.5\" fill=\"var(--text-muted)\" text-anchor=\"end\">&lt;0<\/text>\n<text x=\"234\" y=\"139\" font-size=\"9.5\" fill=\"var(--text-muted)\">\u22650<\/text><\/p>\n<p><rect x=\"139\" y=\"14\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"33\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">entry<\/text>\n<rect x=\"139\" y=\"80\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"99\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">cond<\/text>\n<rect x=\"52\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"93\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">then<\/text>\n<rect x=\"226\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"267\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">else<\/text>\n<rect x=\"139\" y=\"242\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"261\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">exit<\/text>\n<\/svg><\/p>\n<p>green = the reference shape (dashed edge = loop back-edge)<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"viz-row\">\n<p>B \u00b7 the edit distance: reference vs a decompiler&#8217;s CFG<\/p>\n<div class=\"viz-grid\">\n<div class=\"viz-panel\">\n<p>source CFG<\/p>\n<p><svg viewbox=\"0 0 360 300\" role=\"img\" aria-label=\"source control-flow graph\" style=\"max-width:100%;height:auto;display:block\">\n<defs>\n<marker id=\"gb-g\" markerwidth=\"9\" markerheight=\"9\" refx=\"6\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L6,3 L0,6 Z\" fill=\"var(--text-muted)\"\/><\/marker>\n<\/defs>\n<line x1=\"180\" y1=\"44\" x2=\"180\" y2=\"79\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gb-g)\"\/>\n<line x1=\"168\" y1=\"110\" x2=\"112\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gb-g)\"\/>\n<line x1=\"192\" y1=\"110\" x2=\"248\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gb-g)\"\/>\n<line x1=\"101\" y1=\"188\" x2=\"160\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gb-g)\"\/>\n<line x1=\"259\" y1=\"188\" x2=\"200\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gb-g)\"\/>\n<path d=\"M139,251 C78,250 22,238 22,180 C22,120 74,101 137,101\" fill=\"none\" stroke=\"var(--text-muted)\" stroke-width=\"1.2\" stroke-dasharray=\"4 3\" marker-end=\"url(#gb-g)\"\/>\n<text x=\"68\" y=\"130\" font-size=\"9.5\" fill=\"var(--text-muted)\" text-anchor=\"middle\">loop<\/text>\n<rect x=\"139\" y=\"14\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"33\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">entry<\/text>\n<rect x=\"139\" y=\"80\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"99\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">cond<\/text>\n<rect x=\"52\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"93\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">then<\/text>\n<rect x=\"226\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"267\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">else<\/text>\n<rect x=\"139\" y=\"242\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--green)\" stroke-width=\"1.4\"\/><text x=\"180\" y=\"261\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">exit<\/text>\n<\/svg><\/p>\n<p>5 nodes \u00b7 6 edges<\/p>\n<\/div>\n<div class=\"viz-panel\">\n<p>decompiled CFG<\/p>\n<p><svg viewbox=\"0 0 360 300\" role=\"img\" aria-label=\"decompiled control-flow graph with one inserted node\" style=\"max-width:100%;height:auto;display:block\">\n<defs>\n<marker id=\"gd-g\" markerwidth=\"9\" markerheight=\"9\" refx=\"6\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L6,3 L0,6 Z\" fill=\"var(--text-muted)\"\/><\/marker>\n<marker id=\"gd-r\" markerwidth=\"9\" markerheight=\"9\" refx=\"6\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L6,3 L0,6 Z\" fill=\"var(--red)\"\/><\/marker>\n<\/defs><\/p>\n<line x1=\"180\" y1=\"44\" x2=\"180\" y2=\"79\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gd-g)\"\/>\n<line x1=\"168\" y1=\"110\" x2=\"112\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gd-g)\"\/>\n<line x1=\"192\" y1=\"110\" x2=\"248\" y2=\"156\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gd-g)\"\/>\n<line x1=\"101\" y1=\"188\" x2=\"160\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gd-g)\"\/>\n<line x1=\"259\" y1=\"188\" x2=\"200\" y2=\"240\" stroke=\"var(--text-muted)\" stroke-width=\"1.3\" marker-end=\"url(#gd-g)\"\/>\n<path d=\"M139,251 C78,250 22,238 22,180 C22,120 74,101 137,101\" fill=\"none\" stroke=\"var(--text-muted)\" stroke-width=\"1.2\" stroke-dasharray=\"4 3\" marker-end=\"url(#gd-g)\"\/>\n<text x=\"68\" y=\"130\" font-size=\"9.5\" fill=\"var(--text-muted)\" text-anchor=\"middle\">loop<\/text><\/p>\n<path d=\"M222,94 C332,102 332,182 302,214\" fill=\"none\" stroke=\"var(--red)\" stroke-width=\"1.6\" marker-end=\"url(#gd-r)\"\/>\n<line x1=\"252\" y1=\"234\" x2=\"224\" y2=\"250\" stroke=\"var(--red)\" stroke-width=\"1.6\" marker-end=\"url(#gd-r)\"\/>\n<rect x=\"252\" y=\"214\" width=\"70\" height=\"28\" rx=\"5\" fill=\"var(--panel-red-tint)\" stroke=\"var(--red)\" stroke-width=\"1.5\"\/><text x=\"287\" y=\"232\" font-size=\"12\" fill=\"var(--red)\" text-anchor=\"middle\">blk<\/text><\/p>\n<p><rect x=\"139\" y=\"14\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1.3\"\/><text x=\"180\" y=\"33\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">entry<\/text>\n<rect x=\"139\" y=\"80\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1.3\"\/><text x=\"180\" y=\"99\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">cond<\/text>\n<rect x=\"52\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1.3\"\/><text x=\"93\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">then<\/text>\n<rect x=\"226\" y=\"158\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1.3\"\/><text x=\"267\" y=\"177\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">else<\/text>\n<rect x=\"139\" y=\"242\" width=\"82\" height=\"30\" rx=\"5\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1.3\"\/><text x=\"180\" y=\"261\" font-size=\"12.5\" fill=\"var(--text)\" text-anchor=\"middle\">exit<\/text>\n<\/svg><\/p>\n<p>matched nodes grey \u00b7 <span style=\"color:var(--red)\">inserted node + 2 edges red<\/span><\/p>\n<\/div>\n<\/div>\n<p>\nGED = <span class=\"n\">3<\/span> \u00a0\u2014\u00a0 1 node insertion + 2 edge insertions to align the two CFGs\n<\/p>\n<div class=\"viz-score\">\n<p><span class=\"viz-good big\">GED = 0<\/span> <span class=\"viz-dim\">\u2192 the two CFGs are graph-isomorphic \u2014 a perfect structural match.<\/span><\/p>\n<p>Only control-flow shape is scored; node labels are ignored, so the signal is fair across decompilers.<\/p>\n<\/div>\n<\/div>\n<p class=\"viz-note\">Structural Correctness (GED): Joern lifts both the original source and each decompiler&#8217;s C output to control-flow graphs, then counts the fewest node\/edge edits needed to make them isomorphic \u2014 <code>0<\/code> means an identical shape. Only control structure is scored, so the signal is fair across decompilers.<\/p>\n<\/div>\n<\/details>\n<p> <span class=\"perfect\">perfect = GED of 0 (graph-isomorphic control flow).<\/span><\/div>\n<\/p><\/div>\n<div class=\"goal\">\n<p><span class=\"num\">[2]<\/span>Type correctness<\/p>\n<p>metric: Type Correctness<\/p>\n<div class=\"goal-body\">\n<p>Did the decompiler recover the right variable and argument types? We match the decompiled variables against DWARF ground truth (arguments by ABI position, stack variables by calibrated offset, the rest by name) and score the fraction recovered correctly.<\/p>\n<details class=\"metric-viz\" open=\"\">\n<summary>how type matching works: DWARF ground truth  recovered variables<\/summary>\n<div class=\"viz-wrap\">\n<p><svg viewbox=\"0 0 720 322\" role=\"img\" aria-label=\"stack-frame type matching between DWARF ground truth and decompiler output\" style=\"max-width:100%;height:auto;display:block\">\n<defs>\n<marker id=\"tm-g\" markerwidth=\"9\" markerheight=\"9\" refx=\"7\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L7,3 L0,6 Z\" fill=\"var(--green)\"\/><\/marker>\n<marker id=\"tm-a\" markerwidth=\"9\" markerheight=\"9\" refx=\"7\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L7,3 L0,6 Z\" fill=\"var(--amber)\"\/><\/marker>\n<marker id=\"tm-r\" markerwidth=\"9\" markerheight=\"9\" refx=\"7\" refy=\"3\" orient=\"auto\"><path d=\"M0,0 L7,3 L0,6 Z\" fill=\"var(--red)\"\/><\/marker>\n<\/defs><\/p>\n<p><text x=\"24\" y=\"26\" font-size=\"12.5\" fill=\"var(--text)\">DWARF ground truth <tspan fill=\"var(--text-muted)\">(from -g build)<\/tspan><\/text>\n<text x=\"696\" y=\"26\" text-anchor=\"end\" font-size=\"12.5\" fill=\"var(--text)\">decompiler output<\/text>\n<line x1=\"24\" y1=\"34\" x2=\"310\" y2=\"34\" stroke=\"var(--border-dim)\" stroke-width=\"1\" stroke-dasharray=\"4 3\"\/>\n<line x1=\"410\" y1=\"34\" x2=\"696\" y2=\"34\" stroke=\"var(--border-dim)\" stroke-width=\"1\" stroke-dasharray=\"4 3\"\/>\n<p><text x=\"360\" y=\"54\" text-anchor=\"middle\" font-size=\"10.5\" fill=\"var(--text-muted)\"><tspan fill=\"var(--text)\" font-weight=\"bold\">[1]<\/tspan> arguments \u2014 matched by ABI position<\/text><\/p>\n<p><rect x=\"24\" y=\"62\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"34\" y=\"80\" font-size=\"10\" fill=\"var(--text-muted)\">arg 0 \u00b7 %rdi<\/text>\n<text x=\"34\" y=\"99\" font-size=\"13\" fill=\"var(--text)\">char *<tspan fill=\"var(--text-muted)\">path<\/tspan><\/text>\n<rect x=\"410\" y=\"62\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"420\" y=\"80\" font-size=\"10\" fill=\"var(--text-muted)\">param a1<\/text>\n<text x=\"420\" y=\"99\" font-size=\"13\" fill=\"var(--green)\">char *<\/text>\n<text x=\"686\" y=\"94\" text-anchor=\"end\" font-size=\"15\" fill=\"var(--green)\">\u2713<\/text><\/p>\n<p><rect x=\"24\" y=\"114\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"34\" y=\"132\" font-size=\"10\" fill=\"var(--text-muted)\">arg 1 \u00b7 %esi<\/text>\n<text x=\"34\" y=\"151\" font-size=\"13\" fill=\"var(--text)\">int <tspan fill=\"var(--text-muted)\">mode<\/tspan><\/text>\n<rect x=\"410\" y=\"114\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"420\" y=\"132\" font-size=\"10\" fill=\"var(--text-muted)\">param a2<\/text>\n<text x=\"420\" y=\"151\" font-size=\"13\" fill=\"var(--amber)\">uint<\/text>\n<text x=\"686\" y=\"146\" text-anchor=\"end\" font-size=\"15\" fill=\"var(--amber)\">\u2260<\/text><\/p>\n<p><text x=\"360\" y=\"188\" text-anchor=\"middle\" font-size=\"10.5\" fill=\"var(--text-muted)\"><tspan fill=\"var(--text)\" font-weight=\"bold\">[2]<\/tspan> stack locals \u2014 by frame offset, <tspan fill=\"var(--text)\" font-weight=\"bold\">[3]<\/tspan> then by name<\/text><\/p>\n<p><rect x=\"24\" y=\"196\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"34\" y=\"214\" font-size=\"10\" fill=\"var(--text-muted)\">local @ rbp-0x18<\/text>\n<text x=\"34\" y=\"233\" font-size=\"13\" fill=\"var(--text)\">size_t <tspan fill=\"var(--text-muted)\">len<\/tspan><\/text>\n<rect x=\"410\" y=\"196\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"420\" y=\"214\" font-size=\"10\" fill=\"var(--text-muted)\">var_28 @ rbp-0x28<\/text>\n<text x=\"420\" y=\"233\" font-size=\"13\" fill=\"var(--green)\">ulong<\/text>\n<text x=\"686\" y=\"228\" text-anchor=\"end\" font-size=\"15\" fill=\"var(--green)\">\u2713<\/text><\/p>\n<p><rect x=\"24\" y=\"248\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"34\" y=\"266\" font-size=\"10\" fill=\"var(--text-muted)\">local @ rbp-0x20<\/text>\n<text x=\"34\" y=\"285\" font-size=\"13\" fill=\"var(--text)\">struct stat <tspan fill=\"var(--text-muted)\">st<\/tspan><\/text>\n<rect x=\"410\" y=\"248\" width=\"286\" height=\"46\" rx=\"3\" fill=\"var(--code-bg)\" stroke=\"var(--code-border)\" stroke-width=\"1\"\/>\n<text x=\"420\" y=\"266\" font-size=\"10\" fill=\"var(--text-muted)\">var_30 @ rbp-0x30<\/text>\n<text x=\"420\" y=\"285\" font-size=\"13\" fill=\"var(--red)\">undefined8<\/text>\n<text x=\"686\" y=\"280\" text-anchor=\"end\" font-size=\"15\" fill=\"var(--red)\">\u2717<\/text><\/p>\n<p><text x=\"360\" y=\"80\" text-anchor=\"middle\" font-size=\"9.5\" fill=\"var(--green)\"><tspan font-weight=\"bold\">[1]<\/tspan> ABI 0<\/text>\n<line x1=\"310\" y1=\"85\" x2=\"406\" y2=\"85\" stroke=\"var(--green)\" stroke-width=\"1.6\" marker-end=\"url(#tm-g)\"\/>\n<p><text x=\"360\" y=\"132\" text-anchor=\"middle\" font-size=\"9.5\" fill=\"var(--amber)\"><tspan font-weight=\"bold\">[1]<\/tspan> int \u2260 uint<\/text>\n<line x1=\"310\" y1=\"137\" x2=\"406\" y2=\"137\" stroke=\"var(--amber)\" stroke-width=\"1.6\" marker-end=\"url(#tm-a)\"\/>\n<p><text x=\"360\" y=\"214\" text-anchor=\"middle\" font-size=\"9.5\" fill=\"var(--green)\"><tspan font-weight=\"bold\">[2]<\/tspan> offset +0x10<\/text>\n<line x1=\"310\" y1=\"219\" x2=\"406\" y2=\"219\" stroke=\"var(--green)\" stroke-width=\"1.6\" marker-end=\"url(#tm-g)\"\/>\n<p><text x=\"360\" y=\"266\" text-anchor=\"middle\" font-size=\"9.5\" fill=\"var(--red)\"><tspan font-weight=\"bold\">[3]<\/tspan> missed struct<\/text>\n<line x1=\"310\" y1=\"271\" x2=\"406\" y2=\"271\" stroke=\"var(--red)\" stroke-width=\"1.6\" marker-end=\"url(#tm-r)\"\/>\n<\/svg><\/p>\n<p>\n<span class=\"pass\"><span class=\"k\">[1]<\/span> arguments by ABI position (name-independent)<\/span><br \/>\n<span class=\"pass\"><span class=\"k\">[2]<\/span> stack vars by calibrated frame offset<\/span><br \/>\n<span class=\"pass\"><span class=\"k\">[3]<\/span> remainder by exact name<\/span><br \/>\n<span class=\"pass\"><span style=\"color:var(--green)\">\u2713<\/span> correct type \u00b7 <span style=\"color:var(--amber)\">\u2260<\/span> type mismatch \u00b7 <span style=\"color:var(--red)\">\u2717<\/span> missed<\/span>\n<\/p>\n<div class=\"viz-score\">\n<p>score = <span class=\"viz-dim\">matched-correct \/ recoverable<\/span> = <span class=\"viz-good\">2<\/span> <span class=\"viz-dim\">\/<\/span> 4 = <span class=\"viz-warn big\">0.50<\/span><\/p>\n<p><span class=\"viz-good\">1.0<\/span> \u2192 every recoverable variable typed correctly = perfect<\/p>\n<\/div>\n<p class=\"viz-note\">Only variables carrying a DWARF location count as <em>recoverable<\/em> \u2014 fully optimized-out vars are dropped for everyone, so the denominator is identical across decompilers. Arguments match by ABI position (name-independent, so angr&#8217;s <code>a1<\/code>\/<code>a2<\/code> get fair credit), stack locals by an auto-calibrated frame-offset shift (here <code>+0x10<\/code>, so ground-truth <code>-0x18<\/code> aligns to the decompiler&#8217;s <code>-0x28<\/code>), and the remainder by exact name.<\/p>\n<\/div>\n<\/details>\n<p> <span class=\"perfect\">perfect = 1.0 (every recoverable variable typed correctly).<\/span><\/div>\n<\/p><\/div>\n<div class=\"goal\">\n<p><span class=\"num\">[3]<\/span>Recompilation correctness<\/p>\n<p>metric: Recompilation Bytematch<\/p>\n<div class=\"goal-body\">\n<p>Does the decompiled code recompile to the same machine code? We run a uniform compilability fixup (define decompiler pseudo-types, strip illegal symbol-version tokens, declare missing symbols) so every decompiler gets a fair shot at building, recompile each function with the original toolchain, and compare the resulting assembly \u2014 normalizing link-time-dependent operands (call\/jump targets, PC-relative offsets) so only real differences count.<\/p>\n<p>The leaderboard&#8217;s <strong>Compiles<\/strong> column reports the first half of this on its own \u2014 the share of a decompiler&#8217;s output that the fixup got to build at all (before any assembly comparison). It is measured only where a matching recompiler exists (x86); ARM\/PE firmware and malware abstain rather than count as failures.<\/p>\n<details class=\"metric-viz\" open=\"\">\n<summary>how bytematch works: fixup \u2192 recompile \u2192 normalized asm diff<\/summary>\n<div class=\"viz-wrap\">\n<div class=\"viz-row\">\n<p>A \u00b7 rebuild the decompiler&#8217;s own C, the same way the original was built<\/p>\n<p>\n<span class=\"viz-chip is-in\">decompiled .c<\/span><br \/>\n<span class=\"viz-parrow\">\u2014<b>\u00a0compilability fixup\u00a0<\/b>\u2192<\/span><br \/>\n<span class=\"viz-chip\">buildable .c<\/span><br \/>\n<span class=\"viz-parrow\">\u2014<b>\u00a0recompile\u00a0<\/b>\u2192<\/span><br \/>\n<span class=\"viz-chip is-out\">assembly<\/span><br \/>\n<span class=\"viz-dim\">\u00a0(same toolchain &amp; -O flags as the source: x86\u2192gcc, ARM\u2192arm-eabi, PE\u2192MinGW)<\/span>\n<\/p>\n<div class=\"viz-grid\">\n<div class=\"viz-panel\">\n<p>decompiled .c \u2014 pseudo-types injected by the fixup<\/p>\n<pre class=\"viz-code\" data-lang=\"c\"><code>undefined4 scale(int a) {\n    uint x = a * 3;\n    log_val(x);\n    return x + limit;\n}<\/code><\/pre>\n<p>The fixup adds only <code style=\"color:var(--green)\">typedef<\/code>s for <span class=\"tok-type\">undefined4<\/span>\/<span class=\"tok-type\">uint<\/span> \u2014 never rewrites logic<\/p>\n<\/div>\n<div class=\"viz-panel\">\n<p>recompiled assembly (-O2, x86-64)<\/p>\n<pre class=\"viz-code\" data-lang=\"asm\"><code>scale:\n    push   rbx\n    imul   ebx, edi, 3\n    mov    edi, ebx\n    call   log_val\n    mov    eax, ebx\n    add    eax, [rip+limit]\n    pop    rbx\n    ret<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"viz-row\">\n<p>B \u00b7 diff the recompiled bytes against the original .text<\/p>\n<div class=\"viz-diff\">\n<p><span class=\"h-mk\"\/><span>original .text<\/span><span>recompiled<\/span><\/p>\n<p><span class=\"dl-mk\">\u2713<\/span><code class=\"dl-gt\">push   rbx<\/code><code>push   rbx<\/code><\/p>\n<p><span class=\"dl-mk\">\u2717<\/span><code class=\"dl-gt\">lea    ebx, [rdi+rdi*2]<\/code><code>imul   ebx, edi, 3<\/code><\/p>\n<p><span class=\"dl-mk\">\u2713<\/span><code class=\"dl-gt\">mov    edi, ebx<\/code><code>mov    edi, ebx<\/code><\/p>\n<p><span class=\"dl-mk\">\u2248<\/span><code class=\"dl-gt\">call   <span class=\"dl-op\">____<\/span><\/code><code>call   <span class=\"dl-op\">____<\/span><\/code><\/p>\n<p><span class=\"dl-mk\">\u2713<\/span><code class=\"dl-gt\">mov    eax, ebx<\/code><code>mov    eax, ebx<\/code><\/p>\n<p><span class=\"dl-mk\">\u2248<\/span><code class=\"dl-gt\">add    eax, [rip+<span class=\"dl-op\">____<\/span>]<\/code><code>add    eax, [rip+<span class=\"dl-op\">____<\/span>]<\/code><\/p>\n<p><span class=\"dl-mk\">\u2713<\/span><code class=\"dl-gt\">pop    rbx<\/code><code>pop    rbx<\/code><\/p>\n<p><span class=\"dl-mk\">\u2713<\/span><code class=\"dl-gt\">ret<\/code><code>ret<\/code><\/p>\n<\/div>\n<p>\n<span class=\"pass\"><span style=\"color:var(--green)\">\u2713<\/span> identical line<\/span><br \/>\n<span class=\"pass\"><span style=\"color:var(--amber)\">\u2248<\/span> matches after normalizing a link-time operand (<span class=\"dl-op\">____<\/span> = <code>call<\/code> target \/ <code>[rip+disp]<\/code>)<\/span><br \/>\n<span class=\"pass\"><span style=\"color:var(--red)\">\u2717<\/span> real difference (edit distance = changed asm lines)<\/span>\n<\/p>\n<div class=\"viz-score\">\n<p>byte_match = <span class=\"viz-dim\">matching \/ total<\/span> = <span class=\"viz-good\">7<\/span> <span class=\"viz-dim\">\/<\/span> 8 = <span class=\"viz-good big\">0.88<\/span><\/p>\n<p><span class=\"viz-good\">1.0<\/span> \u2192 recompiled assembly matches the original = perfect<\/p>\n<\/div>\n<\/div>\n<p class=\"viz-note\">Recompilation Bytematch rebuilds the decompiler&#8217;s own C the SAME way the original was built \u2014 toolchain and <code>-O*\/-m*<\/code> flags read from the DWARF producer \u2014 then compares assembly line by line. A compilability fixup injects <em>only<\/em> what gcc reports missing (typedefs for pseudo-types like <code>undefined4<\/code>\/<code>uint<\/code>, decls for implicit functions) and never rewrites logic. Link-time-dependent operands \u2014 <code>call<\/code>\/branch targets and <code>[rip\u00b1disp]<\/code> displacements \u2014 are normalized away, so an unlinked address difference is not a penalty. Type recovery is scored separately (type_match), so fixing types just to compile is fair.<\/p>\n<\/div>\n<\/details>\n<p> <span class=\"perfect\">perfect = 1.0 (recompiled assembly matches the original).<\/span><\/div>\n<\/p><\/div>\n<p>\n    [ = ] When a function is perfect on <strong>at least one<\/strong> metric,<br \/>\n    the decompiler has exactly recovered that aspect of the original source:<br \/>\n    the control flow, the types, or code that recompiles to the same bytes.<br \/>\n    That is the Union column on the leaderboard.\n<\/p>\n<h2>metric limitations<\/h2>\n<p class=\"view-desc\">Each metric comes with limitations, some due to the way they are measured, others due to their fundamental algorithm.<\/p>\n<p class=\"view-desc\">he first, and most wide-reaching limitation, is that we attempt to collect all metrics from only the decompilation text.<br \/>\nThis is to assure that <em>all<\/em> decompilers can compete on the benchmark even when they do not expose deep APIs.<br \/>\nThis also allows LLMs to compete, which may have no way to return to you something like an address mapping for a line reliably.<br \/>\nThis can inject error because things like variables may be hard to align across samples, which has been <a href=\"https:\/\/arxiv.org\/abs\/2502.04536\">explored in prior work<\/a>.<\/p>\n<h3 class=\"sub\">Graph Edit Distance<\/h3>\n<p class=\"view-desc\">Every CFG pair receives an exact isomorphism test first, with no size limit, so a perfect graph is always scored correctly.<br \/>\nNon-isomorphic graphs up to 200 nodes use the <a href=\"https:\/\/github.com\/mahaloz\/cfgutils\/blob\/main\/cfgutils\/similarity\/ged\/vujosevic_janicic_ged.py\">Vujosevic Janicic<\/a> algorithm (VJ-GED).<br \/>\nLike most GED algorithms, VJ-GED is an approximation and can report more distance than actually exists.<br \/>\nLarger non-isomorphic graphs use a nonzero lower bound from their node and edge count differences.<\/p>\n<p class=\"view-desc\">There are other ways to inject error here.<br \/>\nWe largely use <a href=\"https:\/\/joern.io\/\">Joern<\/a> to parse the decompilation of each project.<br \/>\nIf Joern fails, we fail.<br \/>\nThere is also ways the <code>.i<\/code> files, which we parse, can have false information left behind by the compiler.<br \/>\nWhen we sampled this process, we found it was small.<\/p>\n<h3 class=\"sub\">Type Edit Distance<\/h3>\n<p class=\"view-desc\">The fundamental flaw here is being unable to match a variable across a decompiler sample if the offset is not reported in the text.<br \/>\nWe attempt to get around this by using heuristics, but, it is a known problem.<\/p>\n<h3 class=\"sub\">Recompilation Byte Edit Distance<\/h3>\n<p class=\"view-desc\">The flaw here is that each function is evaluated alone.<br \/>\nThere are cases where cross-function compiler optimizations can make it impossible for a decompiler to achieve a perfect score.<br \/>\nThis is more common on the optimization dataset, and is a known limitation.<\/p>\n<h2>the dataset<\/h2>\n<h3 class=\"sub\">summary<\/h3>\n<h3 class=\"sub\">projects<\/h3>\n<\/section>\n<section class=\"view\" id=\"view-changelog\" data-view=\"changelog\">\n<h2 class=\"view-title\">Changelog<\/h2>\n<p class=\"view-desc\">Significant changes to DecBench that introduce or update results, which can be viewable on the website.<\/p>\n<h3 class=\"sub\">2026-08-28<\/h3>\n<ul>\n<li>Added the Ventris decompiler.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-08-27<\/h3>\n<ul>\n<li>Added dated scoreboard snapshots. Any page accepts <code>?snapshot=DD-MM-YYYY<\/code> to render<br \/>\nthe numbers as they stood on that day, and <code>\/snapshots\/<\/code> lists them.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-08-08<\/h3>\n<ul>\n<li>Update <code>Kuna<\/code> to version <code>v1.121<\/code>, which has changed its rank.<\/li>\n<li>Minor fix to GED correctness in <a href=\"https:\/\/github.com\/Noelo-Lab\/decbench\/pull\/57\">PR #57<\/a>. Changes the scores of all decompilers on structure, but has largely maintained the same order.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-07-27<\/h3>\n<ul>\n<li>Added a warning about LLM based results having bias, based on <a href=\"https:\/\/github.com\/Noelo-Lab\/decbench\/issues\/43#issuecomment-5093320127\">Issue #43<\/a> discussion and analysis.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-07-25<\/h3>\n<ul>\n<li>Fixed a caching bug in <code>sample-set<\/code> that prevented Codex\/CC from having 3 samples graded\/shown in the UI. Their scores have changed slightly.<\/li>\n<li>External submission to DecBench are now open and can be done for closed source or private decompilers. See the <a href=\"https:\/\/github.com\/Noelo-Lab\/decbench#compete-externally\">README note<\/a> for how.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-07-24<\/h3>\n<ul>\n<li>Updated <code>about<\/code> to include other related works and some limitations of the benchmark metrics.<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-07-23<\/h3>\n<ul>\n<li>DecBench v1.1<\/li>\n<li>Update <code>Kuna<\/code> to version <code>v1.0<\/code>, which have shifted optimized results.<\/li>\n<li>What was previously the <code>distance<\/code> page is now the <code>data<\/code> page and contains new info on LLM costs.<\/li>\n<li>Removed <code>mirai-win<\/code> target since it is not actually Windows, but just Linux binaries (which the benchmark already has).<\/li>\n<\/ul>\n<h3 class=\"sub\">2026-07-22<\/h3>\n<ul>\n<li><strong>DecBench goes live<\/strong> with support for 7 traditional decompilers, 2 LLMs (partial), and 3 defining metrics.<\/li>\n<li>An expanded evaluation of AI agents is planned after credits are secured for running those evaluations.<\/li>\n<\/ul>\n<\/section>\n<section class=\"view\" id=\"view-snapshots\" data-view=\"snapshots\">\n<h2 class=\"view-title\">snapshots<\/h2>\n<p class=\"view-desc\">A snapshot freezes the scoreboard on a given day, so a score you cite keeps a<br \/>\nstable link after the benchmark moves on. Open one by adding<br \/>\n<code>?snapshot=DD-MM-YYYY<\/code> to any page, or follow a date below.<\/p>\n<p class=\"view-desc\">Snapshots are recorded deliberately, not on a schedule \u2014 one is taken whenever a<br \/>\nchange moves published scores or breaks comparability, which is the same moment<br \/>\nthe <a href=\"#changelog\">changelog<\/a> earns an entry. Use the filters to find the<br \/>\nsnapshots where a decompiler was on a particular version.<\/p>\n<p class=\"view-desc\">Each snapshot carries the leaderboard, metrics, data and about pages exactly as<br \/>\nthey stood. The <a href=\"#view\">view<\/a> page is the one exception: its side-by-side source<br \/>\nis ~31 MB per build, far too heavy to freeze per date, so it always shows live<br \/>\ncode.<\/p>\n<\/section>\n<footer>DecBench v1.0 \u2014 decompiler benchmarking suite \u00b7 projects: base-passwd, bash, betaflight, bzip2, chibios, cleanflight, coreutils, crazyflie, cronie, dexter, diffutils, dpkg, e2fsprogs, findutils, freertos, gnutls, grep, gzip, iproute2, kmod, libacl, libbsd, libedit, libexpat, libopencm3, libselinux, minipig, mirai, mydoom, nuttx, openssh-portable, riot-os, rsyslog, shadow, sysvinit, tar, u-boot, x0r-usb, zlib<\/footer>\n<\/p><\/div>\n<p><a href=\"https:\/\/decbench.com\/?utm_source=tldrinfosec\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>leaderboard Decompilers have advanced significantly over the last 30 years, quickly approaching the point where they can recover the exact source code from various binaries. This benchmark ranks decompilers by their ability to recover exact source code, measured across three metrics. All metrics are shown as the percentage of functions on which a decompiler achieves [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":23850,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[143],"tags":[],"class_list":["post-23849","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"_links":{"self":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/comments?post=23849"}],"version-history":[{"count":0,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23849\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media\/23850"}],"wp:attachment":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media?parent=23849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/categories?post=23849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/tags?post=23849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}