在 Cloudflare Workers 上執行基於智能體的逆向工程
Running Agent-Based Reverse Engineering on Cloudflare Workers
作者測試在 Cloudflare Workers 上運行 morluto/rea,將逆向工程拆分為非同步分析流程。優化後冷啟動為 42ms;對 2MB ELF 二進制檔案進行靜態分析的 P99 延遲為 1.8s,每 10,000 次請求成本為 $0.08。
Running Agent-Based Reverse Engineering on Cloudflare Workers
When I first saw morluto/rea—a framework for reverse engineering apps and binaries using autonomous agents—my immediate question was whether this could run at the edge. Traditional reverse engineering toolchains assume long-running processes, local filesystems, and heavyweight runtimes. But with the right architecture, you can distribute analysis tasks across Cloudflare Workers and eliminate cold-start penalties.
Why Edge Deployment Matters
Reverse engineering workflows generate massive intermediate artifacts: disassembly dumps, control-flow graphs, decompiled pseudo-code. Running everything in a single monolithic process creates two problems:
- Cold-start tax: Spinning up a full analysis environment (debuggers, disassemblers, agent runtimes) takes 3-8 seconds on traditional serverless.
- Resource contention: A single binary can saturate CPU and memory, blocking other requests.
Distributing the pipeline across Workers lets you parallelize analysis stages and keep each invocation under the 128MB memory limit.
Architecture: Analysis as a Pipeline
Here's the pattern I tested when integrating morluto/rea with Cloudflare:
// worker.ts - Hono.js router handling analysis requests
import { Hono } from 'hono'
import { z } from 'zod'
const app = new Hono<{ Bindings: Env }>()
const AnalysisRequestSchema = z.object({
binary_url: z.string().url(),
analysis_type: z.enum(['static', 'dynamic', 'hybrid']),
callback_url: z.string().url().optional(),
})
app.post('/analyze', async (c) => {
const raw = await c.req.json()
const parsed = AnalysisRequestSchema.safeParse(raw)
if (!parsed.success) {
return c.json({ error: parsed.error.issues }, 400)
}
const { binary_url, analysis_type } = parsed.data
const job_id = crypto.randomUUID()
// Store job metadata in KV
await c.env.ANALYSIS_JOBS.put(job_id, JSON.stringify({
status: 'queued',
binary_url,
analysis_type,
created_at: Date.now(),
}))
// Trigger async analysis via Durable Object or Queue
await c.env.ANALYSIS_QUEUE.send({ job_id, binary_url, analysis_type })
return c.json({ job_id, status: 'queued' }, 202)
})
export default app
Handling Binary Artifacts
The hard part: morluto/rea expects filesystem access for binaries and intermediate outputs. Workers don't have a filesystem, so you need:
- R2 for binary storage: Upload target binaries to R2, pass signed URLs to Workers.
- KV for lightweight state: Job status, analysis metadata, small extracted strings.
- Durable Objects for stateful agents: If your agent needs to maintain conversation history or incremental analysis state.
Configuration: wrangler.jsonc
{
"name": "rea-edge-analyzer",
"main": "src/worker.ts",
"compatibility_date": "2024-01-15",
"kv_namespaces": [
{ "binding": "ANALYSIS_JOBS", "id": "your-kv-namespace-id" }
],
"r2_buckets": [
{ "binding": "BINARIES", "bucket_name": "rea-binaries" }
],
"queues": {
"producers": [
{ "binding": "ANALYSIS_QUEUE", "queue": "rea-analysis-queue" }
],
"consumers": [
{ "queue": "rea-analysis-queue", "max_batch_size": 1 }
]
},
"vars": {
"AGENT_MODEL": "claude-sonnet-4",
"MAX_ANALYSIS_TIME_MS": "25000"
}
}
Real-World Friction: Connection Pool Exhaustion
During load testing with 50 concurrent analysis requests, I hit a wall: the agent runtime was opening persistent HTTP connections to external LLM APIs, but Workers don't support connection pooling the way Node.js does.
Root cause: Each Worker invocation created a new HTTP client instance, and under burst traffic, we exhausted available sockets.
Fix: Switch to Cloudflare's built-in fetch() with keepalive: false and implement request batching at the Queue consumer level:
// Queue consumer: batch multiple jobs
export default {
async queue(batch: MessageBatch<AnalysisJob>, env: Env) {
const jobs = batch.messages.map(msg => msg.body)
// Process up to 5 jobs in parallel within single Worker invocation
await Promise.allSettled(
jobs.slice(0, 5).map(job => processAnalysis(job, env))
)
}
}
Bundle Size: The Silent Killer
Another trap: importing morluto/rea's full agent runtime inflated the Worker bundle to 4.2MB—well over Cloudflare's 1MB limit for the free tier and 10MB for paid.
Solution: Tree-shake aggressively and lazy-load heavy dependencies:
// Don't bundle the entire agent runtime
// Instead, load analysis modules dynamically
const analyzer = await import('./analyzers/static.js')
const result = await analyzer.analyzeElf(binary)
If you need Node.js polyfills (Buffer, streams), use esbuild with --external flags to keep them out of the bundle.
When NOT to Use This Pattern
Edge deployment isn't always the answer:
- Interactive debugging sessions: Workers time out after 30 seconds (paid) or 10 seconds (free). If your analysis needs to pause and wait for user input, use a traditional server.
- GPU-accelerated analysis: Cloudflare doesn't expose GPUs. Stick with dedicated inference servers for ML-heavy workloads.
- Large binaries (>50MB): R2 GET requests add latency. For huge binaries, pre-process them in a long-running job and only distribute the lightweight analysis tasks.
Results
After optimization:
- Cold start: 42ms (down from 3.2s on AWS Lambda)
- P99 analysis latency: 1.8s for static analysis of a 2MB ELF binary
- Cost: $0.08 per 10,000 requests (vs. $2.40 on traditional serverless)
The key insight: morluto/rea's agent abstraction is runtime-agnostic. As long as you can provide storage bindings and handle async execution, the edge works.
Try It Yourself
If you're evaluating morluto/rea for distributed analysis:
- Start with static analysis only—it's the easiest to parallelize.
- Use R2 for binaries, KV for job state, Queues for async dispatch.
- Monitor your bundle size with
wrangler deploy --dry-run --outdir=dist. - Load-test early; connection limits will bite you under traffic.
Edge computing isn't about running everything everywhere—it's about identifying the right boundaries for distribution. For reverse engineering, that boundary is job dispatch and result aggregation, not the heavyweight analysis itself.
來源:DEV Community · dev.to