BergssonForensics.
In this guide 01 / 10
FIELD REFERENCE 05   /   CODE & BEHAVIOR

Mod Analysis & Detections

A practical reference for identifying suspicious, disguised, or unfair Minecraft mods through trust validation, metadata review, mixin analysis, decompilation, and behavioral triage.

Listen to this guide40 min / AI narration
Download audio ↓

Code, tables and images may need the written guide.

Platform FocusMinecraft (Fabric / Forge)
Version1.0 — 2025
Sections10
4Classification Tiers
3Masked Client Types
4Confidence Levels
8+Artifact Sources
10+IoC Signal Types
§ 01

What Mod Analysis Actually Proves

To analyze unfair mods properly, it helps to think like the player trying to hide one. Most users are not building custom clients from scratch — they are downloading a jar, renaming it, bundling it into something else, or relying on a loader that makes the whole thing look normal. Mod analysis is therefore not just "is this file weird?" The real question is whether the file's claimed identity, technical behavior, and level of concealment all line up. If those three things do not match, you have something worth escalating.

In practice, mod analysis tries to answer four core questions: what the jar claims to be, whether the file is authentic, whether it can provide an unfair advantage, and whether it was built to hide that fact.

Outcome Classification
LegitimateIdentity, metadata, hash, and behavior all line up with an official release or a defensible custom build. No anomalies requiring escalation.
SuspiciousOne or more anomalies exist, but the capability or intent is not yet clearly established. Requires deeper review before a conclusion.
Malicious / UnfairThe jar contains automation, combat logic, packet manipulation, hidden overlays, or similar features that can reasonably provide an advantage.
InconclusiveThe file cannot be authenticated or read cleanly. The evidence does not yet support a firm conclusion in either direction.
Primary Artifact Sources
SourceWhat to CheckWhy It Matters
Jar name and versionBranding, claimed purpose, loader version, release naming conventionUseful for first-pass context, but very easy to fake
HashSHA-256 or SHA-512 compared to an official sourceA mismatch is one of the strongest single authenticity failures
Loader metadatafabric.mod.json, mods.toml, mcmod.info, manifest dataShows what the mod claims about itself and how it loads
Mixin configsTargets, injectors, overwritten methods, package layoutOften exposes real intent faster than class names do
Decompiled codeCombat, input, network, timing, GUI, config handlingPrimary source for proving actual capability
Resources and configsIcons, hidden modules, keybinds, default settings, language keysCan expose module names even when code is heavily obfuscated
Embedded librariesShaded jars, native files, custom loaders, decryptorsMay reveal second-stage payloads or bundled frameworks
Runtime behaviorNew files, network requests, overlays, toggles, packet changesConfirms how the mod behaves when actually loaded
Analyst Mindset

We are reporters. We document indicators, explain why they matter, and preserve confidence levels. We do not need to overstate. A clean report with moderate confidence is better than a dramatic report built on guesses.

§ 02

Classification of Suspicious Mods

A useful way to classify suspicious jars is to separate visibility from readability. Some clients are obvious and essentially admit what they are. Others hide behind a normal name, a copied icon, or a legitimate project. Others go one step further and make the code deliberately painful to read. This gives you three common groups in actual casework — each can still be unfair; the difference is how much work it takes to prove.

Three Common Groups
A
Obvious Public Clients
Clearly known clients, lightly hidden, often detected by quick scanners, in-game mod lists, or simple metadata review. The jar does not make a serious attempt to disguise its identity.
low effort to detectmetadata match
B
Masked but Readable Clients
Packaged to look normal — legitimate name, plausible icon, clean metadata — but decompilation still reveals module systems, combat features, click logic, or packet hooks without significant resistance.
moderate effortdecompilation reveals
C
Masked and Obfuscated Clients
Names, strings, and control flow are deliberately scrambled, forcing the analyst to work from structure, behavior, and technical side effects rather than readable identifiers. The highest-effort category to prove conclusively — but structural analysis still yields strong indicators.
high effortstructural analysisbehavioral signals
Practical Rule

Unknown does not equal malicious, and obfuscated does not equal cheat. What matters is capability, concealment, and inconsistency between the jar's story and the jar's behavior.

§ 03

Trust Validation Before Reverse Engineering

Before pulling classes apart, verify whether the jar is even authentic. A significant amount of time gets wasted reverse engineering files that could have been flagged in the first two minutes by hash comparison alone. Players can rename a jar in five seconds — they can also repackage a legitimate project with added code. Trust validation is what separates a cosmetic rename from an actually altered build.

For Fabric projects, fabric.mod.json is the primary metadata file, defining the mod ID, version, and entrypoints. For Forge, mods.toml under META-INF fills that role. These files tell you what the jar claims to be and how it expects to load.

Clean Validation Workflow
PowerShelltrust_validation.ps1
# Step 1: Hash every jar in the mods folder
$modsPath = "$env:APPDATA\.minecraft\mods"
Get-ChildItem $modsPath -Filter *.jar |
  Get-FileHash -Algorithm SHA256 |
  Sort-Object Path |
  Select-Object Path, Hash

# Step 2: Unpack jar for inspection
# A .jar is a ZIP archive — rename or extract directly
Expand-Archive "suspect.jar" -DestinationPath ".\unpacked\" -Force

# Step 3: Read loader metadata
Get-Content ".\unpacked\fabric.mod.json"    # Fabric
Get-Content ".\unpacked\META-INF\mods.toml"  # Forge
Get-Content ".\unpacked\META-INF\MANIFEST.MF" # Manifest

# Step 4: List mixin configuration files
Get-ChildItem ".\unpacked" -Filter *.json -Recurse |
  Where-Object { $_.Name -match 'mixin' } |
  Select-Object FullName
This workflow completes trust validation in under 2 minutes for most jars. A hash mismatch or a metadata inconsistency found here is already meaningful evidence before any decompilation begins.
Key Trust Validation Signals
  • Hash mismatches matter most when the file claims to be a known public release — if SHA-256 does not match the official release hash, the jar has been modified
  • A copied mod name with a different internal package structure is a major warning sign — the brand is borrowed but the contents are not what they claim
  • A legitimate name plus unrelated combat or network hooks is stronger evidence than a suspicious filename alone
  • Mod IDs that do not match the claimed project — e.g., fabric.mod.json claims to be "SodiumFabric" but the mod ID is "cheatclient" — are an immediate escalation point
  • A mod that cannot be matched to any official source should be documented as unverified, not automatically called malicious
  • Version numbers that do not exist in any official changelog often indicate a custom build or a modified release
§ 04

Metadata, Entrypoints & Mixin Review

Loader metadata tells you how a jar introduces itself. Mixin configuration tells you where it plans to interfere. In advanced reviews, the second part is often more valuable — a jar can hide behind generic names while still targeting player update loops, interaction managers, mouse input, packet handlers, or rendering paths.

Mixins are designed to modify classes before they are loaded. That is normal in modern Minecraft modding, but it is also exactly why they are so forensically useful. The mixin config is often the fastest path to understanding a jar's real intent.

Mixin Analysis — What to Look For
Mixin Target AreaWhy It MattersSignal Level
Player update / tick loopsCore execution path for automation, auto-walk, continuous input injectionHIGH
Attack / interaction managersDirect modification of how hits are registered; reach, timing, auto-crit logicCRITICAL
Mouse / keyboard input handlersCPS schedulers, auto-clickers, input spoofing, and aim assistanceCRITICAL
Packet send / receive pathsVelocity modification, blink, packet delay, desync-based cheatsCRITICAL
Motion and physicsSpeed, fly, step height, bunny-hop; alters how the client calculates movementHIGH
Rendering / GUI overlaysESP, chest finder, player trackers; suspicious if claimed purpose is non-visualMEDIUM
Rendering pipeline onlyExpected for shaders, performance, and visual mods; low suspicion in isolationLOW
Resource loading onlyNormal for resource pack and asset mods; minimal concern by itselfLOW
Reading a Mixin Config
JSONexample.mixins.json
{
  "required": true,
  "minVersion": "0.8",
  "package": "com.example.mixins",
  "compatibilityLevel": "JAVA_17",
  "mixins": [
    "MixinClientPlayerEntity",   // player entity — worth checking
    "MixinMouseHandler",           // mouse input — HIGH signal
        "MixinClientPacketListener",   // packet handling — CRITICAL
        "MixinGameRenderer"            // rendering — context-dependent
  ],
  "injectors": {
    "defaultRequire": 1
  }
}

// Injection types that warrant deeper review:
// @Inject  — adds code at a target point (most common)
// @Overwrite — completely replaces the target method (highest risk)
// @Redirect — intercepts a method call within the target (often stealthy)
// @ModifyArg — alters a single argument passed to a call (subtle changes)
Mixin targets often reveal intent faster than class names do. A "performance" mod that patches MixinMouseHandler or MixinClientPacketListener deserves significantly more scrutiny than one targeting only rendering or asset loading.
High-Signal Inconsistency

If a jar claims to be a replay, HUD, or quality-of-life mod but its mixins target attack routines, motion control, or outgoing packet logic — the metadata story and the technical story do not match. This inconsistency is one of the strongest indicators available at the metadata review stage.

§ 05

Static Triage & String Analysis

Static triage is the first real pass through the jar. You are looking for fast indicators that tell you where deeper review should go next. File structure, class naming patterns, embedded resources, decryptors, native payloads, and repeated terminology all matter here.

String searching is still useful — just not on its own. Plenty of public clients still leak terms like killaura, velocity, trigger, or scaffold. At the same time, many legitimate mods also contain generic words like rotation, timer, or click. Treat keyword hits as routing signals, not final proof. Good triage combines three things: metadata review, targeted string searches, and decompilation.

String Search — PowerShell Triage Script
PowerShellstring_triage.ps1
# After decompiling the jar to .\decompiled\
# Run targeted keyword search across all decompiled sources

$terms = @(
  'autoclick', 'killaura', 'reach', 'velocity', 'trigger',
  'aim', 'rotation', 'scaffold', 'blink', 'cps',
  'criticals', 'aimbot', 'timer', 'speed', 'fly',
  'esp', 'wallhack', 'tracers', 'chams', 'nametags'
)

Get-ChildItem .\decompiled -Recurse -File |
  Select-String -Pattern $terms -SimpleMatch |
  Select-Object Path, LineNumber, Line |
  Format-Table -AutoSize

# Also check language files for leaked module names
Get-ChildItem .\unpacked\assets -Recurse -Filter *.json |
  Get-Content | Select-String -Pattern $terms -SimpleMatch
Language files and resource keys are frequently overlooked. Even heavily obfuscated clients often ship readable feature names in their lang files — KillAura, Velocity, AutoClicker — that survive code obfuscation entirely.
Structural Red Flags During Triage
  • Hidden folders or unexpected package hierarchies — deeply nested packages with single-letter names are a common obfuscation footprint
  • Shaded dependencies not documented in metadata — bundled libraries that are not declared in fabric.mod.json or mods.toml
  • Nested or embedded jars — a .jar inside a .jar, especially if it is encrypted or has no manifest
  • Decryptor utility classes — classes whose sole function is to decrypt strings or resources at runtime
  • Custom class loaders — non-standard loaders that bypass normal Fabric/Forge class loading mechanisms
  • GUI systems and category managers that do not fit the claimed mod purpose — a "performance mod" shipping a full clickGUI framework
  • Keybind registries and command frameworks — especially when the claimed mod has no documented configurable features
  • Packet classes and rotation math — Vec3d rotation calculations in a non-movement mod, or references to PlayerInteractC2SPacket in an unrelated context
Good Reporting Language

Instead of writing "cheat strings found", write: "Keyword triage surfaced combat-related terminology in decompiled sources, which was then corroborated by class behavior and mixin targets." The evidence chain matters more than the individual finding.

§ 06

Detecting Masked or Embedded Clients

Masked clients usually give themselves away through inconsistency. The name says one thing. The metadata says something close to that. The code says something else entirely. Common examples include jars that impersonate a performance mod, a replay utility, or a harmless HUD project while shipping module managers, combat toggles, click schedulers, or packet manipulation routines.

The Legitimacy Triad

A mod should generally align across three dimensions. When any of these three do not line up, document the mismatch clearly — the inconsistency itself is meaningful evidence even before proving specific capability.

1
Name
The filename, jar name, and branding used when presenting the mod. The easiest thing to fake — provides context but never proof on its own.
2
Metadata
Loader config files declaring mod ID, version, entrypoints, and dependencies. More reliable than the filename — harder to fake consistently across all fields.
3
Behavior
What the code actually does — mixin targets, decompiled logic, runtime artifacts. The hardest to disguise and the most reliable indicator of true purpose.
Masked Client Indicators
IndicatorWhat It SuggestsNext Step
Metadata claims harmless purpose but code touches combat, targeting, or network flowIntentional mislabeling; primary masking techniqueDocument the mismatch; decompile combat classes directly
Package names imitate a known project but internal structure differs significantlyBorrowed brand, different codebase — likely a modified or wrapped buildDiff against official release file list
Resources or language keys expose feature names the official project does not shipLeaked module names surviving obfuscation; strong capability evidenceExtract all lang files and compare to official release
Unrelated shaded libraries, native binaries, or custom loaders bundled insideSecond-stage payload, additional framework, or runtime decryptorInspect embedded jar; identify all native and foreign libraries
File list in the jar does not match the official version's file manifestAdded packages, injected mixins, or removed classes relative to clean releaseDiff jarfiles; flag added and modified files for targeted review
Icon copied from a legitimate mod but SHA differs from the official icon fileDeliberate impersonation of a trusted projectHash icon; check against official asset; note the impersonation directly
Diffing Against an Official Release
PowerShelljar_diff.ps1
# Unpack both jars to compare file lists
Expand-Archive "official.jar"  -DestinationPath ".\official\"  -Force
Expand-Archive "suspect.jar"   -DestinationPath ".\suspect\"   -Force

# Compare file listings — identify added, removed, or modified entries
$officialFiles = Get-ChildItem ".\official\" -Recurse | Select-Object -Expand FullName
$suspectFiles  = Get-ChildItem ".\suspect\"  -Recurse | Select-Object -Expand FullName

# Files in suspect jar not present in official release:
Compare-Object $officialFiles $suspectFiles |
  Where-Object { $_.SideIndicator -eq '=>' } |
  Select-Object InputObject

# Hash-compare files present in both (detect modified classes):
Get-ChildItem ".\official\" -Recurse -File | ForEach-Object {
  $rel     = $_.FullName.Replace(".\official\", "")
  $suspect = ".\suspect\" + $rel
  if (Test-Path $suspect) {
    $h1 = (Get-FileHash $_.FullName -Algorithm SHA256).Hash
    $h2 = (Get-FileHash $suspect    -Algorithm SHA256).Hash
    if ($h1 -ne $h2) { Write-Output "MODIFIED: $rel" }
  }
}
Diffing against an official release is often faster than reading every class from scratch. Added mixins, extra packages, and modified entrypoints jump out immediately. This technique is especially powerful for catching embedded clients that use a legitimate mod as a carrier.
§ 07

Obfuscation & Loader Patterns

Obfuscation changes the reading experience, not the purpose of the code. A cheat still has to read game state, make decisions, alter movement or combat, schedule inputs, render overlays, save config, and activate modules. Those tasks leave structural signatures behind even when all identifiable names are shredded. When normal decompilation gets difficult, the analysis strategy shifts from names to behavior.

