EVM Hack Analyzer
EVM Hack Analyzer is a static, backend-free, in-browser debugger that forks chain state at a historical transaction, replays it in an in-browser EVM (@ethereumjs/vm), pulls verified Solidity sources from Etherscan, and produces a pc-to-source-line map so researchers can step through a real exploit opcode-by-opcode or line-by-line. It supports both native replay of a historical tx hash and loading pre-built scripted exploit ZIPs from the companion evm-hack-poc dataset (mirroring DeFiHackLabs and crypto.training/hacks), letting users annotate the vulnerable line and exploit steps, then export/share a self-contained PoC via ZIP or IPFS. It's aimed at smart-contract vulnerability research and community-sourced exploit PoC archiving, entirely client-side with no server or persistent backend required.
How it works
The viewer forks state at block-1 using eth_getBalance / eth_getCode / eth_getStorageAt (deliberately not eth_getProof, since public providers cap it to a recent block window), then re-runs the tx in @ethereumjs/vm, recording every opcode across all call depths. Verified sources come from Etherscan V2 and are compiled in a Web Worker with their exact settings; bytecode is matched to build the pc → source-line map. State is fetched lazily one slot at a time, so heavy txs (hundreds of touched contracts) can take minutes.
There are two distinct load paths, chosen by format detection:
- A JSON with the
evm-hack-analyzer-pockind marker → native tx-replay path (re-runs a historical tx from dumped accounts). - A ZIP from
evm-hack-poc(or a runner JSON withslug + expected + accounts, no kind marker) → scripted-exploit path: loads dumped fork state, deploys/etches the attack contract, applies setup (vm.deal/warp/roll/store/dealToken), then records anattackFunction()orcallScriptcall. This path needs no RPC or Etherscan key — everything is in the bundle.
Preconditions
To generate a native PoC you need three things: a target tx hash, an archive RPC URL that serves historical eth_getBalance/getCode/getStorageAt (Infura, Alchemy, QuickNode), and an Etherscan V2 API key (one key covers all chains; chain id is auto-detected from the RPC). Loading an existing scripted ZIP/CID requires none of these.
What to do
Run locally:
npm install
npm run dev # http://localhost:5173
npm run build # static site → dist/
npm run previewTo self-host the whole app on IPFS (dist/ is built with Vite base: "./", so it works from any gateway subpath):
npx kubo add -r dist # or: ipfs add -r dist / Pinata "pin a folder"Share PoC links as https://<gateway>/ipfs/<siteCID>/#<pocCID> — the #<pocCID> hash is read on load and is gateway-path-agnostic. To contribute research, mark the vuln and steps, save the ZIP, and open a PR against evm-hack-poc; the maintainers plan to expand coverage beyond the original DeFiHackLabs set.
Caveats
- Same-block dependencies: state is forked at block-1, so a tx depending on an earlier tx in the same block may diverge (standard fork-testing caveat).
- Unverified/proxy contracts render as opcode-only — no source mapping. The vulnerability can still be anchored on any contract that does map.
- Source mapping requires a verified, bytecode-matching contract.
- Older ZIPs that embedded a full
poc-data/poc.jsonstill load; newer ZIPs split fork state and sources into separate files with a slimpoc-data/core.json.
Organisations named here
- DeFiHackLabs
Technologies named here
- EVM Hack Analyzer
- @ethereumjs/vm
- Etherscan V2 API
- Web Worker solc
- IPFS
- evm-hack-poc
- evm-hack-registry
- anvil
- Archive JSON-RPC providers
- kubo / ipfs CLI
- Solidity
- Ethereum
- Etherscan
- Pinata
Techniques named here
- Scripted exploit reproduction
- Bytecode-to-source mapping
Related in Offensive Security