This project provides a web frontend and backend for x86-64 Windows binary analysis and transformation. It combines function discovery, symbol analysis, disassembly, control-flow analysis, and per-function transformation controls in one interface.
Upload a Portable Executable (PE) file to find its functions. You can also upload a matching Program Database (PDB) file to add symbol names and module information. The PDB file is optional. The application is designed for fast analysis of large native PDB files.
Warning
This project is experimental. Do not upload a sensitive file to a server that you do not control.
This repository is an experimental prototype. The PE and PDB analysis code and
the RawPDB helper are included. The external Remill-based transformation
executable and its LLVM runtime files are not included. Analysis works without
that executable, but transformations require RECOMPILER_PATH.
Disassembly and control-flow graphs require llvm-objdump.exe. Configure
RECOMPILER_OBJDUMP when it is not supplied beside the transformation
executable.
The API has no user authentication or rate limiting. Add the controls in the production deployment section before you expose it to the internet.
- Validate x86-64 PE files before analysis.
- Analyze a PE file with or without a PDB file.
- Verify the GUID and age of a supplied PDB file.
- Find functions from PDB symbols or PE unwind data.
- Preserve names such as
main, exported names, and the PE entry point. - Assign a
sub_<virtual-address>name when no symbol name exists. - Group functions by source and category.
- Show Intel-syntax disassembly for each function.
- Show an interactive control-flow graph (CFG).
- Follow direct call and jump targets from the CFG.
- Apply allowlisted obfuscation or deobfuscation passes to selected functions.
- Transform as many as 32 functions in one request and download the resulting PE file.
- Cache analyzed uploads for later disassembly requests.
- Use RawPDB for fast native PDB analysis.
- Process RawPDB results through a compact binary protocol.
- Compress large JSON responses with gzip.
- Paginate large function lists in the browser.
The RawPDB helper memory-maps each PDB file. It reads only the streams that are necessary for function analysis. It sends function records to the backend through a compact binary protocol.
The backend caches each validated analysis result. Disassembly requests use the cached result and do not upload or analyze the files again. Gzip responses and browser pagination reduce the cost of large function lists.
| Component | Technology | Purpose |
|---|---|---|
frontend |
SolidJS, TypeScript, Vite | Displays functions, disassembly, CFGs, and transformation controls. |
backend |
Go | Validates uploads and provides the analysis and transformation API. |
rawpdb-helper |
C++ and RawPDB | Reads large native PDB files. |
| External tools | LLVM and the private Remill recompiler | Provide disassembly and optional PE transformation. |
Install these tools before you build the complete application:
- Windows on an x86-64 computer
- Go 1.25 or later
- Node.js and npm
- CMake 3.20 or later
- Microsoft Visual C++ build tools
Install LLVM when you want disassembly and CFG support. Supply the external Remill recompiler and its runtime files only when you want transformations.
Copy the example environment file:
Copy-Item .env.example .envThe backend loads .env from the repository root. A process environment
variable has priority over the same variable in .env.
This step is optional. Without the helper, the backend uses its Go PDB parser.
Run these commands from the repository root:
cmake -S rawpdb-helper -B rawpdb-helper/build -A x64
cmake --build rawpdb-helper/build --config Release --parallelThe backend automatically finds this output file:
rawpdb-helper/build/bin/Release/rawpdb_analyzer.exe
Set RECOMPILER_OBJDUMP in .env to the full path of llvm-objdump.exe when
you want disassembly and CFG support:
RECOMPILER_OBJDUMP=C:\Program Files\LLVM\bin\llvm-objdump.exeThe transformation executable is not part of this repository. If you have a
compatible build, set its path in .env:
RECOMPILER_PATH=./recompiler/remill_recompiler.exeThe backend also accepts a directory that contains remill_recompiler.exe.
See backend/README.md for LLVM and Remill runtime-path
overrides.
Set-Location backend
go run .The API uses port 8080 on all network interfaces by default. Use
http://127.0.0.1:8080 from the local computer.
Open a second PowerShell terminal. Run these commands:
Set-Location frontend
npm.cmd install
npm.cmd run devOpen http://localhost:5173. The Vite development server sends /api
requests to http://127.0.0.1:8080.
- Select one x86-64
.exe,.dll, or.sysfile. - Select its native PDB file if one is available.
- Select Analyze.
- Select a function to see its details.
- Open Disassembly or Control flow.
- Open Transformations to apply an available obfuscation or deobfuscation pass.
The backend rejects a PDB file when its GUID or age does not match the PE file.
Set these values in .env or in the process environment:
| Variable | Default | Description |
|---|---|---|
ADDR |
:8080 |
Sets the API listen address. |
RECOMPILER_PATH |
Not set | Sets the external transformation executable or its directory. |
RECOMPILER_RAWPDB |
Automatic | Sets the RawPDB helper path. |
RECOMPILER_OBJDUMP |
Automatic when bundled | Sets the llvm-objdump.exe path. |
RECOMPILER_MAX_UPLOAD_MIB |
1024 |
Sets the limit for each uploaded file. The range is 1 through 4096 MiB. |
RECOMPILER_CACHE_MIB |
4096 or larger |
Sets the disk-cache capacity. The range is 64 through 65536 MiB. |
RECOMPILER_ANALYSIS_WORKERS |
CPU-based | Sets Go parser workers for one job. The range is 1 through 64. |
RECOMPILER_ANALYSIS_JOBS |
CPU-based | Sets the number of simultaneous analysis jobs. The range is 1 through 16. |
RECOMPILER_LOG_FILE |
C:\ProgramData\recompiler\logs\backend.log |
Sets the backend log path. |
Set RECOMPILER_ENV_FILE in the process environment to select a different
environment file. Relative tool paths in .env are relative to the location
of that file.
| Variable | Default | Description |
|---|---|---|
DD_TRACE_ENABLED |
false |
Sends HTTP and analysis spans to the local Datadog Agent. |
DD_PROFILING_ENABLED |
false |
Sends runtime profiles to the local Datadog Agent. |
DD_AGENT_HOST |
127.0.0.1 |
Sets the Datadog Agent host for APM and profiling. |
DD_TRACE_AGENT_PORT |
8126 |
Sets the Datadog Agent trace port. |
DD_SERVICE |
binary-analysis-api |
Sets the correlated Datadog service name. |
DD_ENV |
development |
Sets the correlated Datadog environment. |
DD_VERSION |
dev |
Sets the deployed application version. |
The frontend uses these build variables. Copy frontend/.env.example to
frontend/.env.local to set them for local development.
| Variable | Default | Description |
|---|---|---|
VITE_API_URL |
Same origin | Sets the API origin for a production frontend build. |
VITE_DD_RUM_APPLICATION_ID |
Empty | Enables Browser RUM when this value and the client token are set. |
VITE_DD_RUM_CLIENT_TOKEN |
Empty | Sets the public RUM client token. Do not use an API key. |
VITE_DD_SITE |
datadoghq.com |
Sets the Datadog site. |
VITE_DD_SERVICE |
binary-analysis-web |
Sets the frontend service name. |
VITE_DD_ENV |
development |
Sets the frontend environment. |
VITE_DD_VERSION |
dev |
Sets the frontend release version. |
VITE_DD_SESSION_SAMPLE_RATE |
100 |
Sets the percentage of browser sessions to collect. |
VITE_DD_TRACE_SAMPLE_RATE |
100 |
Sets the percentage of RUM requests that inject trace context. |
All upload endpoints use multipart/form-data.
| Endpoint | Purpose |
|---|---|
GET /api/health |
Reports API availability. |
POST /api/analyze |
Validates uploads and returns function information. |
POST /api/disassemble |
Returns instructions, basic blocks, and CFG edges. |
POST /api/transform |
Applies allowlisted passes to as many as 32 verified functions. |
An analysis response contains a cacheId. Send this value in later requests.
This action prevents another upload of the PE and PDB files.
The cache keeps a maximum of 16 analyzed upload pairs. An unused entry expires after two hours. The backend removes all entries when it stops.
See backend/README.md for request fields and API limits.
The application accepts native Microsoft MSF 7.0 PDB files. It does not accept portable PDB files from managed .NET builds.
RawPDB memory-maps large PDB files and returns only function records. The Go backend verifies the PDB identity and each executable relative virtual address (RVA). The helper uses a pinned RawPDB revision under the BSD 2-Clause license.
The backend writes the same log messages to the console and this file:
C:\ProgramData\recompiler\logs\backend.log
Successful analysis responses include a Server-Timing header. It reports
upload, PDB analysis, and cache durations.
The function table displays 500 rows on each page. JSON responses use gzip when the browser accepts it.
The backend emits one-line JSON events for HTTP requests, analysis jobs, queue time, upload size, response size, and errors. It does not add file names, function addresses, cache IDs, or client IP addresses to these events.
The repository includes this Datadog Agent configuration:
datadog/conf.d/go.d/conf.yaml
Enable logs in C:\ProgramData\Datadog\datadog.yaml:
logs_enabled: trueRun these commands in PowerShell as an administrator:
New-Item -ItemType Directory -Force 'C:\ProgramData\Datadog\conf.d\go.d'
Copy-Item 'datadog\conf.d\go.d\conf.yaml' 'C:\ProgramData\Datadog\conf.d\go.d\conf.yaml' -Force
Restart-Service DatadogAgentThe Agent sends the logs with service binary-analysis-api, source go, and
tag env:production. Keep the Datadog API key in the Agent configuration.
Set DD_TRACE_ENABLED=true and DD_PROFILING_ENABLED=true to send backend
traces and profiles to the local Agent. HTTP requests include child spans for
queue wait, PE and PDB analysis, cache writes, disassembly, and transformations.
Correlated JSON logs include the trace ID and span ID.
Browser RUM is disabled until both RUM credentials are set in
frontend/.env.local. RUM masks user input and does not record sessions. It
collects resource, interaction, and long-task telemetry. Analysis actions do
not include file names or file contents.
The datadog/terraform directory contains six log-based metrics, four
monitors, a 30-day request-success SLO, a service dashboard, and a Synthetic
health check. Log-based metrics are billable Datadog custom metrics. Read
datadog/README.md before you apply the configuration.
Run the backend tests:
Set-Location backend
go test ./...Build the frontend:
Set-Location frontend
npm.cmd ci
npm.cmd run buildThe workflow in .github/workflows/windows-ci.yml builds the RawPDB helper,
tests and vets the backend, builds the frontend, and validates the Terraform
configuration on each push and pull request.
Do not use the Vite development server as a public server.
Build the frontend with npm.cmd run build. Serve the frontend/dist directory
with a production web server. Send /api requests to the Go backend, or set
VITE_API_URL before the frontend build.
Configure the public proxy for the maximum upload size and request duration. A large PDB file can take several minutes to upload through a slow connection.
Add these controls before a public deployment:
- Authentication
- Rate limits
- TLS
- Upload quotas
- Request logging
- File-retention controls
- Process isolation for native analysis tools
- The backend accepts only x86-64 PE files.
- The backend does not accept portable PDB files.
- A supplied PDB file must match the PE CodeView identity.
- An indirect branch cannot always produce a direct CFG target.
- Disassembly requires LLVM objdump.
- Transformations require a compatible external Remill recompiler and runtime files.
.
|-- .github/ Windows continuous-integration workflow
|-- backend/ Go API
|-- datadog/ Agent, RUM, dashboard, monitor, and SLO configuration
|-- frontend/ SolidJS web application
|-- rawpdb-helper/ RawPDB C++ helper
|-- .env.example Backend configuration example
`-- README.md Project documentation
Create a GitHub issue with these details:
- The operation that failed
- The complete error message
- The Windows version
- The Go, Node.js, and CMake versions
- The PE size and PDB size
Do not attach a private binary or PDB file to a public issue.
This repository does not yet include a project license. All rights are
reserved unless a license states otherwise. RawPDB keeps its BSD 2-Clause
license in rawpdb-helper/RAW_PDB_LICENSE.txt.