Common Obfuscation Techniques
01
Class & Method Renaming
All classes, methods, and fields renamed to single letters or random sequences. Readable structure still survives — class hierarchy, call graphs, and mixin target references remain meaningful.
most commonProGuard / Allatori
02
String Encryption
Readable strings replaced by decryptor calls — Decrypt("a7f3c...") rather than "killaura". The decryptor class is usually identifiable; its inputs reveal the original strings when analyzed statically or traced at runtime.
commonreversible statically
03
Reflection-Heavy Dispatch
Methods resolved by name at runtime via Class.forName() and Method.invoke(), often combining string encryption with reflection to break the static call graph. Tracing decryptor inputs reconstructs the target method names.
moderate-highcall graph breaking
04
Control-Flow Flattening
Logical branching replaced by large switch statements dispatching on a state variable. Normal program flow becomes a flat dispatcher loop — functionally identical but almost unreadable as a static analysis target.
advancedOLLVM-style
05
Invokedynamic Abuse
Java's invokedynamic instruction used to obscure method calls. Some decompilers fail to reconstruct these calls cleanly, producing incomplete or incorrect output. Bytecode-level inspection bypasses the decompiler for these sections.
advanceddecompiler evasion
06
Runtime Loader / Second Stage
A small loader stub in the jar decrypts or downloads the actual payload at runtime, loading it directly into memory. The stub itself is minimal and appears innocuous; the payload may live in encrypted resources or be fetched remotely.
high riskhardest to analyze statically
Analysis Strategy When Code Is Obfuscated
  • Locate decryptor methods and note which classes feed them — decryptors are often one of the few remaining readable components and act as an index into the obfuscated code
  • Track repeated call patterns — even when names are randomized, a method called from 30 different classes is almost certainly a core dispatcher or feature controller
  • Look for reflection helpers that resolve fields or methods by decrypted string — trace the string inputs to identify targeted Minecraft classes
  • Mark classes with unusually high branching or dispatcher tables — these are the signature of control-flow flattening; focus on the state variable values
  • Inspect resources for encrypted blobs, serialized configs, or hidden jars loaded at runtime — encrypted resources are a strong indicator of a second-stage payload
  • Count event hook registrations — a mod that registers many more event hooks than its claimed purpose requires is a structural anomaly regardless of readable names
Responsible Use of AI / Reasoning Tools

AI tools can help summarize hostile control flow, cluster suspicious methods, or explain likely function of obfuscated code. Treat that output as analyst assistance — a starting point for focused review. The proof still comes from the jar, not the summary. Do not cite AI-generated analysis as evidence; cite the specific class, method, and behavior the AI helped you locate.

Core Principle

Obfuscation hides readability. It does not remove capability. The structural fingerprint of a module system, a target loop, or a packet interceptor survives most obfuscation techniques.

§ 08

Behavioral Analysis in Isolation

Static review gets you far, but some jars only become obvious when loaded in a controlled environment. If you do this step, isolate it. Use a disposable VM or a dedicated test machine — never load unknown jars on a personal or production system. The goal is to document runtime behavior safely and deliberately, not to casually run suspicious files out of curiosity.

Safety Requirement

Behavioral analysis of unknown jars must only be performed in an isolated, disposable environment — a fresh VM with no personal data, no saved credentials, and no persistent network access to production systems. Snapshot the VM before loading the jar so the environment can be restored cleanly after analysis.

Behavioral Analysis Workflow
PowerShellbehavioral_prep.ps1
# Pre-launch: baseline snapshot of relevant filesystem locations
$watchPaths = @(
  "$env:APPDATA\.minecraft\config",
  "$env:APPDATA\.minecraft\logs",
  "$env:APPDATA\.minecraft\mods",
  "$env:TEMP",
  "$env:LOCALAPPDATA\Temp"
)

# Capture pre-launch state
$baseline = $watchPaths | ForEach-Object {
  Get-ChildItem $_ -Recurse -ErrorAction SilentlyContinue |
  Get-FileHash -Algorithm SHA256
}

# [ Launch Minecraft with the suspect mod in isolated VM ]
# [ Wait for fully loaded state — observe GUI, keybinds, overlays ]

# Post-launch: compare filesystem state
$postLaunch = $watchPaths | ForEach-Object {
  Get-ChildItem $_ -Recurse -ErrorAction SilentlyContinue |
  Get-FileHash -Algorithm SHA256
}

# New or modified files since launch:
Compare-Object $baseline $postLaunch -Property Hash |
  Where-Object { $_.SideIndicator -eq '=>' }
File changes during the first few seconds of launch — especially in config directories — can expose module names, category labels, and default keybinds that survive any amount of code obfuscation.
What to Observe During Behavioral Analysis
ObservableWhat It RevealsPriority
Generated config filesModule names, category labels, default keybind values, hidden states — even when code is fully obfuscated, configs are almost always readableP1
GUI behavior and hidden menusA clickGUI, module list, or category panel that appears on a keybind press reveals a full module system regardless of what the jar claims to beP1
Filesystem writes during launchNew directories, config trees, and log files created at startup; the structure alone often reveals feature categoriesP2
Network requests at launchOutbound connections to external hosts at startup may indicate license checking, update fetching, or second-stage payload downloadP2
Secret keybind activationsActivating undocumented binds may reveal hidden overlays, toggles, or module panels not visible at initial launchP3
Console / log outputSome loaders print module lists, version information, or capability flags to the game log even when the GUI is hiddenP3
Why Configs Matter Most

Even when code is heavily obfuscated, config files often leak feature names, category labels, default binds, or hidden module states. They are one of the most underrated artifacts in mod review — and one of the few things that obfuscation tools do not touch.

§ 09

Reporting Confidence & False Positives

The cleanest reports separate observation from conclusion. Start with what you found, explain why it matters, then state how confident you are. That structure keeps your notes usable even when the final moderation decision is made by someone else. Admins decide the outcome — analysts document the facts.

Confidence Framework
LevelBasisHow to Write It
LOW Unknown jar, odd strings, but no verified capability. Anomalies exist but do not yet support a conclusion about function. Document anomalies only. Do not claim cheat functionality. Use language like "warrants further review" and "could not be authenticated."
MEDIUM Misleading metadata plus suspicious hooks or resources. The jar is inconsistent with its claimed purpose but specific capability is not fully confirmed. State that the jar is inconsistent with its claimed purpose and warrants deeper review. List specific inconsistencies. Avoid definitive language about function.
HIGH Readable combat, input, or packet manipulation logic found through decompilation. Specific functionality is identifiable and located. Describe the specific functionality and where it was found — class name, method, behavior. State that the capability was identified in decompiled sources.
VERY HIGH Cheat modules, configs, toggles, or runtime confirmation. Capability is directly confirmed through multiple independent artifact sources. Report the behavior directly and attach the strongest artifacts first. Name specific modules, config keys, or runtime observations. State that multiple sources corroborate the finding.
Recommended Report Structure
Formatreport_template.txt
──────────────────────────────────────────────────────────
OBSERVATION:    What artifact was found and where.
                E.g. "MixinMouseHandler found in mixin config
                      targeting com.example.mixins package."

INDICATOR:      What behavior or inconsistency this suggests.
                E.g. "Mouse input handler injection is
                      inconsistent with a claimed replay mod."

WHY IT MATTERS: How this could provide advantage or concealment.
                E.g. "Mouse handler modification is a standard
                      technique for CPS scheduling and aim assist."

CONFIDENCE:     Low / Medium / High / Very High
                E.g. "Medium — mixin target identified, full
                      method behavior not yet confirmed."
──────────────────────────────────────────────────────────
This format is reproducible by another analyst. Every claim is tied to a specific artifact and qualified with a confidence level. Avoid summary conclusions without listed supporting observations.
Common False Positive Causes
  • Leaning too hard on a single signal — one scary string without corroborating code behavior does not prove a module exists
  • Treating public popularity as proof of legitimacy — a well-known mod can still be tampered with; hash validation always applies
  • Ignoring hash mismatches because the filename looks right — the filename is the easiest thing to fake and the least reliable indicator
  • Letting keyword results outweigh mixin and behavior analysis — many legitimate mods contain terms like "rotation" or "click" in non-cheat contexts
  • Treating obfuscation alone as proof — some legitimate mods use obfuscation for IP protection; obfuscation raises suspicion but does not confirm capability
  • Conflating "unusual" with "malicious" — custom, private, or poorly documented mods are not automatically cheats; document anomalies and escalate appropriately
§ 10

Useful Workflows & Scripts

The goal of quick scripts is not to replace actual analysis — it is to speed up repetitive work so your attention stays on the jars that deserve it most. A solid first-pass workflow is: inventory the mod folder, hash every jar, compare claimed releases to official sources, unpack or decompile suspicious files, run targeted searches, then document what was actually confirmed.

