diff --git a/LICENSE b/LICENSE
index 8fb0d13..0a45605 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2023 DerSkythe
+Copyright (c) 2024 DerSkythe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index ad8453f..c2ece90 100644
--- a/README.md
+++ b/README.md
@@ -14,13 +14,13 @@ We do not condone illegal activity and strongly encourage keeping transmissions
## Installation
-The application is included in the standard firmware package of [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware).
+The application is included in the standard firmware package of [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware).
You just need to install the [latest firmware](https://github.com/DarkFlippers/unleashed-firmware/releases/latest).
You can also download the [release](https://github.com/derskythe/flipperzero-subbrute/releases/latest) and unzip/untar it to the `SD Card/apps/Sub-GHz` directory.
> [!WARNING]
->
+>
> The application is not compatible with the official firmware version.
> Also, it has not been tested on other firmware versions other than [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware) and [OFW](https://github.com/flipperdevices/flipperzero-firmware).
@@ -30,11 +30,11 @@ You can also download the [release](https://github.com/derskythe/flipperzero-sub
![image](https://github.com/DarkFlippers/flipperzero-subbrute/assets/31771569/9f428d6e-59fd-4517-895d-fb185f8d884f)
-Here you can select the protocol and frequency that will be used for bruteforce.
+Here you can select the protocol and frequency that will be used for bruteforce.
According to our observations, `CAME 12bit 433MHz` is the most common protocol, so it is selected by default.
To identify other devices and protocols, you should inspect the device.
-According to the protocol, when probe a key, each value is sent 3 times.
-Most of the devices this works but there are devices that don't work and more repetitions are needed.
+According to the protocol, when probe a key, each value is sent 3 times.
+Most of the devices this works but there are devices that don't work and more repetitions are needed.
The number of repetitions can be increased with the right button, the left button decreases the value.
The negative side of increasing the number of repetitions will be a longer key find time.
@@ -88,6 +88,7 @@ The negative side of increasing the number of repetitions will be a longer key f
- Chamberlain 9bit 300MHz
- Chamberlain 9bit 315MHz
+- Chamberlain 9bit 318MHz
- Chamberlain 9bit 390MHz
- Chamberlain 9bit 433MHz
- Chamberlain 8bit 300MHz
@@ -106,7 +107,7 @@ The negative side of increasing the number of repetitions will be a longer key f
### UNILARM
> [!NOTE]
->
+>
> Only dip switch combinations, not full 25bit bruteforce
- UNILARM 25bit 330MHz (TE: 209μs)
@@ -115,7 +116,7 @@ The negative side of increasing the number of repetitions will be a longer key f
### SMC5326
> [!NOTE]
->
+>
> Only dip switch combinations, not full 25bit bruteforce
- SMC5326 25bit 330MHz (TE: 320μs)
@@ -124,7 +125,7 @@ The negative side of increasing the number of repetitions will be a longer key f
### PT2260
> [!NOTE]
->
+>
> Only for 8 dip switch remote, not full 24bit bruteforce
- PT2260 24bit 315MHz (TE: 286μs)
diff --git a/helpers/subbrute_radio_device_loader.c b/helpers/subbrute_radio_device_loader.c
index 6fcfde8..9a7a1fe 100644
--- a/helpers/subbrute_radio_device_loader.c
+++ b/helpers/subbrute_radio_device_loader.c
@@ -46,6 +46,7 @@ bool subbrute_radio_device_loader_is_connect_external(const char* name) {
if(!is_otg_enabled) {
subbrute_radio_device_loader_power_off();
}
+
return is_connect;
}
diff --git a/helpers/subbrute_worker.c b/helpers/subbrute_worker.c
index 2061f7c..45a67a7 100644
--- a/helpers/subbrute_worker.c
+++ b/helpers/subbrute_worker.c
@@ -72,6 +72,7 @@ bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step) {
furi_assert(instance);
if(!subbrute_worker_can_manual_transmit(instance)) {
FURI_LOG_W(TAG, "Cannot set step during running mode");
+
return false;
}
@@ -205,6 +206,7 @@ void subbrute_worker_stop(SubBruteWorker* instance) {
furi_assert(instance);
if(!instance->worker_running) {
+
return;
}
@@ -264,21 +266,14 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste
stream, instance->file, step, instance->bits, instance->te, instance->repeat);
}
- // size_t written = stream_write_string(stream, payload);
- // if(written <= 0) {
- // FURI_LOG_W(TAG, "Error creating packet! EXIT");
- // result = false;
- // } else {
subbrute_worker_subghz_transmit(instance, flipper_format);
result = true;
#if FURI_DEBUG
FURI_LOG_D(TAG, "Manual transmit done");
#endif
- // }
flipper_format_free(flipper_format);
- // furi_string_free(payload);
return result;
}
@@ -366,11 +361,13 @@ int32_t subbrute_worker_thread(void* context) {
if(!instance->worker_running) {
FURI_LOG_W(TAG, "Worker is not set to running state!");
+
return -1;
}
if(instance->state != SubBruteWorkerStateReady &&
instance->state != SubBruteWorkerStateFinished) {
FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state);
+
return -2;
}
#ifdef FURI_DEBUG
@@ -411,15 +408,6 @@ int32_t subbrute_worker_thread(void* context) {
//furi_delay_ms(SUBBRUTE_MANUAL_TRANSMIT_INTERVAL / 4);
#endif
- // size_t written = stream_write_stream_write_string(stream, payload);
- // if(written <= 0) {
- // FURI_LOG_W(TAG, "Error creating packet! BREAK");
- // instance->worker_running = false;
- // local_state = SubBruteWorkerStateIDLE;
- // furi_string_free(payload);
- // break;
- // }
-
subbrute_worker_subghz_transmit(instance, flipper_format);
if(instance->step + 1 > instance->max_value) {
@@ -427,12 +415,11 @@ int32_t subbrute_worker_thread(void* context) {
FURI_LOG_I(TAG, "Worker finished to end");
#endif
local_state = SubBruteWorkerStateFinished;
- // furi_string_free(payload);
+
break;
}
instance->step++;
- // furi_string_free(payload);
furi_delay_ms(instance->tx_timeout_ms);
}
@@ -446,6 +433,7 @@ int32_t subbrute_worker_thread(void* context) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Worker stop");
#endif
+
return 0;
}
@@ -473,18 +461,6 @@ void subbrute_worker_set_te(SubBruteWorker* instance, uint32_t te) {
instance->te = te;
}
-// void subbrute_worker_timeout_inc(SubBruteWorker* instance) {
-// if(instance->tx_timeout_ms < 255) {
-// instance->tx_timeout_ms++;
-// }
-// }
-
-// void subbrute_worker_timeout_dec(SubBruteWorker* instance) {
-// if(instance->tx_timeout_ms > 0) {
-// instance->tx_timeout_ms--;
-// }
-// }
-
bool subbrute_worker_is_tx_allowed(SubBruteWorker* instance, uint32_t value) {
furi_assert(instance);
bool res = false;
diff --git a/scenes/subbrute_scene_load_file.c b/scenes/subbrute_scene_load_file.c
index 391001a..aa78769 100644
--- a/scenes/subbrute_scene_load_file.c
+++ b/scenes/subbrute_scene_load_file.c
@@ -91,5 +91,6 @@ void subbrute_scene_load_file_on_exit(void* context) {
bool subbrute_scene_load_file_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
+
return false;
}
diff --git a/scenes/subbrute_scene_save_name.c b/scenes/subbrute_scene_save_name.c
index 7628a47..4a82ff9 100644
--- a/scenes/subbrute_scene_save_name.c
+++ b/scenes/subbrute_scene_save_name.c
@@ -76,6 +76,7 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) {
instance->scene_manager, SubBruteSceneSetupAttack);
}
}
+
return consumed;
}
diff --git a/scenes/subbrute_scene_save_success.c b/scenes/subbrute_scene_save_success.c
index 20b1a0d..fbfddb3 100644
--- a/scenes/subbrute_scene_save_success.c
+++ b/scenes/subbrute_scene_save_success.c
@@ -31,6 +31,7 @@ bool subbrute_scene_save_success_on_event(void* context, SceneManagerEvent event
return true;
}
}
+
return false;
}
diff --git a/scenes/subbrute_scene_setup_extra.c b/scenes/subbrute_scene_setup_extra.c
index 5e8e05b..ef26b5d 100644
--- a/scenes/subbrute_scene_setup_extra.c
+++ b/scenes/subbrute_scene_setup_extra.c
@@ -22,7 +22,7 @@ static void setup_extra_td_callback(VariableItem* item) {
furi_assert(item);
SubBruteState* instance = variable_item_get_context(item);
furi_assert(instance);
- char buf[6];
+ char buf[6] = {0};
const uint8_t index = variable_item_get_current_value_index(item);
uint8_t val = subbrute_worker_get_timeout(instance->worker);
@@ -76,7 +76,7 @@ static void setup_extra_rep_callback(VariableItem* item) {
furi_assert(item);
SubBruteState* instance = variable_item_get_context(item);
furi_assert(instance);
- char buf[6];
+ char buf[6] = {0};
const uint8_t index = variable_item_get_current_value_index(item);
uint8_t val = subbrute_worker_get_repeats(instance->worker);
@@ -130,7 +130,7 @@ static void setup_extra_te_callback(VariableItem* item) {
furi_assert(item);
SubBruteState* instance = variable_item_get_context(item);
furi_assert(instance);
- char buf[6];
+ char buf[6] = {0};
const uint8_t index = variable_item_get_current_value_index(item);
uint32_t val = subbrute_worker_get_te(instance->worker);
@@ -182,7 +182,7 @@ static void setup_extra_te_callback(VariableItem* item) {
static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bool on_extra) {
furi_assert(instance);
- char str[6];
+ char str[6] = {0};
VariableItem* item;
static bool extra = false;
if(on_extra) {
@@ -254,7 +254,7 @@ static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bo
static void setup_extra_enter_callback(void* context, uint32_t index) {
furi_assert(context);
- SubBruteState* instance = context;
+ SubBruteState* instance = (SubBruteState*)context;
if(index == SubBruteVarListIndexRepeatOrOnExtra) {
subbrute_scene_setup_extra_init_var_list(instance, true);
@@ -263,14 +263,14 @@ static void setup_extra_enter_callback(void* context, uint32_t index) {
void subbrute_scene_setup_extra_on_enter(void* context) {
furi_assert(context);
- SubBruteState* instance = context;
+ SubBruteState* instance = (SubBruteState*)context;
subbrute_scene_setup_extra_init_var_list(instance, false);
}
void subbrute_scene_setup_extra_on_exit(void* context) {
furi_assert(context);
- SubBruteState* instance = context;
+ SubBruteState* instance = (SubBruteState*)context;
variable_item_list_reset(instance->var_list);
}
diff --git a/subbrute_device.c b/subbrute_device.c
index 5670e26..ec854d6 100644
--- a/subbrute_device.c
+++ b/subbrute_device.c
@@ -21,11 +21,8 @@ SubBruteDevice* subbrute_device_alloc(const SubGhzDevice* radio_device) {
instance->radio_device = radio_device;
-//#ifdef FURI_DEBUG
-// subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile);
-//#else
subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433);
-//#endif
+
return instance;
}
diff --git a/subbrute_i.h b/subbrute_i.h
index eb90bef..573d335 100644
--- a/subbrute_i.h
+++ b/subbrute_i.h
@@ -31,7 +31,7 @@
#include "views/subbrute_attack_view.h"
#include "views/subbrute_main_view.h"
-#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.B"
+#define SUBBRUTEFORCER_VER "Sub-GHz BruteForcer 3.C"
#ifdef FURI_DEBUG
//#define SUBBRUTE_FAST_TRACK false
diff --git a/subbrute_protocols.c b/subbrute_protocols.c
index 8ca5bb5..8c69b2f 100644
--- a/subbrute_protocols.c
+++ b/subbrute_protocols.c
@@ -146,6 +146,17 @@ const SubBruteProtocol subbrute_protocol_chamberlain_9bit_315 = {
.preset = FuriHalSubGhzPresetOok650Async,
.file = ChamberlainFileProtocol};
+/**
+ * Chamberlain 9bit 318MHz
+ */
+const SubBruteProtocol subbrute_protocol_chamberlain_9bit_318 = {
+ .frequency = 318000000,
+ .bits = 9,
+ .te = 0,
+ .repeat = 3,
+ .preset = FuriHalSubGhzPresetOok650Async,
+ .file = ChamberlainFileProtocol};
+
/**
* Chamberlain 9bit 390MHz
*/
@@ -435,6 +446,7 @@ static const char* subbrute_protocol_names[] = {
[SubBruteAttackHoltek12bitAM915] = "Holtek AM 12bit 915MHz",
[SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz",
[SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz",
+ [SubBruteAttackChamberlain9bit318] = "Chamberlain 9bit 318MHz",
[SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz",
[SubBruteAttackChamberlain9bit433] = "Chamberlain 9bit 433MHz",
[SubBruteAttackChamberlain8bit300] = "Chamberlain 8bit 300MHz",
@@ -487,6 +499,7 @@ const SubBruteProtocol* subbrute_protocol_registry[] = {
[SubBruteAttackHoltek12bitAM915] = &subbrute_protocol_holtek_12bit_am_915,
[SubBruteAttackChamberlain9bit300] = &subbrute_protocol_chamberlain_9bit_300,
[SubBruteAttackChamberlain9bit315] = &subbrute_protocol_chamberlain_9bit_315,
+ [SubBruteAttackChamberlain9bit318] = &subbrute_protocol_chamberlain_9bit_318,
[SubBruteAttackChamberlain9bit390] = &subbrute_protocol_chamberlain_9bit_390,
[SubBruteAttackChamberlain9bit433] = &subbrute_protocol_chamberlain_9bit_433,
[SubBruteAttackChamberlain8bit300] = &subbrute_protocol_chamberlain_8bit_300,
@@ -828,8 +841,6 @@ void subbrute_protocol_file_generate_file(
uint64_t file_key,
bool two_bytes) {
FuriString* candidate = furi_string_alloc();
- // char subbrute_payload_byte[8];
- //furi_string_set_str(candidate, file_key);
subbrute_protocol_create_candidate_for_existing_file(
candidate, step, bit_index, file_key, two_bytes);
diff --git a/subbrute_protocols.h b/subbrute_protocols.h
index 07bfbeb..2ddd579 100644
--- a/subbrute_protocols.h
+++ b/subbrute_protocols.h
@@ -90,6 +90,7 @@ typedef enum {
* - `SubBruteAttackHoltek12bitAM915`: Holtek 12-bit AM 915 MHz sub-brute attack.
* - `SubBruteAttackChamberlain9bit300`: Chamberlain 9-bit 300 MHz sub-brute attack.
* - `SubBruteAttackChamberlain9bit315`: Chamberlain 9-bit 315 MHz sub-brute attack.
+ * - `SubBruteAttackChamberlain9bit318`: Chamberlain 9-bit 318 MHz sub-brute attack.
* - `SubBruteAttackChamberlain9bit390`: Chamberlain 9-bit 390 MHz sub-brute attack.
* - `SubBruteAttackChamberlain9bit433`: Chamberlain 9-bit 433 MHz sub-brute attack.
* - `SubBruteAttackChamberlain8bit300`: Chamberlain 8-bit 300 MHz sub-brute attack.
@@ -131,6 +132,7 @@ typedef enum {
SubBruteAttackHoltek12bitAM915,
SubBruteAttackChamberlain9bit300,
SubBruteAttackChamberlain9bit315,
+ SubBruteAttackChamberlain9bit318,
SubBruteAttackChamberlain9bit390,
SubBruteAttackChamberlain9bit433,
SubBruteAttackChamberlain8bit300,
diff --git a/views/subbrute_attack_view.c b/views/subbrute_attack_view.c
index a49ffcb..5678fcf 100644
--- a/views/subbrute_attack_view.c
+++ b/views/subbrute_attack_view.c
@@ -193,9 +193,7 @@ View* subbrute_attack_view_get_view(SubBruteAttackView* instance) {
void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step) {
furi_assert(instance);
-#ifdef FURI_DEBUG
- //FURI_LOG_D(TAG, "Set step: %d", current_step);
-#endif
+
instance->current_step = current_step;
with_view_model(
instance->view,
@@ -226,7 +224,6 @@ void subbrute_attack_view_init_values(
instance->max_value = max_value;
instance->current_step = current_step;
instance->is_attacking = is_attacking;
- // instance->extra_repeats = extra_repeats;
with_view_model(
instance->view,
@@ -262,7 +259,7 @@ void subbrute_attack_view_exit(void* context) {
void subbrute_attack_view_draw(Canvas* canvas, void* context) {
furi_assert(context);
SubBruteAttackViewModel* model = (SubBruteAttackViewModel*)context;
- char buffer[64];
+ char buffer[64] = {0};
const char* attack_name = NULL;
attack_name = subbrute_protocol_name(model->attack_type);
diff --git a/views/subbrute_main_view.c b/views/subbrute_main_view.c
index de40670..354340c 100644
--- a/views/subbrute_main_view.c
+++ b/views/subbrute_main_view.c
@@ -109,9 +109,6 @@ void subbrute_main_view_center_displayed_key(
}
void subbrute_main_view_draw_is_byte_selected(Canvas* canvas, SubBruteMainViewModel* model) {
-#ifdef FURI_DEBUG
- //FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file);
-#endif
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:");
@@ -152,9 +149,6 @@ void subbrute_main_view_draw_is_ordinary_selected(Canvas* canvas, SubBruteMainVi
const uint8_t item_height = 16;
const uint8_t string_height_offset = 9;
-#ifdef FURI_DEBUG
- //FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, model->index);
-#endif
for(size_t position = 0; position < SubBruteAttackTotalCount; ++position) {
uint8_t item_position = position - model->window_position;
@@ -189,7 +183,7 @@ void subbrute_main_view_draw_is_ordinary_selected(Canvas* canvas, SubBruteMainVi
#else
canvas_set_font(canvas, FontBatteryPercent);
#endif
- char buffer[10];
+ char buffer[10] = {0};
snprintf(buffer, sizeof(buffer), "x%d", current_repeat_count);
uint8_t temp_x_offset_repeats =
current_repeat_count <= SUBBRUTE_PROTOCOL_MAX_REPEATS ? 15 : 18;
@@ -230,11 +224,13 @@ bool subbrute_main_view_input_file_protocol(InputEvent* event, SubBruteMainView*
(instance->two_bytes && instance->index > 1)) {
instance->index--;
}
+
updated = true;
} else if(event->key == InputKeyRight) {
if(instance->index < 7) {
instance->index++;
}
+
updated = true;
} else if(event->key == InputKeyUp) {
instance->two_bytes = !instance->two_bytes;
@@ -242,14 +238,12 @@ bool subbrute_main_view_input_file_protocol(InputEvent* event, SubBruteMainView*
if(instance->two_bytes && instance->index < 7) {
instance->index++;
}
- // instance->callback(
- // instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp :
- // SubBruteCustomEventTypeChangeStepDown,
- // instance->context);
updated = true;
} else if(event->key == InputKeyOk) {
- instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
+ instance->callback(SubBruteCustomEventTypeIndexSelected,
+ instance->context);
+
updated = true;
}
return updated;
@@ -259,6 +253,7 @@ bool subbrute_main_view_input_ordinary_protocol(
InputEvent* event,
SubBruteMainView* instance,
bool is_short) {
+
const uint8_t min_value = 0;
const uint8_t correct_total = SubBruteAttackTotalCount - 1;
uint8_t index = instance->index;
@@ -273,7 +268,7 @@ bool subbrute_main_view_input_ordinary_protocol(
} else {
instance->index = CLAMP(index - 1, correct_total, min_value);
}
- //instance->repeat_values = 0;
+
updated = true;
} else if(event->key == InputKeyDown && is_short) {
if(index == correct_total) {
@@ -281,7 +276,7 @@ bool subbrute_main_view_input_ordinary_protocol(
} else {
instance->index = CLAMP(index + 1, correct_total, min_value);
}
- //instance->repeat_values = 0;
+
updated = true;
} else if(event->key == InputKeyLeft && is_short) {
instance->repeat_values[index] = CLAMP(current_repeats - 1, max_repeats, min_repeats);
@@ -297,6 +292,7 @@ bool subbrute_main_view_input_ordinary_protocol(
} else {
instance->callback(SubBruteCustomEventTypeMenuSelected, instance->context);
}
+
updated = true;
}
@@ -322,7 +318,7 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
furi_assert(event);
furi_assert(context);
- SubBruteMainView* instance = context;
+ SubBruteMainView* instance = (SubBruteMainView*)context;
if(event->key == InputKeyBack && event->type == InputTypeShort) {
#ifdef FURI_DEBUG
@@ -417,6 +413,7 @@ void subbrute_main_view_free(SubBruteMainView* instance) {
View* subbrute_main_view_get_view(SubBruteMainView* instance) {
furi_assert(instance);
+
return instance->view;
}
@@ -427,6 +424,7 @@ void subbrute_main_view_set_index(
bool is_select_byte,
bool two_bytes,
uint64_t key_from_file) {
+
furi_assert(instance);
furi_assert(idx < SubBruteAttackTotalCount);
#ifdef FURI_DEBUG
@@ -460,6 +458,7 @@ void subbrute_main_view_set_index(
model->key_from_file = instance->key_from_file;
model->is_select_byte = instance->is_select_byte;
model->two_bytes = instance->two_bytes;
+
for(size_t i = 0; i < SubBruteAttackTotalCount; i++) {
model->repeat_values[i] = repeats[i];
}
@@ -469,15 +468,18 @@ void subbrute_main_view_set_index(
SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance) {
furi_assert(instance);
+
return instance->index;
}
const uint8_t* subbrute_main_view_get_repeats(SubBruteMainView* instance) {
furi_assert(instance);
+
return instance->repeat_values;
}
bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) {
furi_assert(instance);
+
return instance->two_bytes;
}