Skip to content

Mitriyweb/upload-analyzer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

47 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Upload Analyzer

A WebAssembly-powered binary file analyzer built with Rust.

Features

  • Multi-Format Analysis: PE (Windows), MSI (Windows), DMG (macOS), DEB (Linux), RPM (Linux)
  • PE Metadata Extraction: Version info, company, product details, timestamps
  • 32-bit & 64-bit Support: Handles both x86 and x64 PE files
  • WebAssembly: Runs directly in the browser with native Rust performance
  • Production Ready: Minified JS, optimized WASM builds
  • TypeScript Support: Full type definitions with IntelliSense

Tech Stack

Backend:

  • Rust - Core analysis engine
  • goblin - Multi-format binary parsing (PE)
  • pelite - Advanced PE file analysis
  • cfb - Compound File Binary format parsing (MSI)
  • wasm-bindgen - Rust/JavaScript interop

Frontend:

  • Vanilla JavaScript (ES6 modules)
  • Terser - JavaScript minification

Prerequisites

  1. Rust - Install from https://rustup.rs/

  2. wasm-pack - Install via:

    cargo install wasm-pack
  3. Node.js - For development server and minification

Development

Development Mode (with unminified JS)

# Build WASM only
npm run build

# Start dev server (uses dev/app.js - unminified)
npm run dev

Opens at http://localhost:8888/dev/ with unminified JavaScript for debugging.

Production Mode (with minified JS)

# Full build (WASM + minification)
./build.sh

# Start production server (uses public/app.min.js - minified)
npm run serve

Opens at http://localhost:8888/public/ with optimized code.

Code Quality \u0026 Linting

The project uses automated tools to maintain code quality and detect dead code:

Linting Commands

# Run all lints (Rust clippy, TypeScript ESLint, Knip, cargo-machete)
npm run lint

# Individual linters
npm run lint:rust          # Rust clippy
npm run lint:ts            # TypeScript ESLint
npm run lint:knip          # Dead code detection (TypeScript/JavaScript)
npm run lint:rust:deps     # Unused dependencies (Rust)

Dead Code Detection

Knip (TypeScript/JavaScript):

  • Detects unused files, exports, dependencies, and types
  • Configuration: knip.json
  • Ignores: generated files (pkg/, dist/), examples

cargo-machete (Rust):

  • Detects unused Rust dependencies in Cargo.toml
  • Configuration: [package.metadata.cargo-machete] in Cargo.toml
  • Install globally: cargo install cargo-machete

Pre-commit Hooks

Pre-commit hooks automatically run linters before commits:

# Install hooks (runs automatically after npm install)
npm run prek:install

# Run hooks manually on all files
npm run prek:run

# Bypass hooks (use sparingly)
git commit --no-verify

Handling False Positives

Knip: Add to knip.json:

{
  "ignoreDependencies": ["package-name"],
  "ignore": ["path/to/file/**"]
}

cargo-machete: Add to Cargo.toml:

[package.metadata.cargo-machete]
ignored = ["crate-name"]

Project Structure

upload-analyzer/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ rs/                # Rust source code
β”‚   β”‚   β”œβ”€β”€ lib.rs         # Main Rust entry point
β”‚   β”‚   β”œβ”€β”€ pe.rs          # PE file analysis module
β”‚   β”‚   β”œβ”€β”€ msi.rs         # MSI file analysis module
β”‚   β”‚   β”œβ”€β”€ dmg.rs         # DMG file analysis module
β”‚   β”‚   β”œβ”€β”€ deb.rs         # DEB file analysis module
β”‚   β”‚   └── rpm.rs         # RPM file analysis module
β”‚   β”‚
β”‚   └── ts/                # TypeScript source code
β”‚       β”œβ”€β”€ helpers.ts     # Type guards and parsers (source)
β”‚       β”œβ”€β”€ types/         # TypeScript definitions
β”‚       β”‚   β”œβ”€β”€ index.d.ts # Main type definitions
β”‚       β”‚   └── README.md  # Types documentation
β”‚       └── examples/      # Usage examples (not published)
β”‚           └── typescript-usage.ts
β”‚
β”œβ”€β”€ dist/                  # Compiled TypeScript (auto-generated)
β”‚   β”œβ”€β”€ helpers.js
β”‚   └── helpers.d.ts
β”‚
β”œβ”€β”€ dev/                   # Development demo
β”‚   β”œβ”€β”€ index.html         # Dev page
β”‚   └── app.js             # UI JavaScript (unminified)
β”‚
β”œβ”€β”€ public/                # Production demo
β”‚   β”œβ”€β”€ index.html         # Production page
β”‚   β”œβ”€β”€ app.min.js         # Bundled JS + WASM loader (auto-generated)
β”‚   └── upload_analyzer_bg.wasm # WASM binary (auto-generated)
β”‚
β”œβ”€β”€ pkg/                   # NPM package (auto-generated)
β”‚   β”œβ”€β”€ upload_analyzer.js
β”‚   β”œβ”€β”€ upload_analyzer_bg.js
β”‚   β”œβ”€β”€ upload_analyzer.d.ts # TypeScript definitions
β”‚   └── upload_analyzer_bg.wasm
β”‚
β”œβ”€β”€ scripts/               # Build scripts
β”‚   └── bundle-single.js   # Production bundler
β”‚
β”œβ”€β”€ .well-known/          # Browser config
β”œβ”€β”€ Cargo.toml            # Rust dependencies
β”œβ”€β”€ package.json          # Node.js dependencies
β”œβ”€β”€ tsconfig.json         # TypeScript configuration
β”œβ”€β”€ build.sh              # Build script
└── README.md