Full First-Pass Triage Script
PowerShellfull_triage.ps1
# ── STEP 1: Inventory and hash all jars ────────────────────────
$modsPath = "$env:APPDATA\.minecraft\mods"
Get-ChildItem $modsPath -Filter *.jar |
  Get-FileHash -Algorithm SHA256 |
  Sort-Object Path |
  Export-Csv ".\hashes.csv" -NoTypeInformation

# ── STEP 2: Unpack a suspect jar ───────────────────────────────
$target = ".\suspect.jar"
Expand-Archive $target -DestinationPath ".\unpacked\" -Force

# ── STEP 3: Read loader metadata ───────────────────────────────
foreach ($meta in @('fabric.mod.json','META-INF\mods.toml','META-INF\MANIFEST.MF')) {
  $path = ".\unpacked\" + $meta
  if (Test-Path $path) {
    Write-Host "=== $meta ===" -ForegroundColor Cyan
    Get-Content $path
  }
}

# ── STEP 4: List mixin configs ─────────────────────────────────
Get-ChildItem ".\unpacked" -Filter *.json -Recurse |
  Where-Object { $_.Name -match 'mixin' } |
  ForEach-Object { Write-Host $_.FullName; Get-Content $_.FullName }

# ── STEP 5: Keyword search across decompiled sources ───────────
# (Run after decompiling with Vineflower / CFR / Procyon)
$patterns = 'reach','velocity','autoclick','trigger','rotation',
            'killaura','scaffold','blink','cps','aimbot',
            'criticals','esp','wallhack','speed','fly'

Get-ChildItem .\decompiled -Recurse -File |
  Select-String -Pattern $patterns -SimpleMatch |
  Sort-Object Path, LineNumber |
  Format-Table Path, LineNumber, Line -AutoSize

# ── STEP 6: Check language / resource files for module names ───
Get-ChildItem .\unpacked\assets -Recurse -Filter *.json -ErrorAction SilentlyContinue |
  Select-String -Pattern $patterns -SimpleMatch |
  Format-Table Path, LineNumber, Line -AutoSize
This script handles the repetitive first-pass work in one run. Steps 1–4 require no decompilation; step 5 requires Vineflower, CFR, or Procyon to be run first. The hash CSV from step 1 can be compared against official release hashes for batch trust validation.
Recommended Decompilation Tools
ToolTypeBest ForSource
VineflowerJava DecompilerMost accurate modern Java decompilation; successor to Fernflower; handles complex patterns wellOpen source — github.com/Vineflower
CFRJava DecompilerStrong on modern Java features; good for comparing output against Vineflower when results differFree — benf.org/counterclockwise/cfr
ProcyonJava DecompilerAlternative decompiler; useful when Vineflower and CFR produce poor output on specific classesOpen source — bitbucket.org/mstrobel/procyon
BytecodeViewerMulti-tool GUIAll-in-one GUI combining multiple decompilers, bytecode view, and string search; good for triageOpen source — github.com/Konloch/bytecode-viewer
RecafBytecode Editor / ViewerBytecode-level inspection; invaluable for invokedynamic abuse and sections decompilers fail onOpen source — github.com/Col-E/Recaf
jadxJava DecompilerFast and readable output; strong GUI; good for initial orientation before deeper analysisOpen source — github.com/skylot/jadx
Workflow Priority Order
Standard Analysis Order

1. Inventory first — hash all jars, document what is present. 2. Trust validation second — compare hashes, read metadata, identify version inconsistencies. 3. Metadata and mixins third — read loader configs, list mixin targets, flag high-signal injection points. 4. Decompiled behavior fourth — targeted class review based on mixin findings, string triage, and structural anomalies. 5. Isolation testing only when needed — and only in a controlled, disposable environment with pre- and post-launch filesystem comparison.

Final Note

The strongest mod analysis is boring in a good way. It is organized, reproducible, and based on artifacts you can point to without any guesswork. Every claim has a source. Every source has a confidence level. Every conclusion follows from the evidence, not from assumption.