mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
subbrute
This commit is contained in:
@@ -2,13 +2,34 @@
|
||||
|
||||
SubGhz Bruteforcer from [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware)
|
||||
|
||||
### Disclaimer
|
||||
|
||||
This software is for experimental purposes only and is not meant for any illegal activity/purposes.
|
||||
We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law.
|
||||
|
||||
### Supported Protocols:
|
||||
|
||||
#### CAME
|
||||
|
||||
- CAME 12bit 303MHz
|
||||
- CAME 12bit 307MHz
|
||||
- CAME 12bit 315MHz
|
||||
- CAME 12bit 433MHz
|
||||
- CAME 12bit 868MHz
|
||||
|
||||
#### NICE
|
||||
|
||||
- NICE 12bit 433MHz
|
||||
- NICE 12bit 868MHz
|
||||
|
||||
#### Ansonic
|
||||
|
||||
- Ansonic 12bit 433.075MHz
|
||||
- Ansonic 12bit 433.920MHz
|
||||
- Ansonic 12bit 434.075MHz
|
||||
|
||||
#### Chamberlain
|
||||
|
||||
- Chamberlain 9bit 300MHz
|
||||
- Chamberlain 9bit 315MHz
|
||||
- Chamberlain 9bit 390MHz
|
||||
@@ -19,6 +40,12 @@ SubGhz Bruteforcer from [Unleashed Firmware](https://github.com/DarkFlippers/unl
|
||||
- Chamberlain 7bit 300MHz
|
||||
- Chamberlain 7bit 315MHz
|
||||
- Chamberlain 7bit 390MHz
|
||||
|
||||
#### Linear
|
||||
|
||||
- Linear 10bit 300MHz
|
||||
- Linear 10bit 310MHz
|
||||
- BF Existing dump works for all other static protocols supported by Flipper Zero
|
||||
|
||||
#### Additional
|
||||
|
||||
- BF Existing dump works for all other static protocols supported by Flipper Zero
|
||||
|
||||
@@ -7,7 +7,7 @@ App(
|
||||
requires=["gui","dialogs"],
|
||||
stack_size=2 * 1024,
|
||||
order=11,
|
||||
fap_icon="subbrute_10px.png",
|
||||
fap_icon="images/subbrute_10px.png",
|
||||
fap_category="Tools",
|
||||
fap_icon_assets="images",
|
||||
)
|
||||
|
||||
59
applications/plugins/subbrute/helpers/gui_top_buttons.c
Normal file
59
applications/plugins/subbrute/helpers/gui_top_buttons.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "gui_top_buttons.h"
|
||||
|
||||
void elements_button_top_left(Canvas* canvas, const char* str) {
|
||||
const Icon* icon = &I_ButtonUp_7x4;
|
||||
|
||||
const uint8_t button_height = 12;
|
||||
const uint8_t vertical_offset = 3;
|
||||
const uint8_t horizontal_offset = 3;
|
||||
const uint8_t string_width = canvas_string_width(canvas, str);
|
||||
const uint8_t icon_h_offset = 3;
|
||||
const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
|
||||
const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = 0;
|
||||
const uint8_t y = 0 + button_height;
|
||||
|
||||
uint8_t line_x = x + button_width;
|
||||
uint8_t line_y = y - button_height;
|
||||
canvas_draw_box(canvas, x, line_y, button_width, button_height);
|
||||
canvas_draw_line(canvas, line_x + 0, line_y, line_x + 0, y - 1);
|
||||
canvas_draw_line(canvas, line_x + 1, line_y, line_x + 1, y - 2);
|
||||
canvas_draw_line(canvas, line_x + 2, line_y, line_x + 2, y - 3);
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, icon);
|
||||
canvas_draw_str(
|
||||
canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
void elements_button_top_right(Canvas* canvas, const char* str) {
|
||||
const Icon* icon = &I_ButtonDown_7x4;
|
||||
|
||||
const uint8_t button_height = 12;
|
||||
const uint8_t vertical_offset = 3;
|
||||
const uint8_t horizontal_offset = 3;
|
||||
const uint8_t string_width = canvas_string_width(canvas, str);
|
||||
const uint8_t icon_h_offset = 3;
|
||||
const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
|
||||
const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset + 1;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = canvas_width(canvas);
|
||||
const uint8_t y = 0 + button_height;
|
||||
|
||||
uint8_t line_x = x - button_width;
|
||||
uint8_t line_y = y - button_height;
|
||||
canvas_draw_box(canvas, line_x, line_y, button_width, button_height);
|
||||
canvas_draw_line(canvas, line_x - 1, line_y, line_x - 1, y - 1);
|
||||
canvas_draw_line(canvas, line_x - 2, line_y, line_x - 2, y - 2);
|
||||
canvas_draw_line(canvas, line_x - 3, line_y, line_x - 3, y - 3);
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
|
||||
canvas_draw_icon(
|
||||
canvas, x - horizontal_offset - icon_get_width(icon), y - icon_v_offset, icon);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
21
applications/plugins/subbrute/helpers/gui_top_buttons.h
Normal file
21
applications/plugins/subbrute/helpers/gui_top_buttons.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <gui/icon.h>
|
||||
#include <gui/icon_animation.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
/**
|
||||
* Thanks to the author of metronome
|
||||
* @param canvas
|
||||
* @param str
|
||||
*/
|
||||
void elements_button_top_left(Canvas* canvas, const char* str);
|
||||
|
||||
/**
|
||||
* Thanks to the author of metronome
|
||||
* @param canvas
|
||||
* @param str
|
||||
*/
|
||||
void elements_button_top_right(Canvas* canvas, const char* str);
|
||||
@@ -96,8 +96,11 @@ bool subbrute_worker_init_default_attack(
|
||||
instance->te = protocol->te;
|
||||
instance->repeat = protocol->repeat + extra_repeats;
|
||||
instance->load_index = 0;
|
||||
instance->file_key = NULL;
|
||||
instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits);
|
||||
instance->file_key = 0;
|
||||
instance->two_bytes = false;
|
||||
|
||||
instance->max_value =
|
||||
subbrute_protocol_calc_max_value(instance->attack, instance->bits, instance->two_bytes);
|
||||
|
||||
instance->initiated = true;
|
||||
instance->state = SubBruteWorkerStateReady;
|
||||
@@ -122,9 +125,10 @@ bool subbrute_worker_init_file_attack(
|
||||
SubBruteWorker* instance,
|
||||
uint64_t step,
|
||||
uint8_t load_index,
|
||||
const char* file_key,
|
||||
uint64_t file_key,
|
||||
SubBruteProtocol* protocol,
|
||||
uint8_t extra_repeats) {
|
||||
uint8_t extra_repeats,
|
||||
bool two_bytes) {
|
||||
furi_assert(instance);
|
||||
|
||||
if(instance->worker_running) {
|
||||
@@ -142,7 +146,10 @@ bool subbrute_worker_init_file_attack(
|
||||
instance->load_index = load_index;
|
||||
instance->repeat = protocol->repeat + extra_repeats;
|
||||
instance->file_key = file_key;
|
||||
instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits);
|
||||
instance->two_bytes = two_bytes;
|
||||
|
||||
instance->max_value =
|
||||
subbrute_protocol_calc_max_value(instance->attack, instance->bits, instance->two_bytes);
|
||||
|
||||
instance->initiated = true;
|
||||
instance->state = SubBruteWorkerStateReady;
|
||||
@@ -150,14 +157,15 @@ bool subbrute_worker_init_file_attack(
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"subbrute_worker_init_file_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld",
|
||||
"subbrute_worker_init_file_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld, key: %llX",
|
||||
subbrute_protocol_name(instance->attack),
|
||||
instance->bits,
|
||||
subbrute_protocol_preset(instance->preset),
|
||||
subbrute_protocol_file(instance->file),
|
||||
instance->te,
|
||||
instance->repeat,
|
||||
instance->max_value);
|
||||
instance->max_value,
|
||||
instance->file_key);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -244,7 +252,8 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste
|
||||
instance->te,
|
||||
instance->repeat,
|
||||
instance->load_index,
|
||||
instance->file_key);
|
||||
instance->file_key,
|
||||
instance->two_bytes);
|
||||
} else {
|
||||
subbrute_protocol_default_payload(
|
||||
stream, step, instance->bits, instance->te, instance->repeat);
|
||||
@@ -373,7 +382,8 @@ int32_t subbrute_worker_thread(void* context) {
|
||||
instance->te,
|
||||
instance->repeat,
|
||||
instance->load_index,
|
||||
instance->file_key);
|
||||
instance->file_key,
|
||||
instance->two_bytes);
|
||||
} else {
|
||||
subbrute_protocol_default_payload(
|
||||
stream, instance->step, instance->bits, instance->te, instance->repeat);
|
||||
|
||||
@@ -28,9 +28,10 @@ bool subbrute_worker_init_file_attack(
|
||||
SubBruteWorker* instance,
|
||||
uint64_t step,
|
||||
uint8_t load_index,
|
||||
const char* file_key,
|
||||
uint64_t file_key,
|
||||
SubBruteProtocol* protocol,
|
||||
uint8_t extra_repeats);
|
||||
uint8_t extra_repeats,
|
||||
bool two_bytes);
|
||||
bool subbrute_worker_start(SubBruteWorker* instance);
|
||||
void subbrute_worker_stop(SubBruteWorker* instance);
|
||||
bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step);
|
||||
|
||||
@@ -31,8 +31,9 @@ struct SubBruteWorker {
|
||||
uint8_t te;
|
||||
uint8_t repeat;
|
||||
uint8_t load_index; // Index of group to bruteforce in loaded file
|
||||
const char* file_key;
|
||||
uint64_t file_key;
|
||||
uint64_t max_value; // Max step
|
||||
bool two_bytes;
|
||||
|
||||
// Manual transmit
|
||||
uint32_t last_time_tx_data;
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -3,13 +3,6 @@
|
||||
|
||||
#define TAG "SubBruteSceneLoadFile"
|
||||
|
||||
//void subbrute_scene_load_file_callback(SubBruteCustomEvent event, void* context) {
|
||||
//// furi_assert(context);
|
||||
////
|
||||
//// SubBruteState* instance = (SubBruteState*)context;
|
||||
//// view_dispatcher_send_custom_event(instance->view_dispatcher, event);
|
||||
//}
|
||||
|
||||
void subbrute_scene_load_file_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
SubBruteState* instance = (SubBruteState*)context;
|
||||
@@ -24,8 +17,14 @@ void subbrute_scene_load_file_on_enter(void* context) {
|
||||
dialog_file_browser_set_basic_options(&browser_options, SUBBRUTE_FILE_EXT, &I_sub1_10px);
|
||||
|
||||
SubBruteFileResult load_result = SubBruteFileResultUnknown;
|
||||
// TODO: DELETE IT
|
||||
#ifdef SUBBRUTE_FAST_TRACK
|
||||
bool res = true;
|
||||
furi_string_printf(load_path, "%s", "/ext/subghz/princeton.sub");
|
||||
#else
|
||||
bool res =
|
||||
dialog_file_browser_show(instance->dialogs, load_path, app_folder, &browser_options);
|
||||
#endif
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
@@ -44,11 +43,12 @@ void subbrute_scene_load_file_on_enter(void* context) {
|
||||
if(load_result == SubBruteFileResultOk) {
|
||||
if(!subbrute_worker_init_file_attack(
|
||||
instance->worker,
|
||||
instance->device->key_index,
|
||||
instance->device->load_index,
|
||||
instance->device->file_key,
|
||||
instance->device->current_step,
|
||||
instance->device->bit_index,
|
||||
instance->device->key_from_file,
|
||||
instance->device->file_protocol_info,
|
||||
extra_repeats)) {
|
||||
extra_repeats,
|
||||
instance->device->two_bytes)) {
|
||||
furi_crash("Invalid attack set!");
|
||||
}
|
||||
// Ready to run!
|
||||
|
||||
@@ -20,7 +20,8 @@ void subbrute_scene_load_select_on_enter(void* context) {
|
||||
|
||||
instance->current_view = SubBruteViewMain;
|
||||
subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
|
||||
subbrute_main_view_set_index(view, 7, true, instance->device->file_key);
|
||||
subbrute_main_view_set_index(
|
||||
view, 7, true, instance->device->two_bytes, instance->device->key_from_file);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
|
||||
}
|
||||
@@ -38,21 +39,37 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event)
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubBruteCustomEventTypeIndexSelected) {
|
||||
instance->device->load_index = subbrute_main_view_get_index(instance->view_main);
|
||||
/*#ifdef FURI_DEBUG && !SUBBRUTE_FAST_TRACK
|
||||
view_dispatcher_stop(instance->view_dispatcher);
|
||||
consumed = true;
|
||||
#else*/
|
||||
instance->device->current_step = 0;
|
||||
instance->device->bit_index = subbrute_main_view_get_index(instance->view_main);
|
||||
instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main);
|
||||
uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
|
||||
instance->device->max_value = subbrute_protocol_calc_max_value(
|
||||
instance->device->attack,
|
||||
instance->device->bit_index,
|
||||
instance->device->two_bytes);
|
||||
|
||||
if(!subbrute_worker_init_file_attack(
|
||||
instance->worker,
|
||||
instance->device->key_index,
|
||||
instance->device->load_index,
|
||||
instance->device->file_key,
|
||||
instance->device->current_step,
|
||||
instance->device->bit_index,
|
||||
instance->device->key_from_file,
|
||||
instance->device->file_protocol_info,
|
||||
extra_repeats)) {
|
||||
extra_repeats,
|
||||
instance->device->two_bytes)) {
|
||||
furi_crash("Invalid attack set!");
|
||||
}
|
||||
scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
|
||||
/*#endif*/
|
||||
consumed = true;
|
||||
}
|
||||
} /* else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
|
||||
instance->device->two_bytes = true;
|
||||
} else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
|
||||
instance->device->two_bytes = false;
|
||||
}*/
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, SubBruteSceneStart)) {
|
||||
|
||||
@@ -45,7 +45,7 @@ void subbrute_scene_run_attack_on_enter(void* context) {
|
||||
instance->worker, subbrute_scene_run_attack_device_state_changed, instance);
|
||||
|
||||
if(!subbrute_worker_is_running(instance->worker)) {
|
||||
subbrute_worker_set_step(instance->worker, instance->device->key_index);
|
||||
subbrute_worker_set_step(instance->worker, instance->device->current_step);
|
||||
if(!subbrute_worker_start(instance->worker)) {
|
||||
view_dispatcher_send_custom_event(
|
||||
instance->view_dispatcher, SubBruteCustomEventTypeError);
|
||||
@@ -64,7 +64,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event)
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
uint64_t step = subbrute_worker_get_step(instance->worker);
|
||||
instance->device->key_index = step;
|
||||
instance->device->current_step = step;
|
||||
subbrute_attack_view_set_current_step(view, step);
|
||||
|
||||
if(event.event == SubBruteCustomEventTypeTransmitFinished) {
|
||||
@@ -89,12 +89,12 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event)
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
instance->scene_manager, SubBruteSceneSetupAttack);
|
||||
} else if(event.event == SubBruteCustomEventTypeUpdateView) {
|
||||
//subbrute_attack_view_set_current_step(view, instance->device->key_index);
|
||||
//subbrute_attack_view_set_current_step(view, instance->device->current_step);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
uint64_t step = subbrute_worker_get_step(instance->worker);
|
||||
instance->device->key_index = step;
|
||||
instance->device->current_step = step;
|
||||
subbrute_attack_view_set_current_step(view, step);
|
||||
|
||||
consumed = true;
|
||||
|
||||
@@ -37,14 +37,14 @@ void subbrute_scene_setup_attack_on_enter(void* context) {
|
||||
instance->worker, subbrute_scene_setup_attack_device_state_changed, context);
|
||||
if(subbrute_worker_is_running(instance->worker)) {
|
||||
subbrute_worker_stop(instance->worker);
|
||||
instance->device->key_index = subbrute_worker_get_step(instance->worker);
|
||||
instance->device->current_step = subbrute_worker_get_step(instance->worker);
|
||||
}
|
||||
|
||||
subbrute_attack_view_init_values(
|
||||
view,
|
||||
instance->device->attack,
|
||||
instance->device->max_value,
|
||||
instance->device->key_index,
|
||||
instance->device->current_step,
|
||||
false,
|
||||
instance->device->extra_repeats);
|
||||
|
||||
@@ -77,7 +77,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
|
||||
view,
|
||||
instance->device->attack,
|
||||
instance->device->max_value,
|
||||
instance->device->key_index,
|
||||
instance->device->current_step,
|
||||
false,
|
||||
instance->device->extra_repeats);
|
||||
scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveName);
|
||||
@@ -86,7 +86,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
|
||||
view,
|
||||
instance->device->attack,
|
||||
instance->device->max_value,
|
||||
instance->device->key_index,
|
||||
instance->device->current_step,
|
||||
false,
|
||||
instance->device->extra_repeats);
|
||||
scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
|
||||
@@ -99,7 +99,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
|
||||
// Blink
|
||||
notification_message(instance->notifications, &sequence_blink_green_100);
|
||||
subbrute_worker_transmit_current_key(
|
||||
instance->worker, instance->device->key_index);
|
||||
instance->worker, instance->device->current_step);
|
||||
// Stop
|
||||
notification_message(instance->notifications, &sequence_blink_stop);
|
||||
}
|
||||
@@ -128,9 +128,9 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
if(subbrute_worker_is_running(instance->worker)) {
|
||||
instance->device->key_index = subbrute_worker_get_step(instance->worker);
|
||||
instance->device->current_step = subbrute_worker_get_step(instance->worker);
|
||||
}
|
||||
subbrute_attack_view_set_current_step(view, instance->device->key_index);
|
||||
subbrute_attack_view_set_current_step(view, instance->device->current_step);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,14 @@ void subbrute_scene_start_on_enter(void* context) {
|
||||
|
||||
instance->current_view = SubBruteViewMain;
|
||||
subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance);
|
||||
subbrute_main_view_set_index(view, instance->device->attack, false, NULL);
|
||||
subbrute_main_view_set_index(view, instance->device->attack, false, instance->device->two_bytes, 0);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
|
||||
|
||||
// TODO: DELETE IT
|
||||
#ifdef SUBBRUTE_FAST_TRACK
|
||||
scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadFile);
|
||||
#endif
|
||||
}
|
||||
|
||||
void subbrute_scene_start_on_exit(void* context) {
|
||||
@@ -57,7 +62,7 @@ bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
(!subbrute_worker_init_default_attack(
|
||||
instance->worker,
|
||||
attack,
|
||||
instance->device->key_index,
|
||||
instance->device->current_step,
|
||||
instance->device->protocol_info,
|
||||
instance->device->extra_repeats))) {
|
||||
furi_crash("Invalid attack set!");
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
SubBruteDevice* subbrute_device_alloc() {
|
||||
SubBruteDevice* instance = malloc(sizeof(SubBruteDevice));
|
||||
|
||||
instance->key_index = 0;
|
||||
instance->current_step = 0;
|
||||
|
||||
instance->protocol_info = NULL;
|
||||
instance->file_protocol_info = NULL;
|
||||
@@ -23,7 +23,7 @@ SubBruteDevice* subbrute_device_alloc() {
|
||||
instance->environment, (void*)&subghz_protocol_registry);
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433);
|
||||
subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile);
|
||||
#else
|
||||
subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433);
|
||||
#endif
|
||||
@@ -51,32 +51,32 @@ void subbrute_device_free(SubBruteDevice* instance) {
|
||||
|
||||
uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step) {
|
||||
if(step > 0) {
|
||||
if((instance->key_index + step) - instance->max_value == 1) {
|
||||
instance->key_index = 0x00;
|
||||
if((instance->current_step + step) - instance->max_value == 1) {
|
||||
instance->current_step = 0x00;
|
||||
} else {
|
||||
uint64_t value = instance->key_index + step;
|
||||
uint64_t value = instance->current_step + step;
|
||||
if(value == instance->max_value) {
|
||||
instance->key_index = value;
|
||||
instance->current_step = value;
|
||||
} else {
|
||||
instance->key_index = value % instance->max_value;
|
||||
instance->current_step = value % instance->max_value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(instance->key_index + step == 0) {
|
||||
instance->key_index = 0x00;
|
||||
} else if(instance->key_index == 0) {
|
||||
instance->key_index = instance->max_value;
|
||||
if(instance->current_step + step == 0) {
|
||||
instance->current_step = 0x00;
|
||||
} else if(instance->current_step == 0) {
|
||||
instance->current_step = instance->max_value;
|
||||
} else {
|
||||
uint64_t value = ((instance->key_index + step) + instance->max_value);
|
||||
uint64_t value = ((instance->current_step + step) + instance->max_value);
|
||||
if(value == instance->max_value) {
|
||||
instance->key_index = value;
|
||||
instance->current_step = value;
|
||||
} else {
|
||||
instance->key_index = value % instance->max_value;
|
||||
instance->current_step = value % instance->max_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance->key_index;
|
||||
return instance->current_step;
|
||||
}
|
||||
|
||||
bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_name) {
|
||||
@@ -101,19 +101,20 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na
|
||||
instance->file_protocol_info->frequency,
|
||||
instance->file_protocol_info->preset,
|
||||
instance->file_protocol_info->file,
|
||||
instance->key_index,
|
||||
instance->current_step,
|
||||
instance->file_protocol_info->bits,
|
||||
instance->file_protocol_info->te,
|
||||
instance->file_protocol_info->repeat,
|
||||
instance->load_index,
|
||||
instance->file_key);
|
||||
instance->bit_index,
|
||||
instance->key_from_file,
|
||||
instance->two_bytes);
|
||||
} else {
|
||||
subbrute_protocol_default_generate_file(
|
||||
stream,
|
||||
instance->protocol_info->frequency,
|
||||
instance->protocol_info->preset,
|
||||
instance->protocol_info->file,
|
||||
instance->key_index,
|
||||
instance->current_step,
|
||||
instance->protocol_info->bits,
|
||||
instance->protocol_info->te,
|
||||
instance->protocol_info->repeat);
|
||||
@@ -174,8 +175,8 @@ SubBruteFileResult subbrute_device_attack_set(
|
||||
protocol_check_result = SubBruteFileResultOk;
|
||||
|
||||
// Calc max value
|
||||
instance->max_value =
|
||||
subbrute_protocol_calc_max_value(instance->attack, instance->protocol_info->bits);
|
||||
instance->max_value = subbrute_protocol_calc_max_value(
|
||||
instance->attack, instance->protocol_info->bits, instance->two_bytes);
|
||||
}
|
||||
#ifdef FURI_DEBUG
|
||||
bits = instance->protocol_info->bits;
|
||||
@@ -189,8 +190,8 @@ SubBruteFileResult subbrute_device_attack_set(
|
||||
protocol_check_result = SubBruteFileResultOk;
|
||||
|
||||
// Calc max value
|
||||
instance->max_value =
|
||||
subbrute_protocol_calc_max_value(instance->attack, instance->file_protocol_info->bits);
|
||||
instance->max_value = subbrute_protocol_calc_max_value(
|
||||
instance->attack, instance->file_protocol_info->bits, instance->two_bytes);
|
||||
#ifdef FURI_DEBUG
|
||||
bits = instance->file_protocol_info->bits;
|
||||
te = instance->file_protocol_info->te;
|
||||
@@ -257,25 +258,24 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
|
||||
}
|
||||
|
||||
// Frequency
|
||||
if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
|
||||
instance->file_protocol_info->frequency = temp_data32;
|
||||
if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
|
||||
result = SubBruteFileResultFrequencyNotAllowed;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
|
||||
FURI_LOG_E(TAG, "Missing or incorrect Frequency");
|
||||
result = SubBruteFileResultMissingOrIncorrectFrequency;
|
||||
break;
|
||||
}
|
||||
instance->file_protocol_info->frequency = temp_data32;
|
||||
if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) {
|
||||
result = SubBruteFileResultFrequencyNotAllowed;
|
||||
break;
|
||||
}
|
||||
|
||||
// Preset
|
||||
if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
|
||||
FURI_LOG_E(TAG, "Preset FAIL");
|
||||
result = SubBruteFileResultPresetInvalid;
|
||||
} else {
|
||||
instance->file_protocol_info->preset = subbrute_protocol_convert_preset(temp_str);
|
||||
break;
|
||||
}
|
||||
instance->file_protocol_info->preset = subbrute_protocol_convert_preset(temp_str);
|
||||
|
||||
const char* protocol_file = NULL;
|
||||
// Protocol
|
||||
@@ -283,13 +283,12 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
|
||||
FURI_LOG_E(TAG, "Missing Protocol");
|
||||
result = SubBruteFileResultMissingProtocol;
|
||||
break;
|
||||
} else {
|
||||
instance->file_protocol_info->file = subbrute_protocol_file_protocol_name(temp_str);
|
||||
protocol_file = subbrute_protocol_file(instance->file_protocol_info->file);
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Protocol: %s", protocol_file);
|
||||
#endif
|
||||
}
|
||||
instance->file_protocol_info->file = subbrute_protocol_file_protocol_name(temp_str);
|
||||
protocol_file = subbrute_protocol_file(instance->file_protocol_info->file);
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Protocol: %s", protocol_file);
|
||||
#endif
|
||||
|
||||
instance->decoder_result = subghz_receiver_search_decoder_base_by_name(
|
||||
instance->receiver, furi_string_get_cstr(temp_str));
|
||||
@@ -307,9 +306,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
|
||||
break;
|
||||
}
|
||||
#ifdef FURI_DEBUG
|
||||
else {
|
||||
FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name);
|
||||
}
|
||||
FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name);
|
||||
#endif
|
||||
|
||||
// Bit
|
||||
@@ -317,28 +314,120 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil
|
||||
FURI_LOG_E(TAG, "Missing or incorrect Bit");
|
||||
result = SubBruteFileResultMissingOrIncorrectBit;
|
||||
break;
|
||||
} else {
|
||||
instance->file_protocol_info->bits = temp_data32;
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Bit: %d", instance->file_protocol_info->bits);
|
||||
#endif
|
||||
}
|
||||
instance->file_protocol_info->bits = temp_data32;
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Bit: %d", instance->file_protocol_info->bits);
|
||||
#endif
|
||||
|
||||
// TODO: Delete this
|
||||
// Key
|
||||
if(!flipper_format_read_string(fff_data_file, "Key", temp_str)) {
|
||||
FURI_LOG_E(TAG, "Missing or incorrect Key");
|
||||
// if(!flipper_format_read_string(fff_data_file, "Key", temp_str)) {
|
||||
// FURI_LOG_E(TAG, "Missing or incorrect Key");
|
||||
// result = SubBruteFileResultMissingOrIncorrectKey;
|
||||
// break;
|
||||
// } else {
|
||||
// snprintf(
|
||||
// instance->current_key_from_file,
|
||||
// sizeof(instance->current_key_from_file),
|
||||
// "%s",
|
||||
// furi_string_get_cstr(temp_str));
|
||||
// #ifdef FURI_DEBUG
|
||||
// FURI_LOG_D(TAG, "Key: %s", instance->current_key_from_file);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// flipper_format_rewind(fff_data_file);
|
||||
|
||||
uint8_t key_data[sizeof(uint64_t)] = {0};
|
||||
if(!flipper_format_read_hex(fff_data_file, "Key", key_data, sizeof(uint64_t))) {
|
||||
FURI_LOG_E(TAG, "Missing Key");
|
||||
result = SubBruteFileResultMissingOrIncorrectKey;
|
||||
break;
|
||||
} else {
|
||||
snprintf(
|
||||
instance->file_key,
|
||||
sizeof(instance->file_key),
|
||||
"%s",
|
||||
furi_string_get_cstr(temp_str));
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Key: %s", instance->file_key);
|
||||
#endif
|
||||
}
|
||||
uint64_t data = 0;
|
||||
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
||||
data = (data << 8) | key_data[i];
|
||||
}
|
||||
#if FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "Key: %.16llX", data);
|
||||
#endif
|
||||
instance->key_from_file = data;
|
||||
|
||||
// uint16_t add_value = 0x0001;
|
||||
// uint8_t bit_index = 7;
|
||||
// bool two_bytes = true;
|
||||
// uint8_t p[8];
|
||||
// for(int i = 0; i < 8; i++) {
|
||||
// p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
|
||||
// }
|
||||
// uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
|
||||
// FURI_LOG_D(TAG, "num: 0x%04X", num);
|
||||
// num += add_value;
|
||||
// FURI_LOG_D(TAG, "num added: 0x%04X", num);
|
||||
// uint8_t low_byte = num & (0xff);
|
||||
// uint8_t high_byte = (num >> 8) & 0xff;
|
||||
|
||||
// data = 0;
|
||||
// for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
||||
// if(i == bit_index - 1 && two_bytes) {
|
||||
// data = (data << 8) | high_byte;
|
||||
// data = (data << 8) | low_byte;
|
||||
// i++;
|
||||
// } else if(i == bit_index) {
|
||||
// data = (data << 8) | low_byte;
|
||||
// } else {
|
||||
// data = (data << 8) | p[i];
|
||||
// }
|
||||
// }
|
||||
// #if FURI_DEBUG
|
||||
// furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
|
||||
// FURI_LOG_D(
|
||||
// TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
|
||||
// #endif
|
||||
// uint8_t key_data[sizeof(uint64_t)] = {0};
|
||||
// if(!flipper_format_read_hex(fff_data_file, "Key", key_data, sizeof(uint64_t))) {
|
||||
// FURI_LOG_E(TAG, "Missing Key");
|
||||
// result = SubBruteFileResultMissingOrIncorrectKey;
|
||||
// break;
|
||||
// }
|
||||
// uint64_t data = 0;
|
||||
// for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
||||
// data = (data << 8) | key_data[i];
|
||||
// }
|
||||
// instance->key_from_file = data;
|
||||
|
||||
// uint16_t add_value = 0x0001;
|
||||
// uint8_t bit_index = 7;
|
||||
// bool two_bytes = true;
|
||||
|
||||
// uint8_t p[8];
|
||||
// for(int i = 0; i < 8; i++) {
|
||||
// p[i] = (uint8_t)(instance->key_from_file >> 8 * (7 - i)) & 0xFF;
|
||||
// }
|
||||
// uint16_t num = two_bytes ? (p[bit_index - 1] << 8) | p[bit_index] : p[bit_index];
|
||||
// FURI_LOG_D(TAG, "num: 0x%04X", num);
|
||||
// num += add_value;
|
||||
// FURI_LOG_D(TAG, "num added: 0x%04X", num);
|
||||
// uint8_t low_byte = num & (0xff);
|
||||
// uint8_t high_byte = (num >> 8) & 0xff;
|
||||
|
||||
// data = 0;
|
||||
// for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
||||
// if(i == bit_index - 1 && two_bytes) {
|
||||
// data = (data << 8) | high_byte;
|
||||
// data = (data << 8) | low_byte;
|
||||
// i++;
|
||||
// } else if(i == bit_index) {
|
||||
// data = (data << 8) | low_byte;
|
||||
// } else {
|
||||
// data = (data << 8) | p[i];
|
||||
// }
|
||||
// }
|
||||
|
||||
// furi_string_printf(temp_str, "Key: %lX", (uint32_t)(data & 0xFFFFFFFF));
|
||||
// FURI_LOG_D(
|
||||
// TAG, "H: 0x%02X, L: 0x%02X, %s", high_byte, low_byte, furi_string_get_cstr(temp_str));
|
||||
|
||||
// TE
|
||||
if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) {
|
||||
@@ -394,15 +483,15 @@ void subbrute_device_attack_set_default_values(
|
||||
FURI_LOG_D(TAG, "subbrute_device_attack_set_default_values");
|
||||
#endif
|
||||
instance->attack = default_attack;
|
||||
instance->key_index = 0x00;
|
||||
instance->load_index = 0x00;
|
||||
instance->current_step = 0x00;
|
||||
instance->bit_index = 0x00;
|
||||
instance->extra_repeats = 0;
|
||||
instance->two_bytes = false;
|
||||
memset(instance->current_key, 0, sizeof(instance->current_key));
|
||||
|
||||
if(default_attack != SubBruteAttackLoadFile) {
|
||||
memset(instance->file_key, 0, sizeof(instance->file_key));
|
||||
|
||||
instance->max_value = (uint64_t)0x00;
|
||||
instance->max_value = subbrute_protocol_calc_max_value(
|
||||
instance->attack, instance->bit_index, instance->two_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,7 @@ typedef struct {
|
||||
SubBruteProtocol* file_protocol_info;
|
||||
|
||||
// Current step
|
||||
uint64_t key_index;
|
||||
// Index of group to bruteforce in loaded file
|
||||
uint8_t load_index;
|
||||
uint64_t current_step;
|
||||
|
||||
// SubGhz
|
||||
SubGhzReceiver* receiver;
|
||||
@@ -52,7 +50,11 @@ typedef struct {
|
||||
|
||||
// Loaded info for attack type
|
||||
char current_key[SUBBRUTE_PAYLOAD_SIZE];
|
||||
char file_key[SUBBRUTE_MAX_LEN_NAME];
|
||||
uint64_t key_from_file;
|
||||
uint64_t current_key_from_file;
|
||||
bool two_bytes;
|
||||
// Index of group to bruteforce in loaded file
|
||||
uint8_t bit_index;
|
||||
} SubBruteDevice;
|
||||
|
||||
SubBruteDevice* subbrute_device_alloc();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <gui/modules/widget.h>
|
||||
#include <gui/modules/loading.h>
|
||||
|
||||
#include <SubGHz_Bruteforcer_icons.h>
|
||||
#include "SubGHz_Bruteforcer_icons.h"
|
||||
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "views/subbrute_attack_view.h"
|
||||
#include "views/subbrute_main_view.h"
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
//#define SUBBRUTE_FAST_TRACK false
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SubBruteViewNone,
|
||||
SubBruteViewMain,
|
||||
|
||||
@@ -25,6 +25,17 @@ const SubBruteProtocol subbrute_protocol_came_12bit_307 = {
|
||||
.preset = FuriHalSubGhzPresetOok650Async,
|
||||
.file = CAMEFileProtocol};
|
||||
|
||||
/**
|
||||
* CAME 12bit 315MHz
|
||||
*/
|
||||
const SubBruteProtocol subbrute_protocol_came_12bit_315 = {
|
||||
.frequency = 315000000,
|
||||
.bits = 12,
|
||||
.te = 0,
|
||||
.repeat = 3,
|
||||
.preset = FuriHalSubGhzPresetOok650Async,
|
||||
.file = CAMEFileProtocol};
|
||||
|
||||
/**
|
||||
* CAME 12bit 433MHz
|
||||
*/
|
||||
@@ -243,6 +254,7 @@ const SubBruteProtocol subbrute_protocol_load_file =
|
||||
static const char* subbrute_protocol_names[] = {
|
||||
[SubBruteAttackCAME12bit303] = "CAME 12bit 303MHz",
|
||||
[SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz",
|
||||
[SubBruteAttackCAME12bit315] = "CAME 12bit 315MHz",
|
||||
[SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz",
|
||||
[SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz",
|
||||
[SubBruteAttackNICE12bit433] = "NICE 12bit 433MHz",
|
||||
@@ -279,6 +291,7 @@ static const char* subbrute_protocol_presets[] = {
|
||||
const SubBruteProtocol* subbrute_protocol_registry[] = {
|
||||
[SubBruteAttackCAME12bit303] = &subbrute_protocol_came_12bit_303,
|
||||
[SubBruteAttackCAME12bit307] = &subbrute_protocol_came_12bit_307,
|
||||
[SubBruteAttackCAME12bit315] = &subbrute_protocol_came_12bit_315,
|
||||
[SubBruteAttackCAME12bit433] = &subbrute_protocol_came_12bit_433,
|
||||
[SubBruteAttackCAME12bit868] = &subbrute_protocol_came_12bit_868,
|
||||
[SubBruteAttackNICE12bit433] = &subbrute_protocol_nice_12bit_433,
|
||||
@@ -366,27 +379,74 @@ SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name) {
|
||||
return UnknownFileProtocol;
|
||||
}
|
||||
|
||||
void subbrute_protocol_create_candidate_for_existing_file(
|
||||
FuriString* candidate,
|
||||
uint64_t step,
|
||||
uint8_t bit_index,
|
||||
uint64_t file_key,
|
||||
bool two_bytes) {
|
||||
uint8_t p[8];
|
||||
for(int i = 0; i < 8; i++) {
|
||||
p[i] = (uint8_t)(file_key >> 8 * (7 - i)) & 0xFF;
|
||||
}
|
||||
uint8_t low_byte = step & (0xff);
|
||||
uint8_t high_byte = (step >> 8) & 0xff;
|
||||
|
||||
size_t size = sizeof(uint64_t);
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
if(i == bit_index - 1 && two_bytes) {
|
||||
furi_string_cat_printf(candidate, "%02X %02X", high_byte, low_byte);
|
||||
i++;
|
||||
} else if(i == bit_index) {
|
||||
furi_string_cat_printf(candidate, "%02X", low_byte);
|
||||
} else if(p[i] != 0) {
|
||||
furi_string_cat_printf(candidate, "%02X", p[i]);
|
||||
} else {
|
||||
furi_string_cat_printf(candidate, "%s", "00");
|
||||
}
|
||||
|
||||
if(i < size - 1) {
|
||||
furi_string_push_back(candidate, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "file candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
|
||||
#endif
|
||||
}
|
||||
|
||||
void subbrute_protocol_create_candidate_for_default(FuriString* candidate, uint64_t step) {
|
||||
uint8_t p[8];
|
||||
for(int i = 0; i < 8; i++) {
|
||||
p[i] = (uint8_t)(step >> 8 * (7 - i)) & 0xFF;
|
||||
}
|
||||
|
||||
size_t size = sizeof(uint64_t);
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
if(p[i] != 0) {
|
||||
furi_string_cat_printf(candidate, "%02X", p[i]);
|
||||
} else {
|
||||
furi_string_cat_printf(candidate, "%s", "00");
|
||||
}
|
||||
|
||||
if(i < size - 1) {
|
||||
furi_string_push_back(candidate, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
|
||||
#endif
|
||||
}
|
||||
|
||||
void subbrute_protocol_default_payload(
|
||||
Stream* stream,
|
||||
uint64_t step,
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat) {
|
||||
FuriString* candidate = furi_string_alloc_set_str(" ");
|
||||
|
||||
FuriString* buffer = furi_string_alloc_printf("%16llX", step);
|
||||
int j = 0;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
if(furi_string_get_char(buffer, i) != ' ') {
|
||||
furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i));
|
||||
} else {
|
||||
furi_string_set_char(candidate, i + j, '0');
|
||||
}
|
||||
if(i % 2 != 0) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
furi_string_free(buffer);
|
||||
FuriString* candidate = furi_string_alloc();
|
||||
subbrute_protocol_create_candidate_for_default(candidate, step);
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(
|
||||
@@ -420,13 +480,12 @@ void subbrute_protocol_file_payload(
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat,
|
||||
uint8_t load_index,
|
||||
const char* file_key) {
|
||||
uint8_t bit_index,
|
||||
uint64_t file_key,
|
||||
bool two_bytes) {
|
||||
FuriString* candidate = furi_string_alloc();
|
||||
char subbrute_payload_byte[4];
|
||||
furi_string_set_str(candidate, file_key);
|
||||
snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step);
|
||||
furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte);
|
||||
subbrute_protocol_create_candidate_for_existing_file(
|
||||
candidate, step, bit_index, file_key, two_bytes);
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(
|
||||
@@ -464,21 +523,8 @@ void subbrute_protocol_default_generate_file(
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat) {
|
||||
FuriString* candidate = furi_string_alloc_set_str(" ");
|
||||
|
||||
FuriString* buffer = furi_string_alloc_printf("%16llX", step);
|
||||
int j = 0;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
if(furi_string_get_char(buffer, i) != ' ') {
|
||||
furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i));
|
||||
} else {
|
||||
furi_string_set_char(candidate, i + j, '0');
|
||||
}
|
||||
if(i % 2 != 0) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
furi_string_free(buffer);
|
||||
FuriString* candidate = furi_string_alloc();
|
||||
subbrute_protocol_create_candidate_for_default(candidate, step);
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
|
||||
@@ -520,17 +566,15 @@ void subbrute_protocol_file_generate_file(
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat,
|
||||
uint8_t load_index,
|
||||
const char* file_key) {
|
||||
uint8_t bit_index,
|
||||
uint64_t file_key,
|
||||
bool two_bytes) {
|
||||
FuriString* candidate = furi_string_alloc();
|
||||
char subbrute_payload_byte[4];
|
||||
furi_string_set_str(candidate, file_key);
|
||||
snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step);
|
||||
furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte);
|
||||
// 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);
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
|
||||
#endif
|
||||
stream_clean(stream);
|
||||
if(te) {
|
||||
stream_write_format(
|
||||
@@ -558,10 +602,11 @@ void subbrute_protocol_file_generate_file(
|
||||
furi_string_free(candidate);
|
||||
}
|
||||
|
||||
uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) {
|
||||
uint64_t
|
||||
subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits, bool two_bytes) {
|
||||
uint64_t max_value;
|
||||
if(attack_type == SubBruteAttackLoadFile) {
|
||||
max_value = 0xFF;
|
||||
max_value = two_bytes ? 0xFFFF : 0xFF;
|
||||
} else {
|
||||
FuriString* max_value_s;
|
||||
max_value_s = furi_string_alloc();
|
||||
|
||||
@@ -26,6 +26,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
SubBruteAttackCAME12bit303,
|
||||
SubBruteAttackCAME12bit307,
|
||||
SubBruteAttackCAME12bit315,
|
||||
SubBruteAttackCAME12bit433,
|
||||
SubBruteAttackCAME12bit868,
|
||||
SubBruteAttackNICE12bit433,
|
||||
@@ -78,8 +79,9 @@ void subbrute_protocol_file_payload(
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat,
|
||||
uint8_t load_index,
|
||||
const char* file_key);
|
||||
uint8_t bit_index,
|
||||
uint64_t file_key,
|
||||
bool two_bytes);
|
||||
void subbrute_protocol_default_generate_file(
|
||||
Stream* stream,
|
||||
uint32_t frequency,
|
||||
@@ -98,6 +100,8 @@ void subbrute_protocol_file_generate_file(
|
||||
uint8_t bits,
|
||||
uint8_t te,
|
||||
uint8_t repeat,
|
||||
uint8_t load_index,
|
||||
const char* file_key);
|
||||
uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits);
|
||||
uint8_t bit_index,
|
||||
uint64_t file_key,
|
||||
bool two_bytes);
|
||||
uint64_t
|
||||
subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits, bool two_bytes);
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "subbrute_attack_view.h"
|
||||
#include "../subbrute_i.h"
|
||||
#include "../subbrute_protocols.h"
|
||||
#include "../helpers/gui_top_buttons.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
@@ -255,74 +256,6 @@ void subbrute_attack_view_exit(void* context) {
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thanks to the author of metronome
|
||||
* @param canvas
|
||||
* @param str
|
||||
*/
|
||||
void elements_button_top_left(Canvas* canvas, const char* str) {
|
||||
const Icon* icon = &I_ButtonUp_7x4;
|
||||
|
||||
const uint8_t button_height = 12;
|
||||
const uint8_t vertical_offset = 3;
|
||||
const uint8_t horizontal_offset = 3;
|
||||
const uint8_t string_width = canvas_string_width(canvas, str);
|
||||
const uint8_t icon_h_offset = 3;
|
||||
const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
|
||||
const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = 0;
|
||||
const uint8_t y = 0 + button_height;
|
||||
|
||||
uint8_t line_x = x + button_width;
|
||||
uint8_t line_y = y - button_height;
|
||||
canvas_draw_box(canvas, x, line_y, button_width, button_height);
|
||||
canvas_draw_line(canvas, line_x + 0, line_y, line_x + 0, y - 1);
|
||||
canvas_draw_line(canvas, line_x + 1, line_y, line_x + 1, y - 2);
|
||||
canvas_draw_line(canvas, line_x + 2, line_y, line_x + 2, y - 3);
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, icon);
|
||||
canvas_draw_str(
|
||||
canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thanks to the author of metronome
|
||||
* @param canvas
|
||||
* @param str
|
||||
*/
|
||||
void elements_button_top_right(Canvas* canvas, const char* str) {
|
||||
const Icon* icon = &I_ButtonDown_7x4;
|
||||
|
||||
const uint8_t button_height = 12;
|
||||
const uint8_t vertical_offset = 3;
|
||||
const uint8_t horizontal_offset = 3;
|
||||
const uint8_t string_width = canvas_string_width(canvas, str);
|
||||
const uint8_t icon_h_offset = 3;
|
||||
const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
|
||||
const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset + 1;
|
||||
const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
|
||||
|
||||
const uint8_t x = canvas_width(canvas);
|
||||
const uint8_t y = 0 + button_height;
|
||||
|
||||
uint8_t line_x = x - button_width;
|
||||
uint8_t line_y = y - button_height;
|
||||
canvas_draw_box(canvas, line_x, line_y, button_width, button_height);
|
||||
canvas_draw_line(canvas, line_x - 1, line_y, line_x - 1, y - 1);
|
||||
canvas_draw_line(canvas, line_x - 2, line_y, line_x - 2, y - 2);
|
||||
canvas_draw_line(canvas, line_x - 3, line_y, line_x - 3, y - 3);
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
|
||||
canvas_draw_icon(
|
||||
canvas, x - horizontal_offset - icon_get_width(icon), y - icon_v_offset, icon);
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
|
||||
void subbrute_attack_view_draw(Canvas* canvas, void* context) {
|
||||
furi_assert(context);
|
||||
SubBruteAttackViewModel* model = (SubBruteAttackViewModel*)context;
|
||||
@@ -339,9 +272,27 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) {
|
||||
}
|
||||
|
||||
// Current Step / Max value
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
snprintf(buffer, sizeof(buffer), "%04d/%04d", (int)model->current_step, (int)model->max_value);
|
||||
canvas_draw_str_aligned(canvas, 64, 17, AlignCenter, AlignTop, buffer);
|
||||
const uint8_t y_frequency = 17;
|
||||
if(model->max_value > 9999) {
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
snprintf(buffer, sizeof(buffer), "%05d/", (int)model->current_step);
|
||||
canvas_draw_str_aligned(canvas, 5, y_frequency, AlignLeft, AlignTop, buffer);
|
||||
|
||||
// Second part with another font, because BigNumber is out of screen bounds
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
snprintf(buffer, sizeof(buffer), "%05d", (int)model->max_value);
|
||||
canvas_draw_str_aligned(canvas, 107, y_frequency + 13, AlignRight, AlignBottom, buffer);
|
||||
} else if(model->max_value <= 0xFF) {
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
snprintf(
|
||||
buffer, sizeof(buffer), "%03d/%03d", (int)model->current_step, (int)model->max_value);
|
||||
canvas_draw_str_aligned(canvas, 64, y_frequency, AlignCenter, AlignTop, buffer);
|
||||
} else {
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
snprintf(
|
||||
buffer, sizeof(buffer), "%04d/%04d", (int)model->current_step, (int)model->max_value);
|
||||
canvas_draw_str_aligned(canvas, 64, y_frequency, AlignCenter, AlignTop, buffer);
|
||||
}
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "subbrute_main_view.h"
|
||||
#include "../subbrute_i.h"
|
||||
#include "../subbrute_protocols.h"
|
||||
#include "../helpers/gui_top_buttons.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
@@ -10,6 +11,15 @@
|
||||
#define TAG "SubBruteMainView"
|
||||
|
||||
#define ITEMS_ON_SCREEN 3
|
||||
#define ITEMS_INTERVAL 1
|
||||
#define ITEM_WIDTH 14
|
||||
#define ITEM_Y 27
|
||||
#define ITEM_HEIGHT 13
|
||||
#define TEXT_X 6
|
||||
#define TEXT_Y 37
|
||||
#define TEXT_INTERVAL 3
|
||||
#define TEXT_WIDTH 12
|
||||
#define ITEM_FRAME_RADIUS 2
|
||||
|
||||
struct SubBruteMainView {
|
||||
View* view;
|
||||
@@ -17,7 +27,8 @@ struct SubBruteMainView {
|
||||
void* context;
|
||||
uint8_t index;
|
||||
bool is_select_byte;
|
||||
const char* key_field;
|
||||
bool two_bytes;
|
||||
uint64_t key_from_file;
|
||||
uint8_t extra_repeats;
|
||||
uint8_t window_position;
|
||||
};
|
||||
@@ -27,7 +38,8 @@ typedef struct {
|
||||
uint8_t extra_repeats;
|
||||
uint8_t window_position;
|
||||
bool is_select_byte;
|
||||
const char* key_field;
|
||||
bool two_bytes;
|
||||
uint64_t key_from_file;
|
||||
} SubBruteMainViewModel;
|
||||
|
||||
void subbrute_main_view_set_callback(
|
||||
@@ -41,84 +53,105 @@ void subbrute_main_view_set_callback(
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
FuriString* center_displayed_key(const char* key_cstr, uint8_t index) {
|
||||
uint8_t str_index = (index * 3);
|
||||
void subbrute_main_view_center_displayed_key(
|
||||
Canvas* canvas,
|
||||
uint64_t key,
|
||||
uint8_t index,
|
||||
bool two_bytes) {
|
||||
uint8_t text_x = TEXT_X;
|
||||
uint8_t item_x = TEXT_X - ITEMS_INTERVAL;
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
char display_menu[] = {
|
||||
'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
|
||||
for(int i = 0; i < 8; i++) {
|
||||
char current_value[3] = {0};
|
||||
uint8_t byte_value = (uint8_t)(key >> 8 * (7 - i)) & 0xFF;
|
||||
snprintf(current_value, sizeof(current_value), "%02X", byte_value);
|
||||
|
||||
if(key_cstr != NULL) {
|
||||
if(index > 1) {
|
||||
display_menu[0] = key_cstr[str_index - 6];
|
||||
display_menu[1] = key_cstr[str_index - 5];
|
||||
// For two bytes we need to select prev location
|
||||
if(!two_bytes && i == index) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_rbox(
|
||||
canvas, item_x - 1, ITEM_Y, ITEM_WIDTH + 1, ITEM_HEIGHT, ITEM_FRAME_RADIUS);
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
|
||||
} else if(two_bytes && (i == index || i == index - 1)) {
|
||||
if(i == index) {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_rbox(
|
||||
canvas,
|
||||
item_x - ITEMS_INTERVAL - ITEM_WIDTH - 1,
|
||||
ITEM_Y,
|
||||
ITEM_WIDTH * 2 + ITEMS_INTERVAL * 2 + 1,
|
||||
ITEM_HEIGHT,
|
||||
ITEM_FRAME_RADIUS);
|
||||
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
|
||||
|
||||
// Redraw prev element with white
|
||||
memset(current_value, 0, sizeof(current_value));
|
||||
byte_value = (uint8_t)(key >> 8 * (7 - i + 1)) & 0xFF;
|
||||
snprintf(current_value, sizeof(current_value), "%02X", byte_value);
|
||||
canvas_draw_str(
|
||||
canvas, text_x - (TEXT_WIDTH + TEXT_INTERVAL), TEXT_Y, current_value);
|
||||
} else {
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
|
||||
}
|
||||
} else {
|
||||
display_menu[0] = ' ';
|
||||
display_menu[1] = ' ';
|
||||
}
|
||||
|
||||
if(index > 0) {
|
||||
display_menu[3] = key_cstr[str_index - 3];
|
||||
display_menu[4] = key_cstr[str_index - 2];
|
||||
} else {
|
||||
display_menu[3] = ' ';
|
||||
display_menu[4] = ' ';
|
||||
}
|
||||
|
||||
display_menu[7] = key_cstr[str_index];
|
||||
display_menu[8] = key_cstr[str_index + 1];
|
||||
|
||||
if((str_index + 4) <= (uint8_t)strlen(key_cstr)) {
|
||||
display_menu[11] = key_cstr[str_index + 3];
|
||||
display_menu[12] = key_cstr[str_index + 4];
|
||||
} else {
|
||||
display_menu[11] = ' ';
|
||||
display_menu[12] = ' ';
|
||||
}
|
||||
|
||||
if((str_index + 8) <= (uint8_t)strlen(key_cstr)) {
|
||||
display_menu[14] = key_cstr[str_index + 6];
|
||||
display_menu[15] = key_cstr[str_index + 7];
|
||||
} else {
|
||||
display_menu[14] = ' ';
|
||||
display_menu[15] = ' ';
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_draw_str(canvas, text_x, TEXT_Y, current_value);
|
||||
}
|
||||
text_x = text_x + TEXT_WIDTH + TEXT_INTERVAL;
|
||||
item_x = item_x + ITEM_WIDTH + ITEMS_INTERVAL;
|
||||
}
|
||||
return furi_string_alloc_set(display_menu);
|
||||
|
||||
// Return normal color
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
}
|
||||
|
||||
void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) {
|
||||
// Title
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz BruteForcer 3.2");
|
||||
canvas_invert_color(canvas);
|
||||
|
||||
uint16_t screen_width = canvas_width(canvas);
|
||||
uint16_t screen_height = canvas_height(canvas);
|
||||
|
||||
if(model->is_select_byte) {
|
||||
#ifdef FURI_DEBUG
|
||||
//FURI_LOG_D(TAG, "key_field: %s", model->key_field);
|
||||
//FURI_LOG_D(TAG, "key_from_file: %s", model->key_from_file);
|
||||
#endif
|
||||
char msg_index[18];
|
||||
snprintf(msg_index, sizeof(msg_index), "Field index : %d", model->index);
|
||||
canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignTop, msg_index);
|
||||
|
||||
FuriString* menu_items;
|
||||
|
||||
menu_items = center_displayed_key(model->key_field, model->index);
|
||||
//char msg_index[18];
|
||||
//snprintf(msg_index, sizeof(msg_index), "Field index: %d", model->index);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 40, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
|
||||
canvas, 64, 17, AlignCenter, AlignTop, "Please select values to calc:");
|
||||
|
||||
subbrute_main_view_center_displayed_key(
|
||||
canvas, model->key_from_file, model->index, model->two_bytes);
|
||||
//const char* line = furi_string_get_cstr(menu_items);
|
||||
//canvas_set_font(canvas, FontSecondary);
|
||||
//canvas_draw_str_aligned(
|
||||
// canvas, 64, 37, AlignCenter, AlignTop, furi_string_get_cstr(menu_items));
|
||||
|
||||
elements_button_center(canvas, "Select");
|
||||
elements_button_left(canvas, "<");
|
||||
elements_button_right(canvas, ">");
|
||||
|
||||
furi_string_reset(menu_items);
|
||||
furi_string_free(menu_items);
|
||||
if(model->index > 0) {
|
||||
elements_button_left(canvas, " ");
|
||||
}
|
||||
if(model->index < 7) {
|
||||
elements_button_right(canvas, " ");
|
||||
}
|
||||
// Switch to another mode
|
||||
if(model->two_bytes) {
|
||||
elements_button_top_left(canvas, "One byte");
|
||||
} else {
|
||||
elements_button_top_left(canvas, "Two bytes");
|
||||
}
|
||||
} else {
|
||||
// Title
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT);
|
||||
canvas_invert_color(canvas);
|
||||
canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz BruteForcer 3.3");
|
||||
canvas_invert_color(canvas);
|
||||
|
||||
// Menu
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
@@ -257,18 +290,34 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(event->key == InputKeyLeft && is_short) {
|
||||
if(instance->index > 0) {
|
||||
} else if(is_short) {
|
||||
if(event->key == InputKeyLeft) {
|
||||
if((instance->index > 0 && !instance->two_bytes) ||
|
||||
(instance->two_bytes && instance->index > 1)) {
|
||||
instance->index--;
|
||||
}
|
||||
updated = true;
|
||||
} else if(event->key == InputKeyRight && is_short) {
|
||||
consumed = true;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(instance->index < 7) {
|
||||
instance->index++;
|
||||
}
|
||||
updated = true;
|
||||
} else if(event->key == InputKeyOk && is_short) {
|
||||
consumed = true;
|
||||
} else if(event->key == InputKeyUp) {
|
||||
instance->two_bytes = !instance->two_bytes;
|
||||
// Because index is changing
|
||||
if(instance->two_bytes && instance->index < 7) {
|
||||
instance->index++;
|
||||
}
|
||||
// instance->callback(
|
||||
// instance->two_bytes ? SubBruteCustomEventTypeChangeStepUp :
|
||||
// SubBruteCustomEventTypeChangeStepDown,
|
||||
// instance->context);
|
||||
|
||||
updated = true;
|
||||
consumed = true;
|
||||
} else if(event->key == InputKeyOk) {
|
||||
instance->callback(SubBruteCustomEventTypeIndexSelected, instance->context);
|
||||
consumed = true;
|
||||
updated = true;
|
||||
@@ -282,8 +331,9 @@ bool subbrute_main_view_input(InputEvent* event, void* context) {
|
||||
{
|
||||
model->index = instance->index;
|
||||
model->window_position = instance->window_position;
|
||||
model->key_field = instance->key_field;
|
||||
model->key_from_file = instance->key_from_file;
|
||||
model->is_select_byte = instance->is_select_byte;
|
||||
model->two_bytes = instance->two_bytes;
|
||||
model->extra_repeats = instance->extra_repeats;
|
||||
},
|
||||
true);
|
||||
@@ -318,24 +368,25 @@ SubBruteMainView* subbrute_main_view_alloc() {
|
||||
view_set_enter_callback(instance->view, subbrute_main_view_enter);
|
||||
view_set_exit_callback(instance->view, subbrute_main_view_exit);
|
||||
|
||||
instance->index = 0;
|
||||
instance->window_position = 0;
|
||||
instance->key_from_file = 0;
|
||||
instance->is_select_byte = false;
|
||||
instance->two_bytes = false;
|
||||
instance->extra_repeats = 0;
|
||||
with_view_model(
|
||||
instance->view,
|
||||
SubBruteMainViewModel * model,
|
||||
{
|
||||
model->index = 0;
|
||||
model->window_position = 0;
|
||||
model->key_field = NULL;
|
||||
model->is_select_byte = false;
|
||||
model->extra_repeats = 0;
|
||||
model->index = instance->index;
|
||||
model->window_position = instance->window_position;
|
||||
model->key_from_file = instance->key_from_file;
|
||||
model->is_select_byte = instance->is_select_byte;
|
||||
model->two_bytes = instance->two_bytes;
|
||||
model->extra_repeats = instance->extra_repeats;
|
||||
},
|
||||
true);
|
||||
|
||||
instance->index = 0;
|
||||
instance->window_position = 0;
|
||||
instance->key_field = NULL;
|
||||
instance->is_select_byte = false;
|
||||
instance->extra_repeats = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -355,14 +406,16 @@ void subbrute_main_view_set_index(
|
||||
SubBruteMainView* instance,
|
||||
uint8_t idx,
|
||||
bool is_select_byte,
|
||||
const char* key_field) {
|
||||
bool two_bytes,
|
||||
uint64_t key_from_file) {
|
||||
furi_assert(instance);
|
||||
furi_assert(idx < SubBruteAttackTotalCount);
|
||||
#ifdef FURI_DEBUG
|
||||
FURI_LOG_I(TAG, "Set index: %d, IS_SELECT_BYTE: %d", idx, is_select_byte);
|
||||
FURI_LOG_I(TAG, "Set index: %d, is_select_byte: %d", idx, is_select_byte);
|
||||
#endif
|
||||
instance->is_select_byte = is_select_byte;
|
||||
instance->key_field = key_field;
|
||||
instance->two_bytes = two_bytes;
|
||||
instance->key_from_file = key_from_file;
|
||||
instance->index = idx;
|
||||
instance->window_position = idx;
|
||||
|
||||
@@ -386,8 +439,9 @@ void subbrute_main_view_set_index(
|
||||
{
|
||||
model->index = instance->index;
|
||||
model->window_position = instance->window_position;
|
||||
model->key_field = instance->key_field;
|
||||
model->key_from_file = instance->key_from_file;
|
||||
model->is_select_byte = instance->is_select_byte;
|
||||
model->two_bytes = instance->two_bytes;
|
||||
model->extra_repeats = instance->extra_repeats;
|
||||
},
|
||||
true);
|
||||
@@ -401,4 +455,9 @@ SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance) {
|
||||
uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->extra_repeats;
|
||||
}
|
||||
|
||||
bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->two_bytes;
|
||||
}
|
||||
@@ -21,9 +21,11 @@ void subbrute_main_view_set_index(
|
||||
SubBruteMainView* instance,
|
||||
uint8_t idx,
|
||||
bool is_select_byte,
|
||||
const char* key_field);
|
||||
bool two_bytes,
|
||||
uint64_t file_key);
|
||||
SubBruteAttacks subbrute_main_view_get_index(SubBruteMainView* instance);
|
||||
uint8_t subbrute_main_view_get_extra_repeats(SubBruteMainView* instance);
|
||||
bool subbrute_main_view_get_two_bytes(SubBruteMainView* instance);
|
||||
void subbrute_attack_view_enter(void* context);
|
||||
void subbrute_attack_view_exit(void* context);
|
||||
bool subbrute_attack_view_input(InputEvent* event, void* context);
|
||||
|
||||
Reference in New Issue
Block a user