Key Directories:

  • src/rs/ - Rust source code
  • src/ts/ - TypeScript source code, type definitions, and examples
  • dist/ - Compiled TypeScript output
  • dev/ - Development demo with unminified JavaScript
  • public/ - Production-ready demo (3 files: HTML, JS, WASM)
  • pkg/ - NPM package with TypeScript definitions (auto-generated)
  • scripts/ - Build and bundling scripts

NPM Package Publishing

To publish this library to npm:

# Build everything (WASM + production demo)
./build.sh

# Or just build the NPM package
npm run build

# Publish to npm
cd pkg
npm publish

The pkg/ folder contains:

  • upload_analyzer.js - Main entry point
  • upload_analyzer_bg.js - WASM glue code
  • upload_analyzer.d.ts - TypeScript definitions
  • upload_analyzer_bg.wasm - WebAssembly binary (~223 KB)
  • package.json - Package metadata

Package Features:

  • βœ… Full TypeScript support
  • βœ… Works with bundlers (webpack, rollup, vite)
  • βœ… Tree-shakeable ES modules
  • βœ… Optimized for production

Deployment

The public/ folder is production-ready and contains only 3 files (~235 KB total):

./build.sh    # Build everything

Then deploy the entire public/ folder to any static host:

  • Netlify
  • Vercel
  • GitHub Pages
  • AWS S3
  • Any CDN or web server

What's in public/:

  • index.html - Main page
  • app.min.js - Bundled JavaScript with WASM loader (6.4 KB)
  • upload_analyzer_bg.wasm - WebAssembly binary (228 KB)

Usage

TypeScript (Recommended)

Full type safety with IntelliSense support:

import init, { analyze_pe_file, get_file_info } from 'upload-analyzer';
import type { FileAnalysis, PEAnalysis } from 'upload-analyzer/types';
import { isPEAnalysis, isAnalysisError } from 'upload-analyzer/helpers';

// Initialize WASM
await init();

// Analyze file
const file = await fetch('example.exe').then(r => r.arrayBuffer());
const data = new Uint8Array(file);

const result = analyze_pe_file(data);
const analysis = JSON.parse(result) as FileAnalysis;

if (isAnalysisError(analysis)) {
  console.error('Error:', analysis.error);
} else if (isPEAnalysis(analysis)) {
  // TypeScript knows all available fields
  console.log('Company:', analysis.CompanyName);      // βœ“ Autocomplete
  console.log('Product:', analysis.ProductName);      // βœ“ Type-safe
  console.log('Version:', analysis.FileVersionNumber); // βœ“ IntelliSense
  console.log('Signed by:', analysis.SignedBy);

  if (analysis.InstallerType) {
    console.log('Installer:', analysis.InstallerType);
  }
}

See types/README.md for complete TypeScript documentation.

In Browser (with bundler)

import * as analyzer from 'upload-analyzer';

// Initialize
analyzer.init();

// Read file
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const buffer = await file.arrayBuffer();
  const data = new Uint8Array(buffer);

  try {
    // Get basic file info
    const info = analyzer.get_file_info(data);
    console.log('File info:', JSON.parse(info));

    // Analyze PE file
    const analysis = analyzer.analyze_pe_file(data);
    console.log('Analysis:', JSON.parse(analysis));
  } catch (error) {
    console.error('Analysis failed:', error);
  }
});

In Node.js

const fs = require('fs');
const analyzer = require('upload-analyzer');

// Read file
const data = fs.readFileSync('example.exe');
const buffer = new Uint8Array(data);

// Get file info
const info = analyzer.get_file_info(buffer);
console.log('File info:', JSON.parse(info));

// Analyze PE file
try {
  const analysis = analyzer.analyze_pe_file(buffer);
  const result = JSON.parse(analysis);

  console.log('Format:', result.Format);
  console.log('Architecture:', result.architecture);
  console.log('Sections:', result.sections);
  console.log('Imports:', result.imports);
  console.log('Exports:', result.exports);
} catch (error) {
  console.error('Analysis failed:', error);
}

API

init()

Initialize the WASM module. Call this once before using other functions.

get_file_info(data: Uint8Array): string

Get basic information about a binary file.

Parameters:

  • data: Uint8Array containing the file data

Returns: JSON string with file information

analyze_pe_file(data: Uint8Array): string

Perform detailed analysis of a PE file.

Parameters:

  • data: Uint8Array containing the PE file data

Returns: JSON string with analysis results including:

  • Format: Type of file (PE, MSI, DMG, DEB, RPM)
  • architecture: CPU architecture (x86, x86_64)
  • sections: Array of section information
  • imports: List of imported functions
  • exports: List of exported functions
  • is_64bit: Boolean indicating 64-bit PE
  • entry_point: Entry point address

Example Output

{
  "Format": "PE",
  "architecture": "x86_64",
  "is_64bit": true,
  "entry_point": 4096,
  "sections": [
    {
      "name": ".text",
      "virtual_size": 8192,
      "virtual_address": 4096,
      "raw_data_size": 8192
    }
  ],
  "imports": [
    "ExitProcess (KERNEL32.dll)",
    "GetLastError (KERNEL32.dll)"
  ],
  "exports": [
    "MainFunction"
  ]
}

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

A WebAssembly-powered binary file analyzer built with Rust.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors