diff --git a/applications/external/flipfrid/LICENSE.md b/applications/external/flipfrid/LICENSE.md deleted file mode 100644 index a856581c9..000000000 --- a/applications/external/flipfrid/LICENSE.md +++ /dev/null @@ -1,8 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * @G4N4P4T1 wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. - * ---------------------------------------------------------------------------- - */ \ No newline at end of file diff --git a/applications/external/flipfrid/application.fam b/applications/external/flipfrid/application.fam deleted file mode 100644 index e71601735..000000000 --- a/applications/external/flipfrid/application.fam +++ /dev/null @@ -1,12 +0,0 @@ -App( - appid="rfid_fuzzer", - name="RFID Fuzzer", - apptype=FlipperAppType.EXTERNAL, - entry_point="flipfrid_start", - requires=["gui", "storage", "dialogs", "input", "notification"], - stack_size=2 * 1024, - order=180, - fap_icon="rfid_10px.png", - fap_category="Tools", - fap_icon_assets="images", -) diff --git a/applications/external/flipfrid/flipfrid.c b/applications/external/flipfrid/flipfrid.c deleted file mode 100644 index 172a98ef3..000000000 --- a/applications/external/flipfrid/flipfrid.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "flipfrid.h" - -#include "scene/flipfrid_scene_entrypoint.h" -#include "scene/flipfrid_scene_load_file.h" -#include "scene/flipfrid_scene_select_field.h" -#include "scene/flipfrid_scene_run_attack.h" -#include "scene/flipfrid_scene_load_custom_uids.h" -#include - -#define RFIDFUZZER_APP_FOLDER "/ext/lrfid/rfidfuzzer" - -static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - FlipFridState* flipfrid_state = ctx; - furi_mutex_acquire(flipfrid_state->mutex, FuriWaitForever); - - // Draw correct Canvas - switch(flipfrid_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - flipfrid_scene_entrypoint_on_draw(canvas, flipfrid_state); - break; - case SceneSelectFile: - flipfrid_scene_load_file_on_draw(canvas, flipfrid_state); - break; - case SceneSelectField: - flipfrid_scene_select_field_on_draw(canvas, flipfrid_state); - break; - case SceneAttack: - flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state); - break; - case SceneLoadCustomUids: - flipfrid_scene_load_custom_uids_on_draw(canvas, flipfrid_state); - break; - default: - break; - } - - furi_mutex_release(flipfrid_state->mutex); -} - -void flipfrid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - FlipFridEvent event = { - .evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type}; - furi_message_queue_put(event_queue, &event, 25); -} - -static void flipfrid_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - FlipFridEvent event = { - .evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease}; - furi_message_queue_put(event_queue, &event, 25); -} - -FlipFridState* flipfrid_alloc() { - FlipFridState* flipfrid = malloc(sizeof(FlipFridState)); - flipfrid->notification_msg = furi_string_alloc(); - flipfrid->attack_name = furi_string_alloc(); - flipfrid->proto_name = furi_string_alloc(); - flipfrid->data_str = furi_string_alloc(); - - flipfrid->main_menu_items[0] = furi_string_alloc_set("Default Values"); - flipfrid->main_menu_items[1] = furi_string_alloc_set("BF Customer ID"); - flipfrid->main_menu_items[2] = furi_string_alloc_set("Load File"); - flipfrid->main_menu_items[3] = furi_string_alloc_set("Load UIDs from file"); - - flipfrid->main_menu_proto_items[0] = furi_string_alloc_set("EM4100"); - flipfrid->main_menu_proto_items[1] = furi_string_alloc_set("HIDProx"); - flipfrid->main_menu_proto_items[2] = furi_string_alloc_set("PAC/Stanley"); - flipfrid->main_menu_proto_items[3] = furi_string_alloc_set("H10301"); - - flipfrid->previous_scene = NoneScene; - flipfrid->current_scene = SceneEntryPoint; - flipfrid->is_running = true; - flipfrid->is_attacking = false; - flipfrid->key_index = 0; - flipfrid->menu_index = 0; - flipfrid->menu_proto_index = 0; - - flipfrid->attack = FlipFridAttackDefaultValues; - flipfrid->notify = furi_record_open(RECORD_NOTIFICATION); - - flipfrid->data[0] = 0x00; - flipfrid->data[1] = 0x00; - flipfrid->data[2] = 0x00; - flipfrid->data[3] = 0x00; - flipfrid->data[4] = 0x00; - flipfrid->data[5] = 0x00; - - flipfrid->payload[0] = 0x00; - flipfrid->payload[1] = 0x00; - flipfrid->payload[2] = 0x00; - flipfrid->payload[3] = 0x00; - flipfrid->payload[4] = 0x00; - flipfrid->payload[5] = 0x00; - - //Dialog - flipfrid->dialogs = furi_record_open(RECORD_DIALOGS); - - return flipfrid; -} - -void flipfrid_free(FlipFridState* flipfrid) { - //Dialog - furi_record_close(RECORD_DIALOGS); - notification_message(flipfrid->notify, &sequence_blink_stop); - - // Strings - furi_string_free(flipfrid->notification_msg); - furi_string_free(flipfrid->attack_name); - furi_string_free(flipfrid->proto_name); - furi_string_free(flipfrid->data_str); - - for(uint32_t i = 0; i < 4; i++) { - furi_string_free(flipfrid->main_menu_items[i]); - } - - for(uint32_t i = 0; i < 4; i++) { - furi_string_free(flipfrid->main_menu_proto_items[i]); - } - - // The rest - free(flipfrid); -} - -// ENTRYPOINT -int32_t flipfrid_start(void* p) { - UNUSED(p); - // Input - FURI_LOG_I(TAG, "Initializing input"); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(FlipFridEvent)); - FlipFridState* flipfrid_state = flipfrid_alloc(); - - DOLPHIN_DEED(DolphinDeedPluginStart); - flipfrid_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!flipfrid_state->mutex) { - FURI_LOG_E(TAG, "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - furi_record_close(RECORD_NOTIFICATION); - flipfrid_free(flipfrid_state); - return 255; - } - - Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_simply_mkdir(storage, RFIDFUZZER_APP_FOLDER)) { - FURI_LOG_E(TAG, "Could not create folder %s", RFIDFUZZER_APP_FOLDER); - } - furi_record_close(RECORD_STORAGE); - - // Configure view port - FURI_LOG_I(TAG, "Initializing viewport"); - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, flipfrid_draw_callback, flipfrid_state); - view_port_input_callback_set(view_port, flipfrid_input_callback, event_queue); - - // Configure timer - FURI_LOG_I(TAG, "Initializing timer"); - FuriTimer* timer = - furi_timer_alloc(flipfrid_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second - - // Register view port in GUI - FURI_LOG_I(TAG, "Initializing gui"); - Gui* gui = (Gui*)furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - // Init values - FlipFridEvent event; - while(flipfrid_state->is_running) { - // Get next event - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25); - if(event_status == FuriStatusOk) { - if(event.evt_type == EventTypeKey) { - //Handle event key - switch(flipfrid_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - flipfrid_scene_entrypoint_on_event(event, flipfrid_state); - break; - case SceneSelectFile: - flipfrid_scene_load_file_on_event(event, flipfrid_state); - break; - case SceneSelectField: - flipfrid_scene_select_field_on_event(event, flipfrid_state); - break; - case SceneAttack: - flipfrid_scene_run_attack_on_event(event, flipfrid_state); - break; - case SceneLoadCustomUids: - flipfrid_scene_load_custom_uids_on_event(event, flipfrid_state); - break; - default: - break; - } - - } else if(event.evt_type == EventTypeTick) { - //Handle event tick - if(flipfrid_state->current_scene != flipfrid_state->previous_scene) { - // Trigger Exit Scene - switch(flipfrid_state->previous_scene) { - case SceneEntryPoint: - flipfrid_scene_entrypoint_on_exit(flipfrid_state); - break; - case SceneSelectFile: - flipfrid_scene_load_file_on_exit(flipfrid_state); - break; - case SceneSelectField: - flipfrid_scene_select_field_on_exit(flipfrid_state); - break; - case SceneAttack: - flipfrid_scene_run_attack_on_exit(flipfrid_state); - break; - case SceneLoadCustomUids: - flipfrid_scene_load_custom_uids_on_exit(flipfrid_state); - break; - case NoneScene: - break; - default: - break; - } - - // Trigger Entry Scene - switch(flipfrid_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - flipfrid_scene_entrypoint_on_enter(flipfrid_state); - break; - case SceneSelectFile: - flipfrid_scene_load_file_on_enter(flipfrid_state); - break; - case SceneSelectField: - flipfrid_scene_select_field_on_enter(flipfrid_state); - break; - case SceneAttack: - flipfrid_scene_run_attack_on_enter(flipfrid_state); - break; - case SceneLoadCustomUids: - flipfrid_scene_load_custom_uids_on_enter(flipfrid_state); - break; - default: - break; - } - flipfrid_state->previous_scene = flipfrid_state->current_scene; - } - - // Trigger Tick Scene - switch(flipfrid_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - flipfrid_scene_entrypoint_on_tick(flipfrid_state); - break; - case SceneSelectFile: - flipfrid_scene_load_file_on_tick(flipfrid_state); - break; - case SceneSelectField: - flipfrid_scene_select_field_on_tick(flipfrid_state); - break; - case SceneAttack: - flipfrid_scene_run_attack_on_tick(flipfrid_state); - break; - case SceneLoadCustomUids: - flipfrid_scene_load_custom_uids_on_tick(flipfrid_state); - break; - default: - break; - } - view_port_update(view_port); - } - } - } - - // Cleanup - furi_timer_stop(timer); - furi_timer_free(timer); - - FURI_LOG_I(TAG, "Cleaning up"); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_mutex_free(flipfrid_state->mutex); - flipfrid_free(flipfrid_state); - - return 0; -} diff --git a/applications/external/flipfrid/flipfrid.h b/applications/external/flipfrid/flipfrid.h deleted file mode 100644 index b95f9f75f..000000000 --- a/applications/external/flipfrid/flipfrid.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#define TAG "FlipFrid" - -typedef enum { - FlipFridAttackDefaultValues, - FlipFridAttackBfCustomerId, - FlipFridAttackLoadFile, - FlipFridAttackLoadFileCustomUids, -} FlipFridAttacks; - -typedef enum { - EM4100, - HIDProx, - PAC, - H10301, -} FlipFridProtos; - -typedef enum { - NoneScene, - SceneEntryPoint, - SceneSelectFile, - SceneSelectField, - SceneAttack, - SceneLoadCustomUids, -} FlipFridScene; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType evt_type; - InputKey key; - InputType input_type; -} FlipFridEvent; - -// STRUCTS -typedef struct { - FuriMutex* mutex; - bool is_running; - bool is_attacking; - FlipFridScene current_scene; - FlipFridScene previous_scene; - NotificationApp* notify; - u_int8_t menu_index; - u_int8_t menu_proto_index; - - FuriString* data_str; - uint8_t data[6]; - uint8_t payload[6]; - uint8_t attack_step; - FlipFridAttacks attack; - FlipFridProtos proto; - FuriString* attack_name; - FuriString* proto_name; - FuriString* main_menu_items[4]; - FuriString* main_menu_proto_items[4]; - - DialogsApp* dialogs; - FuriString* notification_msg; - uint8_t key_index; - LFRFIDWorker* worker; - ProtocolDict* dict; - ProtocolId protocol; - bool workr_rund; - bool attack_stop_called; - - uint8_t time_between_cards; - - // Used for custom dictionnary - Stream* uids_stream; -} FlipFridState; \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.c b/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.c deleted file mode 100644 index f4b39aa66..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "flipfrid_scene_entrypoint.h" - -void flipfrid_scene_entrypoint_menu_callback( - FlipFridState* context, - uint32_t index, - uint32_t proto_index) { - switch(index) { - case FlipFridAttackDefaultValues: - context->attack = FlipFridAttackDefaultValues; - context->current_scene = SceneAttack; - furi_string_set(context->attack_name, "Default Values"); - break; - case FlipFridAttackBfCustomerId: - context->attack = FlipFridAttackBfCustomerId; - context->current_scene = SceneAttack; - furi_string_set(context->attack_name, "Bad Customer ID"); - break; - case FlipFridAttackLoadFile: - context->attack = FlipFridAttackLoadFile; - context->current_scene = SceneSelectFile; - furi_string_set(context->attack_name, "Load File"); - break; - case FlipFridAttackLoadFileCustomUids: - context->attack = FlipFridAttackLoadFileCustomUids; - context->current_scene = SceneLoadCustomUids; - furi_string_set(context->attack_name, "Load Custom UIDs"); - break; - default: - break; - } - - switch(proto_index) { - case EM4100: - context->proto = EM4100; - furi_string_set(context->proto_name, "EM4100"); - break; - case HIDProx: - context->proto = HIDProx; - furi_string_set(context->proto_name, "HIDProx"); - break; - case PAC: - context->proto = PAC; - furi_string_set(context->proto_name, "PAC/Stanley"); - break; - case H10301: - context->proto = H10301; - furi_string_set(context->proto_name, "H10301"); - break; - default: - break; - } -} - -void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) { - // Clear the previous payload - context->payload[0] = 0x00; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - context->payload[3] = 0x00; - context->payload[4] = 0x00; - context->payload[5] = 0x00; - - context->menu_index = 0; - /*for(uint32_t i = 0; i < 4; i++) { - menu_items[i] = furi_string_alloc(); - }*/ - - context->menu_proto_index = 0; - /*for(uint32_t i = 0; i < 4; i++) { - menu_proto_items[i] = furi_string_alloc(); - }*/ -} - -void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_entrypoint_on_tick(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - if(context->menu_index < FlipFridAttackLoadFileCustomUids) { - context->menu_index++; - } - break; - case InputKeyUp: - if(context->menu_index > FlipFridAttackDefaultValues) { - context->menu_index--; - } - break; - case InputKeyLeft: - if(context->menu_proto_index > EM4100) { - context->menu_proto_index--; - } else if(context->menu_proto_index == EM4100) { - context->menu_proto_index = H10301; - } - break; - case InputKeyRight: - if(context->menu_proto_index < H10301) { - context->menu_proto_index++; - } else if(context->menu_proto_index == H10301) { - context->menu_proto_index = EM4100; - } - break; - case InputKeyOk: - flipfrid_scene_entrypoint_menu_callback( - context, context->menu_index, context->menu_proto_index); - break; - case InputKeyBack: - context->is_running = false; - break; - default: - break; - } - } - } -} - -void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - if(context->main_menu_items != NULL) { - if(context->main_menu_items[context->menu_index] != NULL) { - if(context->menu_index > FlipFridAttackDefaultValues) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - 24, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index - 1])); - } - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, - 64, - 36, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index])); - - if(context->menu_index < FlipFridAttackLoadFileCustomUids) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - 48, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index + 1])); - } - - if(context->menu_proto_index > EM4100) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - -12, - AlignCenter, - AlignTop, - furi_string_get_cstr( - context->main_menu_proto_items[context->menu_proto_index - 1])); - } - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 27, 4, AlignCenter, AlignTop, "<"); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, - 64, - 4, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_proto_items[context->menu_proto_index])); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 101, 4, AlignCenter, AlignTop, ">"); - - if(context->menu_proto_index < H10301) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - -12, - AlignCenter, - AlignTop, - furi_string_get_cstr( - context->main_menu_proto_items[context->menu_proto_index + 1])); - } - } - } -} \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.h b/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.h deleted file mode 100644 index 29ca5bdfa..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_entrypoint.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../flipfrid.h" - -void flipfrid_scene_entrypoint_on_enter(FlipFridState* context); -void flipfrid_scene_entrypoint_on_exit(FlipFridState* context); -void flipfrid_scene_entrypoint_on_tick(FlipFridState* context); -void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* context); -void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context); \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.c b/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.c deleted file mode 100644 index 32157556b..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "flipfrid_scene_load_custom_uids.h" -#include "flipfrid_scene_run_attack.h" -#include "flipfrid_scene_entrypoint.h" - -#define LFRFID_UIDS_EXTENSION ".txt" -#define RFIDFUZZER_APP_PATH_FOLDER "/ext/rfidfuzzer" - -bool flipfrid_load_uids(FlipFridState* context, const char* file_path) { - bool result = false; - Storage* storage = furi_record_open(RECORD_STORAGE); - context->uids_stream = buffered_file_stream_alloc(storage); - result = - buffered_file_stream_open(context->uids_stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING); - // Close if loading fails - if(!result) { - buffered_file_stream_close(context->uids_stream); - return false; - } - return result; -} - -bool flipfrid_load_custom_uids_from_file(FlipFridState* context) { - // Input events and views are managed by file_select - FuriString* uid_path; - uid_path = furi_string_alloc(); - furi_string_set(uid_path, RFIDFUZZER_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, LFRFID_UIDS_EXTENSION, &I_125_10px); - browser_options.base_path = RFIDFUZZER_APP_PATH_FOLDER; - browser_options.hide_ext = false; - - bool res = dialog_file_browser_show(context->dialogs, uid_path, uid_path, &browser_options); - - if(res) { - res = flipfrid_load_uids(context, furi_string_get_cstr(uid_path)); - } - - furi_string_free(uid_path); - - return res; -} - -void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context) { - if(flipfrid_load_custom_uids_from_file(context)) { - // Force context loading - flipfrid_scene_run_attack_on_enter(context); - context->current_scene = SceneAttack; - } else { - flipfrid_scene_entrypoint_on_enter(context); - context->current_scene = SceneEntryPoint; - } -} - -void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - case InputKeyUp: - case InputKeyLeft: - case InputKeyRight: - case InputKeyOk: - case InputKeyBack: - context->current_scene = SceneEntryPoint; - break; - default: - break; - } - } - } -} - -void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context) { - UNUSED(context); - UNUSED(canvas); -} diff --git a/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.h b/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.h deleted file mode 100644 index a8ed982b6..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_load_custom_uids.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../flipfrid.h" - -void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context); -void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context); -void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context); -void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context); -void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context); -bool flipfrid_load_custom_uids_from_file(FlipFridState* context); \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_load_file.c b/applications/external/flipfrid/scene/flipfrid_scene_load_file.c deleted file mode 100644 index 5f3f1a31b..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_load_file.c +++ /dev/null @@ -1,193 +0,0 @@ -#include "flipfrid_scene_load_file.h" -#include "flipfrid_scene_entrypoint.h" - -#define LFRFID_APP_EXTENSION ".rfid" -#define LFRFID_APP_PATH_FOLDER "/ext/lfrfid" - -bool flipfrid_load(FlipFridState* context, const char* file_path) { - bool result = false; - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - if(!flipper_format_file_open_existing(fff_data_file, file_path)) { - FURI_LOG_E(TAG, "Error open file %s", file_path); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Error open file"); - break; - } - - // FileType - if(!flipper_format_read_string(fff_data_file, "Filetype", temp_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Filetype"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Filetypes"); - break; - } else { - FURI_LOG_I(TAG, "Filetype: %s", furi_string_get_cstr(temp_str)); - } - - // Key type - if(!flipper_format_read_string(fff_data_file, "Key type", temp_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Key type"); - break; - } else { - FURI_LOG_I(TAG, "Key type: %s", furi_string_get_cstr(temp_str)); - - if(context->proto == EM4100) { - if(strcmp(furi_string_get_cstr(temp_str), "EM4100") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else if(context->proto == PAC) { - if(strcmp(furi_string_get_cstr(temp_str), "PAC/Stanley") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else if(context->proto == H10301) { - if(strcmp(furi_string_get_cstr(temp_str), "H10301") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else { - if(strcmp(furi_string_get_cstr(temp_str), "HIDProx") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } - } - - // Data - if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Data"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Key"); - break; - } else { - FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str)); - - if(context->proto == EM4100) { - if(furi_string_size(context->data_str) != 14) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } else if(context->proto == PAC) { - if(furi_string_size(context->data_str) != 11) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } else if(context->proto == H10301) { - if(furi_string_size(context->data_str) != 8) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } else { - if(furi_string_size(context->data_str) != 17) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } - - // String to uint8_t - for(uint8_t i = 0; i < 6; i++) { - char temp_str2[3]; - temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3]; - temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1]; - temp_str2[2] = '\0'; - context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); - } - } - - result = true; - } while(0); - furi_string_free(temp_str); - flipper_format_free(fff_data_file); - if(result) { - FURI_LOG_I(TAG, "Loaded successfully"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Source loaded."); - } - return result; -} - -void flipfrid_scene_load_file_on_enter(FlipFridState* context) { - if(flipfrid_load_protocol_from_file(context)) { - context->current_scene = SceneSelectField; - } else { - flipfrid_scene_entrypoint_on_enter(context); - context->current_scene = SceneEntryPoint; - } -} - -void flipfrid_scene_load_file_on_exit(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_load_file_on_tick(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_load_file_on_event(FlipFridEvent event, FlipFridState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - case InputKeyUp: - case InputKeyLeft: - case InputKeyRight: - case InputKeyOk: - case InputKeyBack: - context->current_scene = SceneEntryPoint; - break; - default: - break; - } - } - } -} - -void flipfrid_scene_load_file_on_draw(Canvas* canvas, FlipFridState* context) { - UNUSED(context); - UNUSED(canvas); -} - -bool flipfrid_load_protocol_from_file(FlipFridState* context) { - FuriString* user_file_path; - user_file_path = furi_string_alloc(); - furi_string_set(user_file_path, LFRFID_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px); - browser_options.base_path = LFRFID_APP_PATH_FOLDER; - - // Input events and views are managed by file_select - bool res = dialog_file_browser_show( - context->dialogs, user_file_path, user_file_path, &browser_options); - - if(res) { - res = flipfrid_load(context, furi_string_get_cstr(user_file_path)); - } - - furi_string_free(user_file_path); - - return res; -} \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_load_file.h b/applications/external/flipfrid/scene/flipfrid_scene_load_file.h deleted file mode 100644 index ca82daab4..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_load_file.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../flipfrid.h" - -void flipfrid_scene_load_file_on_enter(FlipFridState* context); -void flipfrid_scene_load_file_on_exit(FlipFridState* context); -void flipfrid_scene_load_file_on_tick(FlipFridState* context); -void flipfrid_scene_load_file_on_event(FlipFridEvent event, FlipFridState* context); -void flipfrid_scene_load_file_on_draw(Canvas* canvas, FlipFridState* context); -bool flipfrid_load_protocol_from_file(FlipFridState* context); \ No newline at end of file diff --git a/applications/external/flipfrid/scene/flipfrid_scene_run_attack.c b/applications/external/flipfrid/scene/flipfrid_scene_run_attack.c deleted file mode 100644 index 225752559..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_run_attack.c +++ /dev/null @@ -1,668 +0,0 @@ -#include "flipfrid_scene_run_attack.h" -#include - -uint8_t counter = 0; - -uint8_t id_list[17][5] = { - {0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF - {0x11, 0x11, 0x11, 0x11, 0x11}, // Only 11 - {0x22, 0x22, 0x22, 0x22, 0x22}, // Only 22 - {0x33, 0x33, 0x33, 0x33, 0x33}, // Only 33 - {0x44, 0x44, 0x44, 0x44, 0x44}, // Only 44 - {0x55, 0x55, 0x55, 0x55, 0x55}, // Only 55 - {0x66, 0x66, 0x66, 0x66, 0x66}, // Only 66 - {0x77, 0x77, 0x77, 0x77, 0x77}, // Only 77 - {0x88, 0x88, 0x88, 0x88, 0x88}, // Only 88 - {0x99, 0x99, 0x99, 0x99, 0x99}, // Only 99 - {0x12, 0x34, 0x56, 0x78, 0x9A}, // Incremental UID - {0x9A, 0x78, 0x56, 0x34, 0x12}, // Decremental UID - {0x04, 0xd0, 0x9b, 0x0d, 0x6a}, // From arha - {0x34, 0x00, 0x29, 0x3d, 0x9e}, // From arha - {0x04, 0xdf, 0x00, 0x00, 0x01}, // From arha - {0xCA, 0xCA, 0xCA, 0xCA, 0xCA}, // From arha -}; - -uint8_t id_list_hid[14][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF - {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, // Only 11 - {0x22, 0x22, 0x22, 0x22, 0x22, 0x22}, // Only 22 - {0x33, 0x33, 0x33, 0x33, 0x33, 0x33}, // Only 33 - {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, // Only 44 - {0x55, 0x55, 0x55, 0x55, 0x55, 0x55}, // Only 55 - {0x66, 0x66, 0x66, 0x66, 0x66, 0x66}, // Only 66 - {0x77, 0x77, 0x77, 0x77, 0x77, 0x77}, // Only 77 - {0x88, 0x88, 0x88, 0x88, 0x88, 0x88}, // Only 88 - {0x99, 0x99, 0x99, 0x99, 0x99, 0x99}, // Only 99 - {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}, // Incremental UID - {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}, // Decremental UID - {0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA}, // From arha -}; - -uint8_t id_list_pac[17][4] = { - {0x00, 0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF, 0xFF}, // Only FF - {0x11, 0x11, 0x11, 0x11}, // Only 11 - {0x22, 0x22, 0x22, 0x22}, // Only 22 - {0x33, 0x33, 0x33, 0x33}, // Only 33 - {0x44, 0x44, 0x44, 0x44}, // Only 44 - {0x55, 0x55, 0x55, 0x55}, // Only 55 - {0x66, 0x66, 0x66, 0x66}, // Only 66 - {0x77, 0x77, 0x77, 0x77}, // Only 77 - {0x88, 0x88, 0x88, 0x88}, // Only 88 - {0x99, 0x99, 0x99, 0x99}, // Only 99 - {0x12, 0x34, 0x56, 0x78}, // Incremental UID - {0x9A, 0x78, 0x56, 0x34}, // Decremental UID - {0x04, 0xd0, 0x9b, 0x0d}, // From arha - {0x34, 0x00, 0x29, 0x3d}, // From arha - {0x04, 0xdf, 0x00, 0x00}, // From arha - {0xCA, 0xCA, 0xCA, 0xCA}, // From arha -}; - -uint8_t id_list_h[14][3] = { - {0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF}, // Only FF - {0x11, 0x11, 0x11}, // Only 11 - {0x22, 0x22, 0x22}, // Only 22 - {0x33, 0x33, 0x33}, // Only 33 - {0x44, 0x44, 0x44}, // Only 44 - {0x55, 0x55, 0x55}, // Only 55 - {0x66, 0x66, 0x66}, // Only 66 - {0x77, 0x77, 0x77}, // Only 77 - {0x88, 0x88, 0x88}, // Only 88 - {0x99, 0x99, 0x99}, // Only 99 - {0x12, 0x34, 0x56}, // Incremental UID - {0x56, 0x34, 0x12}, // Decremental UID - {0xCA, 0xCA, 0xCA}, // From arha -}; - -void flipfrid_scene_run_attack_on_enter(FlipFridState* context) { - context->time_between_cards = 10; - context->attack_step = 0; - context->attack_stop_called = false; - context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); - context->worker = lfrfid_worker_alloc(context->dict); - if(context->proto == HIDProx) { - context->protocol = protocol_dict_get_protocol_by_name(context->dict, "HIDProx"); - } else if(context->proto == PAC) { - context->protocol = protocol_dict_get_protocol_by_name(context->dict, "PAC/Stanley"); - } else if(context->proto == H10301) { - context->protocol = protocol_dict_get_protocol_by_name(context->dict, "H10301"); - } else { - context->protocol = protocol_dict_get_protocol_by_name(context->dict, "EM4100"); - } -} - -void flipfrid_scene_run_attack_on_exit(FlipFridState* context) { - if(context->workr_rund) { - lfrfid_worker_stop(context->worker); - lfrfid_worker_stop_thread(context->worker); - context->workr_rund = false; - } - lfrfid_worker_free(context->worker); - protocol_dict_free(context->dict); - notification_message(context->notify, &sequence_blink_stop); -} - -void flipfrid_scene_run_attack_on_tick(FlipFridState* context) { - if(context->is_attacking) { - if(1 == counter) { - protocol_dict_set_data(context->dict, context->protocol, context->payload, 6); - lfrfid_worker_free(context->worker); - context->worker = lfrfid_worker_alloc(context->dict); - lfrfid_worker_start_thread(context->worker); - lfrfid_worker_emulate_start(context->worker, context->protocol); - context->workr_rund = true; - } else if(0 == counter) { - if(context->workr_rund) { - lfrfid_worker_stop(context->worker); - lfrfid_worker_stop_thread(context->worker); - context->workr_rund = false; - furi_delay_ms(200); - } - switch(context->attack) { - case FlipFridAttackDefaultValues: - if(context->proto == EM4100) { - context->payload[0] = id_list[context->attack_step][0]; - context->payload[1] = id_list[context->attack_step][1]; - context->payload[2] = id_list[context->attack_step][2]; - context->payload[3] = id_list[context->attack_step][3]; - context->payload[4] = id_list[context->attack_step][4]; - - if(context->attack_step == 16) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else if(context->proto == PAC) { - context->payload[0] = id_list_pac[context->attack_step][0]; - context->payload[1] = id_list_pac[context->attack_step][1]; - context->payload[2] = id_list_pac[context->attack_step][2]; - context->payload[3] = id_list_pac[context->attack_step][3]; - - if(context->attack_step == 16) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else if(context->proto == H10301) { - context->payload[0] = id_list_h[context->attack_step][0]; - context->payload[1] = id_list_h[context->attack_step][1]; - context->payload[2] = id_list_h[context->attack_step][2]; - - if(context->attack_step == 13) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else { - context->payload[0] = id_list_hid[context->attack_step][0]; - context->payload[1] = id_list_hid[context->attack_step][1]; - context->payload[2] = id_list_hid[context->attack_step][2]; - context->payload[3] = id_list_hid[context->attack_step][3]; - context->payload[4] = id_list_hid[context->attack_step][4]; - context->payload[5] = id_list_hid[context->attack_step][5]; - - if(context->attack_step == 13) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - - } else { - context->attack_step++; - } - break; - } - - case FlipFridAttackBfCustomerId: - if(context->proto == EM4100) { - context->payload[0] = context->attack_step; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - context->payload[3] = 0x00; - context->payload[4] = 0x00; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else if(context->proto == PAC) { - context->payload[0] = context->attack_step; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - context->payload[3] = 0x00; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else if(context->proto == H10301) { - context->payload[0] = context->attack_step; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else { - context->payload[0] = context->attack_step; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - context->payload[3] = 0x00; - context->payload[4] = 0x00; - context->payload[5] = 0x00; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } - - case FlipFridAttackLoadFile: - if(context->proto == EM4100) { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - context->payload[3] = context->data[3]; - context->payload[4] = context->data[4]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } else if(context->proto == PAC) { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - context->payload[3] = context->data[3]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } else if(context->proto == H10301) { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } else { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - context->payload[3] = context->data[3]; - context->payload[4] = context->data[4]; - context->payload[5] = context->data[5]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } - - case FlipFridAttackLoadFileCustomUids: - if(context->proto == EM4100) { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - } - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 11) break; - break; - } - if(end_of_list) break; - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(furi_string_size(context->data_str) != 11) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - } - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 5; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } else if(context->proto == PAC) { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - } - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 9) break; - break; - } - if(end_of_list) break; - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(furi_string_size(context->data_str) != 9) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - } - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 4; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } else if(context->proto == H10301) { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - }; - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 7) break; - break; - } - if(end_of_list) break; - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(furi_string_size(context->data_str) != 7) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - }; - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 3; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } else { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - }; - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 13) break; - break; - } - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(end_of_list) break; - if(furi_string_size(context->data_str) != 13) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - }; - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 6; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - default: - break; - } - } - } - if(counter > context->time_between_cards) { - counter = 0; - } else { - counter++; - } - } -} - -void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - break; - case InputKeyUp: - break; - case InputKeyLeft: - if(!context->is_attacking) { - if(context->time_between_cards > 5) { - context->time_between_cards--; - } - } - break; - case InputKeyRight: - if(!context->is_attacking) { - if(context->time_between_cards < 70) { - context->time_between_cards++; - } - } - break; - case InputKeyOk: - counter = 0; - if(!context->is_attacking) { - notification_message(context->notify, &sequence_blink_start_blue); - context->is_attacking = true; - } else { - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } - break; - case InputKeyBack: - context->is_attacking = false; - counter = 0; - - notification_message(context->notify, &sequence_blink_stop); - if(context->attack_stop_called) { - context->attack_stop_called = false; - context->attack_step = 0; - if(context->attack == FlipFridAttackLoadFileCustomUids) { - furi_string_reset(context->data_str); - stream_rewind(context->uids_stream); - buffered_file_stream_close(context->uids_stream); - } - - furi_string_reset(context->notification_msg); - context->current_scene = SceneEntryPoint; - } - - context->attack_stop_called = true; - break; - default: - break; - } - } - if(event.input_type == InputTypeLong) { - switch(event.key) { - case InputKeyLeft: - if(!context->is_attacking) { - if(context->time_between_cards > 0) { - if((context->time_between_cards - 10) > 5) { - context->time_between_cards -= 10; - } - } - } - break; - case InputKeyRight: - if(!context->is_attacking) { - if(context->time_between_cards < 70) { - context->time_between_cards += 10; - } - } - break; - default: - break; - } - } - } -} - -void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - // Frame - //canvas_draw_frame(canvas, 0, 0, 128, 64); - - // Title - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(context->attack_name)); - - char uid[18]; - char speed[16]; - if(context->proto == HIDProx) { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X:%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2], - context->payload[3], - context->payload[4], - context->payload[5]); - } else if(context->proto == PAC) { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2], - context->payload[3]); - } else if(context->proto == H10301) { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2]); - } else { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2], - context->payload[3], - context->payload[4]); - } - - canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, uid); - - canvas_set_font(canvas, FontSecondary); - - canvas_draw_str_aligned( - canvas, 64, 26, AlignCenter, AlignTop, furi_string_get_cstr(context->proto_name)); - - snprintf(speed, sizeof(speed), "Time delay: %d", context->time_between_cards); - - //canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Speed:"); - canvas_draw_str_aligned(canvas, 64, 14, AlignCenter, AlignTop, speed); - //char start_stop_msg[20]; - if(context->is_attacking) { - elements_button_center(canvas, "Stop"); - //snprintf(start_stop_msg, sizeof(start_stop_msg), " Press OK to stop "); - } else { - elements_button_center(canvas, "Start"); - elements_button_left(canvas, "TD -"); - elements_button_right(canvas, "+ TD"); - } - //canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, start_stop_msg); -} diff --git a/applications/external/flipfrid/scene/flipfrid_scene_run_attack.h b/applications/external/flipfrid/scene/flipfrid_scene_run_attack.h deleted file mode 100644 index ae56d35e7..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_run_attack.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../flipfrid.h" - -void flipfrid_scene_run_attack_on_enter(FlipFridState* context); -void flipfrid_scene_run_attack_on_exit(FlipFridState* context); -void flipfrid_scene_run_attack_on_tick(FlipFridState* context); -void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* context); -void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context); diff --git a/applications/external/flipfrid/scene/flipfrid_scene_select_field.c b/applications/external/flipfrid/scene/flipfrid_scene_select_field.c deleted file mode 100644 index ccb49e910..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_select_field.c +++ /dev/null @@ -1,160 +0,0 @@ -#include "flipfrid_scene_select_field.h" - -void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) { - char key_cstr[18]; - uint8_t key_len = 18; - uint8_t str_index = (index * 3); - int data_len = sizeof(context->data) / sizeof(context->data[0]); - int key_index = 0; - - if(context->proto == EM4100) { - key_len = 16; - } - if(context->proto == PAC) { - key_len = 13; - } - if(context->proto == H10301) { - key_len = 10; - } - - for(uint8_t i = 0; i < data_len; i++) { - if(context->data[i] < 9) { - key_index += - snprintf(&key_cstr[key_index], key_len - key_index, "0%X ", context->data[i]); - } else { - key_index += - snprintf(&key_cstr[key_index], key_len - key_index, "%X ", context->data[i]); - } - } - - char display_menu[17] = { - 'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'}; - - if(index > 1) { - display_menu[0] = key_cstr[str_index - 6]; - display_menu[1] = key_cstr[str_index - 5]; - } 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] = ' '; - } - - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, display_menu); -} - -void flipfrid_scene_select_field_on_enter(FlipFridState* context) { - furi_string_reset(context->notification_msg); -} - -void flipfrid_scene_select_field_on_exit(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_select_field_on_tick(FlipFridState* context) { - UNUSED(context); -} - -void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - const char* key_cstr = furi_string_get_cstr(context->data_str); - int data_len = sizeof(context->data) / sizeof(context->data[0]); - - // don't look, it's ugly but I'm a python dev so... - uint8_t nb_bytes = 0; - for(uint8_t i = 0; i < strlen(key_cstr); i++) { - if(' ' == key_cstr[i]) { - nb_bytes++; - } - } - - switch(event.key) { - case InputKeyDown: - for(uint8_t i = 0; i < data_len; i++) { - if(context->key_index == i) { - context->data[i] = (context->data[i] - 1); - } - } - break; - case InputKeyUp: - for(uint8_t i = 0; i < data_len; i++) { - if(context->key_index == i) { - context->data[i] = (context->data[i] + 1); - } - } - break; - case InputKeyLeft: - if(context->key_index > 0) { - context->key_index = context->key_index - 1; - } - break; - case InputKeyRight: - if(context->key_index < nb_bytes) { - context->key_index = context->key_index + 1; - } - break; - case InputKeyOk: - furi_string_reset(context->notification_msg); - context->current_scene = SceneAttack; - break; - case InputKeyBack: - context->key_index = 0; - furi_string_reset(context->notification_msg); - context->current_scene = SceneSelectFile; - break; - default: - break; - } - FURI_LOG_D(TAG, "Position: %d/%d", context->key_index, nb_bytes); - } - } -} - -void flipfrid_scene_select_field_on_draw(Canvas* canvas, FlipFridState* context) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - // Frame - //canvas_draw_frame(canvas, 0, 0, 128, 64); - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 12, 5, AlignLeft, AlignTop, "Left and right: select byte"); - canvas_draw_str_aligned(canvas, 12, 15, AlignLeft, AlignTop, "Up and down: adjust byte"); - - char msg_index[18]; - canvas_set_font(canvas, FontPrimary); - snprintf(msg_index, sizeof(msg_index), "Field index : %d", context->key_index); - canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignTop, msg_index); - - flipfrid_center_displayed_key(context, context->key_index); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, 64, 45, AlignCenter, AlignTop, furi_string_get_cstr(context->notification_msg)); -} diff --git a/applications/external/flipfrid/scene/flipfrid_scene_select_field.h b/applications/external/flipfrid/scene/flipfrid_scene_select_field.h deleted file mode 100644 index 5533e321c..000000000 --- a/applications/external/flipfrid/scene/flipfrid_scene_select_field.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../flipfrid.h" - -void flipfrid_scene_select_field_on_enter(FlipFridState* context); -void flipfrid_scene_select_field_on_exit(FlipFridState* context); -void flipfrid_scene_select_field_on_tick(FlipFridState* context); -void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* context); -void flipfrid_scene_select_field_on_draw(Canvas* canvas, FlipFridState* context); -void center_displayed_key(FlipFridState* context, uint8_t index); \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/LICENSE.md b/applications/external/ibtn_fuzzer/LICENSE.md deleted file mode 100644 index ba3b84456..000000000 --- a/applications/external/ibtn_fuzzer/LICENSE.md +++ /dev/null @@ -1,8 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * @xMasterX and @G4N4P4T1(made original version) wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. - * ---------------------------------------------------------------------------- - */ \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/application.fam b/applications/external/ibtn_fuzzer/application.fam deleted file mode 100644 index 87c02a913..000000000 --- a/applications/external/ibtn_fuzzer/application.fam +++ /dev/null @@ -1,12 +0,0 @@ -App( - appid="ibtn_fuzzer", - name="iButton Fuzzer", - apptype=FlipperAppType.EXTERNAL, - entry_point="ibtnfuzzer_start", - requires=["gui", "storage", "dialogs", "input", "notification"], - stack_size=1 * 1024, - order=15, - fap_icon="ibutt_10px.png", - fap_category="Tools", - fap_icon_assets="images", -) diff --git a/applications/external/ibtn_fuzzer/ibtnfuzzer.c b/applications/external/ibtn_fuzzer/ibtnfuzzer.c deleted file mode 100644 index 9e6239b69..000000000 --- a/applications/external/ibtn_fuzzer/ibtnfuzzer.c +++ /dev/null @@ -1,282 +0,0 @@ -#include "ibtnfuzzer.h" - -#include "scene/ibtnfuzzer_scene_entrypoint.h" -#include "scene/ibtnfuzzer_scene_load_file.h" -#include "scene/ibtnfuzzer_scene_select_field.h" -#include "scene/ibtnfuzzer_scene_run_attack.h" -#include "scene/ibtnfuzzer_scene_load_custom_uids.h" -#include - -#define IBTNFUZZER_APP_FOLDER "/ext/ibtnfuzzer" - -static void ibtnfuzzer_draw_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - iBtnFuzzerState* ibtnfuzzer_state = ctx; - furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever); - - // Draw correct Canvas - switch(ibtnfuzzer_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - ibtnfuzzer_scene_entrypoint_on_draw(canvas, ibtnfuzzer_state); - break; - case SceneSelectFile: - ibtnfuzzer_scene_load_file_on_draw(canvas, ibtnfuzzer_state); - break; - case SceneSelectField: - ibtnfuzzer_scene_select_field_on_draw(canvas, ibtnfuzzer_state); - break; - case SceneAttack: - ibtnfuzzer_scene_run_attack_on_draw(canvas, ibtnfuzzer_state); - break; - case SceneLoadCustomUids: - ibtnfuzzer_scene_load_custom_uids_on_draw(canvas, ibtnfuzzer_state); - break; - } - - furi_mutex_release(ibtnfuzzer_state->mutex); -} - -void ibtnfuzzer_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - iBtnFuzzerEvent event = { - .evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type}; - furi_message_queue_put(event_queue, &event, 25); -} - -static void ibtnfuzzer_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); - iBtnFuzzerEvent event = { - .evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease}; - furi_message_queue_put(event_queue, &event, 25); -} - -iBtnFuzzerState* ibtnfuzzer_alloc() { - iBtnFuzzerState* ibtnfuzzer = malloc(sizeof(iBtnFuzzerState)); - ibtnfuzzer->notification_msg = furi_string_alloc(); - ibtnfuzzer->attack_name = furi_string_alloc(); - ibtnfuzzer->proto_name = furi_string_alloc(); - ibtnfuzzer->data_str = furi_string_alloc(); - - ibtnfuzzer->main_menu_items[0] = furi_string_alloc_set("Default Values"); - ibtnfuzzer->main_menu_items[1] = furi_string_alloc_set("Load File"); - ibtnfuzzer->main_menu_items[2] = furi_string_alloc_set("Load UIDs from file"); - - ibtnfuzzer->main_menu_proto_items[0] = furi_string_alloc_set("DS1990"); - ibtnfuzzer->main_menu_proto_items[1] = furi_string_alloc_set("Metakom"); - ibtnfuzzer->main_menu_proto_items[2] = furi_string_alloc_set("Cyfral"); - - ibtnfuzzer->previous_scene = NoneScene; - ibtnfuzzer->current_scene = SceneEntryPoint; - ibtnfuzzer->is_running = true; - ibtnfuzzer->is_attacking = false; - ibtnfuzzer->key_index = 0; - ibtnfuzzer->menu_index = 0; - ibtnfuzzer->menu_proto_index = 0; - - ibtnfuzzer->attack = iBtnFuzzerAttackDefaultValues; - ibtnfuzzer->notify = furi_record_open(RECORD_NOTIFICATION); - - ibtnfuzzer->data[0] = 0x00; - ibtnfuzzer->data[1] = 0x00; - ibtnfuzzer->data[2] = 0x00; - ibtnfuzzer->data[3] = 0x00; - ibtnfuzzer->data[4] = 0x00; - ibtnfuzzer->data[5] = 0x00; - ibtnfuzzer->data[6] = 0x00; - ibtnfuzzer->data[7] = 0x00; - - ibtnfuzzer->payload[0] = 0x00; - ibtnfuzzer->payload[1] = 0x00; - ibtnfuzzer->payload[2] = 0x00; - ibtnfuzzer->payload[3] = 0x00; - ibtnfuzzer->payload[4] = 0x00; - ibtnfuzzer->payload[5] = 0x00; - ibtnfuzzer->payload[6] = 0x00; - ibtnfuzzer->payload[7] = 0x00; - - //Dialog - ibtnfuzzer->dialogs = furi_record_open(RECORD_DIALOGS); - - return ibtnfuzzer; -} - -void ibtnfuzzer_free(iBtnFuzzerState* ibtnfuzzer) { - //Dialog - furi_record_close(RECORD_DIALOGS); - notification_message(ibtnfuzzer->notify, &sequence_blink_stop); - - // Strings - furi_string_free(ibtnfuzzer->notification_msg); - furi_string_free(ibtnfuzzer->attack_name); - furi_string_free(ibtnfuzzer->proto_name); - furi_string_free(ibtnfuzzer->data_str); - - for(uint32_t i = 0; i < 3; i++) { - furi_string_free(ibtnfuzzer->main_menu_items[i]); - } - - for(uint32_t i = 0; i < 3; i++) { - furi_string_free(ibtnfuzzer->main_menu_proto_items[i]); - } - - // The rest - free(ibtnfuzzer); -} - -// ENTRYPOINT -int32_t ibtnfuzzer_start(void* p) { - UNUSED(p); - // Input - FURI_LOG_I(TAG, "Initializing input"); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(iBtnFuzzerEvent)); - iBtnFuzzerState* ibtnfuzzer_state = ibtnfuzzer_alloc(); - - DOLPHIN_DEED(DolphinDeedPluginStart); - ibtnfuzzer_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!ibtnfuzzer_state->mutex) { - FURI_LOG_E(TAG, "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - furi_record_close(RECORD_NOTIFICATION); - ibtnfuzzer_free(ibtnfuzzer_state); - return 255; - } - - Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_simply_mkdir(storage, IBTNFUZZER_APP_FOLDER)) { - FURI_LOG_E(TAG, "Could not create folder %s", IBTNFUZZER_APP_FOLDER); - } - furi_record_close(RECORD_STORAGE); - - // Configure view port - FURI_LOG_I(TAG, "Initializing viewport"); - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, ibtnfuzzer_draw_callback, ibtnfuzzer_state); - view_port_input_callback_set(view_port, ibtnfuzzer_input_callback, event_queue); - - // Configure timer - FURI_LOG_I(TAG, "Initializing timer"); - FuriTimer* timer = - furi_timer_alloc(ibtnfuzzer_timer_callback, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second - - // Register view port in GUI - FURI_LOG_I(TAG, "Initializing gui"); - Gui* gui = (Gui*)furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - // Init values - iBtnFuzzerEvent event; - while(ibtnfuzzer_state->is_running) { - // Get next event - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25); - //furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever); - if(event_status == FuriStatusOk) { - if(event.evt_type == EventTypeKey) { - //Handle event key - switch(ibtnfuzzer_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - ibtnfuzzer_scene_entrypoint_on_event(event, ibtnfuzzer_state); - break; - case SceneSelectFile: - ibtnfuzzer_scene_load_file_on_event(event, ibtnfuzzer_state); - break; - case SceneSelectField: - ibtnfuzzer_scene_select_field_on_event(event, ibtnfuzzer_state); - break; - case SceneAttack: - ibtnfuzzer_scene_run_attack_on_event(event, ibtnfuzzer_state); - break; - case SceneLoadCustomUids: - ibtnfuzzer_scene_load_custom_uids_on_event(event, ibtnfuzzer_state); - break; - } - - } else if(event.evt_type == EventTypeTick) { - //Handle event tick - if(ibtnfuzzer_state->current_scene != ibtnfuzzer_state->previous_scene) { - // Trigger Exit Scene - switch(ibtnfuzzer_state->previous_scene) { - case SceneEntryPoint: - ibtnfuzzer_scene_entrypoint_on_exit(ibtnfuzzer_state); - break; - case SceneSelectFile: - ibtnfuzzer_scene_load_file_on_exit(ibtnfuzzer_state); - break; - case SceneSelectField: - ibtnfuzzer_scene_select_field_on_exit(ibtnfuzzer_state); - break; - case SceneAttack: - ibtnfuzzer_scene_run_attack_on_exit(ibtnfuzzer_state); - break; - case SceneLoadCustomUids: - ibtnfuzzer_scene_load_custom_uids_on_exit(ibtnfuzzer_state); - break; - case NoneScene: - break; - } - - // Trigger Entry Scene - switch(ibtnfuzzer_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - ibtnfuzzer_scene_entrypoint_on_enter(ibtnfuzzer_state); - break; - case SceneSelectFile: - ibtnfuzzer_scene_load_file_on_enter(ibtnfuzzer_state); - break; - case SceneSelectField: - ibtnfuzzer_scene_select_field_on_enter(ibtnfuzzer_state); - break; - case SceneAttack: - ibtnfuzzer_scene_run_attack_on_enter(ibtnfuzzer_state); - break; - case SceneLoadCustomUids: - ibtnfuzzer_scene_load_custom_uids_on_enter(ibtnfuzzer_state); - break; - } - ibtnfuzzer_state->previous_scene = ibtnfuzzer_state->current_scene; - } - - // Trigger Tick Scene - switch(ibtnfuzzer_state->current_scene) { - case NoneScene: - case SceneEntryPoint: - ibtnfuzzer_scene_entrypoint_on_tick(ibtnfuzzer_state); - break; - case SceneSelectFile: - ibtnfuzzer_scene_load_file_on_tick(ibtnfuzzer_state); - break; - case SceneSelectField: - ibtnfuzzer_scene_select_field_on_tick(ibtnfuzzer_state); - break; - case SceneAttack: - ibtnfuzzer_scene_run_attack_on_tick(ibtnfuzzer_state); - break; - case SceneLoadCustomUids: - ibtnfuzzer_scene_load_custom_uids_on_tick(ibtnfuzzer_state); - break; - } - view_port_update(view_port); - } - } - //furi_mutex_release(ibtnfuzzer_state->mutex); - } - - // Cleanup - furi_timer_stop(timer); - furi_timer_free(timer); - - FURI_LOG_I(TAG, "Cleaning up"); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_mutex_free(ibtnfuzzer_state->mutex); - ibtnfuzzer_free(ibtnfuzzer_state); - - return 0; -} diff --git a/applications/external/ibtn_fuzzer/ibtnfuzzer.h b/applications/external/ibtn_fuzzer/ibtnfuzzer.h deleted file mode 100644 index 7a9e2b537..000000000 --- a/applications/external/ibtn_fuzzer/ibtnfuzzer.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#define TAG "iBtnFuzzer" - -typedef enum { - iBtnFuzzerAttackDefaultValues, - iBtnFuzzerAttackLoadFile, - iBtnFuzzerAttackLoadFileCustomUids, -} iBtnFuzzerAttacks; - -typedef enum { - DS1990, - Metakom, - Cyfral, -} iBtnFuzzerProtos; - -typedef enum { - NoneScene, - SceneEntryPoint, - SceneSelectFile, - SceneSelectField, - SceneAttack, - SceneLoadCustomUids, -} iBtnFuzzerScene; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType evt_type; - InputKey key; - InputType input_type; -} iBtnFuzzerEvent; - -// STRUCTS -typedef struct { - FuriMutex* mutex; - bool is_running; - bool is_attacking; - iBtnFuzzerScene current_scene; - iBtnFuzzerScene previous_scene; - NotificationApp* notify; - u_int8_t menu_index; - u_int8_t menu_proto_index; - - FuriString* data_str; - uint8_t data[8]; - uint8_t payload[8]; - uint8_t attack_step; - iBtnFuzzerAttacks attack; - iBtnFuzzerProtos proto; - FuriString* attack_name; - FuriString* proto_name; - FuriString* main_menu_items[3]; - FuriString* main_menu_proto_items[3]; - - DialogsApp* dialogs; - FuriString* notification_msg; - uint8_t key_index; - iButtonWorker* worker; - iButtonKey* key; - iButtonProtocolId keytype; - iButtonProtocols* protocols; - bool workr_rund; - bool enter_rerun; - bool attack_stop_called; - - uint8_t time_between_cards; - - // Used for custom dictionnary - Stream* uids_stream; -} iBtnFuzzerState; \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/images/ibutt_10px.png b/applications/external/ibtn_fuzzer/images/ibutt_10px.png deleted file mode 100644 index 2fdaf123a..000000000 Binary files a/applications/external/ibtn_fuzzer/images/ibutt_10px.png and /dev/null differ diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.c b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.c deleted file mode 100644 index 1dd239c3b..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "ibtnfuzzer_scene_entrypoint.h" - -void ibtnfuzzer_scene_entrypoint_menu_callback( - iBtnFuzzerState* context, - uint32_t index, - uint32_t proto_index) { - switch(index) { - case iBtnFuzzerAttackDefaultValues: - context->attack = iBtnFuzzerAttackDefaultValues; - context->current_scene = SceneAttack; - furi_string_set(context->attack_name, "Default Values"); - break; - case iBtnFuzzerAttackLoadFile: - context->attack = iBtnFuzzerAttackLoadFile; - context->current_scene = SceneSelectFile; - furi_string_set(context->attack_name, "Load File"); - break; - case iBtnFuzzerAttackLoadFileCustomUids: - context->attack = iBtnFuzzerAttackLoadFileCustomUids; - context->current_scene = SceneLoadCustomUids; - furi_string_set(context->attack_name, "Load Custom UIDs"); - break; - default: - break; - } - - switch(proto_index) { - case DS1990: - context->proto = DS1990; - furi_string_set(context->proto_name, "DS1990"); - break; - case Metakom: - context->proto = Metakom; - furi_string_set(context->proto_name, "Metakom"); - break; - case Cyfral: - context->proto = Cyfral; - furi_string_set(context->proto_name, "Cyfral"); - break; - default: - break; - } -} - -void ibtnfuzzer_scene_entrypoint_on_enter(iBtnFuzzerState* context) { - // Clear the previous payload - context->payload[0] = 0x00; - context->payload[1] = 0x00; - context->payload[2] = 0x00; - context->payload[3] = 0x00; - context->payload[4] = 0x00; - context->payload[5] = 0x00; - context->payload[6] = 0x00; - context->payload[7] = 0x00; - - context->menu_index = 0; - /*for(uint32_t i = 0; i < 4; i++) { - menu_items[i] = furi_string_alloc(); - }*/ - - context->menu_proto_index = 0; - /*for(uint32_t i = 0; i < 4; i++) { - menu_proto_items[i] = furi_string_alloc(); - }*/ -} - -void ibtnfuzzer_scene_entrypoint_on_exit(iBtnFuzzerState* context) { - context->enter_rerun = false; -} - -void ibtnfuzzer_scene_entrypoint_on_tick(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_entrypoint_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - if(context->menu_index < iBtnFuzzerAttackLoadFileCustomUids) { - context->menu_index++; - } - break; - case InputKeyUp: - if(context->menu_index > iBtnFuzzerAttackDefaultValues) { - context->menu_index--; - } - break; - case InputKeyLeft: - if(context->menu_proto_index > DS1990) { - context->menu_proto_index--; - } else if(context->menu_proto_index == DS1990) { - context->menu_proto_index = Cyfral; - } - break; - case InputKeyRight: - if(context->menu_proto_index < Cyfral) { - context->menu_proto_index++; - } else if(context->menu_proto_index == Cyfral) { - context->menu_proto_index = DS1990; - } - break; - case InputKeyOk: - ibtnfuzzer_scene_entrypoint_menu_callback( - context, context->menu_index, context->menu_proto_index); - break; - case InputKeyBack: - context->is_running = false; - break; - default: - break; - } - } - } -} - -void ibtnfuzzer_scene_entrypoint_on_draw(Canvas* canvas, iBtnFuzzerState* context) { - if(!context->enter_rerun) { - ibtnfuzzer_scene_entrypoint_on_enter(context); - context->enter_rerun = true; - } - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - if(context->main_menu_items != NULL) { - if(context->main_menu_items[context->menu_index] != NULL) { - if(context->menu_index > iBtnFuzzerAttackDefaultValues) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - 24, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index - 1])); - } - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, - 64, - 36, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index])); - - if(context->menu_index < iBtnFuzzerAttackLoadFileCustomUids) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - 48, - AlignCenter, - AlignTop, - furi_string_get_cstr(context->main_menu_items[context->menu_index + 1])); - } - - if(context->menu_proto_index > DS1990) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - -12, - AlignCenter, - AlignTop, - furi_string_get_cstr( - context->main_menu_proto_items[context->menu_proto_index - 1])); - } - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 27, 4, AlignCenter, AlignTop, "<"); - - canvas_set_font(canvas, FontPrimary); - if(context->main_menu_proto_items[context->menu_proto_index] != NULL) { - canvas_draw_str_aligned( - canvas, - 64, - 4, - AlignCenter, - AlignTop, - furi_string_get_cstr( - context->main_menu_proto_items[context->menu_proto_index])); - } - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 101, 4, AlignCenter, AlignTop, ">"); - - if(context->menu_proto_index < Cyfral) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, - 64, - -12, - AlignCenter, - AlignTop, - furi_string_get_cstr( - context->main_menu_proto_items[context->menu_proto_index + 1])); - } - } - } -} \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.h b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.h deleted file mode 100644 index b77aec369..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_entrypoint.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../ibtnfuzzer.h" - -void ibtnfuzzer_scene_entrypoint_on_enter(iBtnFuzzerState* context); -void ibtnfuzzer_scene_entrypoint_on_exit(iBtnFuzzerState* context); -void ibtnfuzzer_scene_entrypoint_on_tick(iBtnFuzzerState* context); -void ibtnfuzzer_scene_entrypoint_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context); -void ibtnfuzzer_scene_entrypoint_on_draw(Canvas* canvas, iBtnFuzzerState* context); \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.c b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.c deleted file mode 100644 index 07199ab46..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "ibtnfuzzer_scene_load_custom_uids.h" -#include "ibtnfuzzer_scene_run_attack.h" -#include "ibtnfuzzer_scene_entrypoint.h" - -#define IBTNFUZZER_UIDS_EXTENSION ".txt" -#define IBTNFUZZER_APP_PATH_FOLDER "/ext/ibtnfuzzer" - -bool ibtnfuzzer_load_uids(iBtnFuzzerState* context, const char* file_path) { - bool result = false; - Storage* storage = furi_record_open(RECORD_STORAGE); - context->uids_stream = buffered_file_stream_alloc(storage); - result = - buffered_file_stream_open(context->uids_stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING); - // Close if loading fails - if(!result) { - buffered_file_stream_close(context->uids_stream); - return false; - } - return result; -} - -bool ibtnfuzzer_load_custom_uids_from_file(iBtnFuzzerState* context) { - // Input events and views are managed by file_select - FuriString* uid_path; - uid_path = furi_string_alloc(); - furi_string_set(uid_path, IBTNFUZZER_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, IBTNFUZZER_UIDS_EXTENSION, &I_ibutt_10px); - browser_options.base_path = IBTNFUZZER_APP_PATH_FOLDER; - browser_options.hide_ext = false; - - bool res = dialog_file_browser_show(context->dialogs, uid_path, uid_path, &browser_options); - - if(res) { - res = ibtnfuzzer_load_uids(context, furi_string_get_cstr(uid_path)); - } - - furi_string_free(uid_path); - - return res; -} - -void ibtnfuzzer_scene_load_custom_uids_on_enter(iBtnFuzzerState* context) { - if(ibtnfuzzer_load_custom_uids_from_file(context)) { - // Force context loading - ibtnfuzzer_scene_run_attack_on_enter(context); - context->current_scene = SceneAttack; - } else { - ibtnfuzzer_scene_entrypoint_on_enter(context); - context->current_scene = SceneEntryPoint; - } -} - -void ibtnfuzzer_scene_load_custom_uids_on_exit(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_load_custom_uids_on_tick(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_load_custom_uids_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - case InputKeyUp: - case InputKeyLeft: - case InputKeyRight: - case InputKeyOk: - case InputKeyBack: - context->current_scene = SceneEntryPoint; - break; - default: - break; - } - } - } -} - -void ibtnfuzzer_scene_load_custom_uids_on_draw(Canvas* canvas, iBtnFuzzerState* context) { - UNUSED(context); - UNUSED(canvas); -} diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.h b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.h deleted file mode 100644 index bb51c7079..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_custom_uids.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../ibtnfuzzer.h" - -void ibtnfuzzer_scene_load_custom_uids_on_enter(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_custom_uids_on_exit(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_custom_uids_on_tick(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_custom_uids_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_custom_uids_on_draw(Canvas* canvas, iBtnFuzzerState* context); -bool ibtnfuzzer_load_custom_uids_from_file(iBtnFuzzerState* context); \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.c b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.c deleted file mode 100644 index 92f79a424..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.c +++ /dev/null @@ -1,293 +0,0 @@ -#include "ibtnfuzzer_scene_load_file.h" -#include "ibtnfuzzer_scene_entrypoint.h" - -#define IBUTTON_FUZZER_APP_EXTENSION ".ibtn" -#define IBUTTON_FUZZER_APP_PATH_FOLDER "/ext/ibutton" - -bool ibtnfuzzer_load(iBtnFuzzerState* context, const char* file_path) { - bool result = false; - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - FuriString* temp_str; - temp_str = furi_string_alloc(); - bool key_v2 = false; - do { - if(!flipper_format_file_open_existing(fff_data_file, file_path)) { - FURI_LOG_E(TAG, "Error open file %s", file_path); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Error open file"); - break; - } - - // FileType - if(!flipper_format_read_string(fff_data_file, "Filetype", temp_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Filetype"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Filetypes"); - break; - } else { - FURI_LOG_I(TAG, "Filetype: %s", furi_string_get_cstr(temp_str)); - } - - // Key type - if(!flipper_format_read_string(fff_data_file, "Key type", temp_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Key type, checking for typ2.."); - - if(!flipper_format_rewind(fff_data_file)) { - FURI_LOG_E(TAG, "Failed to rewind file"); - break; - } - if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { - furi_string_reset(context->notification_msg); - furi_string_set( - context->notification_msg, "Missing or incorrect Protocol or Key type"); - break; - } - FURI_LOG_I(TAG, "Key type V2: %s", furi_string_get_cstr(temp_str)); - key_v2 = true; - - if(context->proto == DS1990) { - if(strcmp(furi_string_get_cstr(temp_str), "DS1990") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else if(context->proto == Cyfral) { - if(strcmp(furi_string_get_cstr(temp_str), "Cyfral") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else { - if(strcmp(furi_string_get_cstr(temp_str), "Metakom") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } - } else { - FURI_LOG_I(TAG, "Key type: %s", furi_string_get_cstr(temp_str)); - - if(context->proto == DS1990) { - if(strcmp(furi_string_get_cstr(temp_str), "Dallas") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else if(context->proto == Cyfral) { - if(strcmp(furi_string_get_cstr(temp_str), "Cyfral") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } else { - if(strcmp(furi_string_get_cstr(temp_str), "Metakom") != 0) { - FURI_LOG_E(TAG, "Unsupported Key type"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Unsupported Key type"); - break; - } - } - } - if(!key_v2) { - // Data - if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Data"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Key"); - break; - } else { - FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str)); - - if(context->proto == DS1990) { - if(furi_string_size(context->data_str) != 23) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } else if(context->proto == Cyfral) { - if(furi_string_size(context->data_str) != 5) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } else { - if(furi_string_size(context->data_str) != 11) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - } - - // String to uint8_t - for(uint8_t i = 0; i < 8; i++) { - char temp_str2[3]; - temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3]; - temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1]; - temp_str2[2] = '\0'; - context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); - } - } - } else { - // Data - if(context->proto == DS1990) { - if(!flipper_format_read_string(fff_data_file, "Rom Data", context->data_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Rom Data"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Rom Data"); - break; - } else { - FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str)); - - if(furi_string_size(context->data_str) != 23) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - - // String to uint8_t - for(uint8_t i = 0; i < 8; i++) { - char temp_str2[3]; - temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3]; - temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1]; - temp_str2[2] = '\0'; - context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); - } - } - } else if(context->proto == Cyfral) { - if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Data"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Data"); - break; - } else { - FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str)); - - if(furi_string_size(context->data_str) != 5) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - - // String to uint8_t - for(uint8_t i = 0; i < 8; i++) { - char temp_str2[3]; - temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3]; - temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1]; - temp_str2[2] = '\0'; - context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); - } - } - } else { - if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Data"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Missing or incorrect Data"); - break; - } else { - FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str)); - - if(furi_string_size(context->data_str) != 11) { - FURI_LOG_E(TAG, "Incorrect Key length"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Incorrect Key length"); - break; - } - - // String to uint8_t - for(uint8_t i = 0; i < 8; i++) { - char temp_str2[3]; - temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3]; - temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1]; - temp_str2[2] = '\0'; - context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); - } - } - } - } - - result = true; - } while(0); - furi_string_free(temp_str); - flipper_format_free(fff_data_file); - if(result) { - FURI_LOG_I(TAG, "Loaded successfully"); - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, "Source loaded."); - } - return result; -} - -void ibtnfuzzer_scene_load_file_on_enter(iBtnFuzzerState* context) { - if(ibtnfuzzer_load_protocol_from_file(context)) { - context->current_scene = SceneSelectField; - } else { - ibtnfuzzer_scene_entrypoint_on_enter(context); - context->current_scene = SceneEntryPoint; - } -} - -void ibtnfuzzer_scene_load_file_on_exit(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_load_file_on_tick(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_load_file_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - case InputKeyUp: - case InputKeyLeft: - case InputKeyRight: - case InputKeyOk: - case InputKeyBack: - context->current_scene = SceneEntryPoint; - break; - default: - break; - } - } - } -} - -void ibtnfuzzer_scene_load_file_on_draw(Canvas* canvas, iBtnFuzzerState* context) { - UNUSED(context); - UNUSED(canvas); -} - -bool ibtnfuzzer_load_protocol_from_file(iBtnFuzzerState* context) { - FuriString* user_file_path; - user_file_path = furi_string_alloc(); - furi_string_set(user_file_path, IBUTTON_FUZZER_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, IBUTTON_FUZZER_APP_EXTENSION, &I_ibutt_10px); - browser_options.base_path = IBUTTON_FUZZER_APP_PATH_FOLDER; - - // Input events and views are managed by file_select - bool res = dialog_file_browser_show( - context->dialogs, user_file_path, user_file_path, &browser_options); - - if(res) { - res = ibtnfuzzer_load(context, furi_string_get_cstr(user_file_path)); - } - - furi_string_free(user_file_path); - - return res; -} \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.h b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.h deleted file mode 100644 index 34031d08c..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_load_file.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../ibtnfuzzer.h" - -void ibtnfuzzer_scene_load_file_on_enter(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_file_on_exit(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_file_on_tick(iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_file_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context); -void ibtnfuzzer_scene_load_file_on_draw(Canvas* canvas, iBtnFuzzerState* context); -bool ibtnfuzzer_load_protocol_from_file(iBtnFuzzerState* context); \ No newline at end of file diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.c b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.c deleted file mode 100644 index 53f2f694f..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.c +++ /dev/null @@ -1,501 +0,0 @@ -#include "ibtnfuzzer_scene_run_attack.h" -#include - -uint8_t counter = 0; - -uint8_t id_list_ds1990[18][8] = { - {0x01, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0xE1}, //– код универсального ключа, для Vizit - {0x01, 0xBE, 0x40, 0x11, 0x5A, 0x56, 0x00, 0xBB}, //- проверен работает - {0x01, 0xBE, 0x40, 0x11, 0x00, 0x00, 0x00, 0x77}, //- проверен работает - {0x01, 0xBE, 0x40, 0x11, 0x0A, 0x00, 0x00, 0x1D}, //- проверен работает Визит иногда КЕЙМАНЫ - {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F}, //- проверен(метаком, цифрал, ВИЗИТ). - {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x9B}, //- проверен Визит, Метакомы, КОНДОР - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14}, //???-Открываает 98% Метаком и некоторые Цифрал - {0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x19, 0xFF}, //???-Отлично работает на старых домофонах - {0x01, 0x6F, 0x2E, 0x88, 0x8A, 0x00, 0x00, 0x4D}, //???-Открывать что-то должен - {0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x7E, 0x88}, //???-Cyfral, Metakom - {0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x00, 0x6F}, //???-домофоны Визит (Vizit) - до 99% - {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D}, //???-домофоны Cyfral CCD-20 - до 70% - {0x01, 0x00, 0xBE, 0x11, 0xAA, 0x00, 0x00, 0xFB}, //???-домофоны Кейман (KEYMAN) - {0x01, 0x76, 0xB8, 0x2E, 0x0F, 0x00, 0x00, 0x5C}, //???-домофоны Форвард - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14}, // Only FF - {0x01, 0x78, 0x00, 0x48, 0xFD, 0xFF, 0xFF, 0xD1}, // StarNew Uni5 - {0x01, 0xA9, 0xE4, 0x3C, 0x09, 0x00, 0x00, 0xE6}, // Eltis Uni -}; - -uint8_t id_list_metakom[17][4] = { - {0x00, 0x00, 0x00, 0x00}, // Null bytes - {0xFF, 0xFF, 0xFF, 0xFF}, // Only FF - {0x11, 0x11, 0x11, 0x11}, // Only 11 - {0x22, 0x22, 0x22, 0x22}, // Only 22 - {0x33, 0x33, 0x33, 0x33}, // Only 33 - {0x44, 0x44, 0x44, 0x44}, // Only 44 - {0x55, 0x55, 0x55, 0x55}, // Only 55 - {0x66, 0x66, 0x66, 0x66}, // Only 66 - {0x77, 0x77, 0x77, 0x77}, // Only 77 - {0x88, 0x88, 0x88, 0x88}, // Only 88 - {0x99, 0x99, 0x99, 0x99}, // Only 99 - {0x12, 0x34, 0x56, 0x78}, // Incremental UID - {0x9A, 0x78, 0x56, 0x34}, // Decremental UID - {0x04, 0xd0, 0x9b, 0x0d}, // ?? - {0x34, 0x00, 0x29, 0x3d}, // ?? - {0x04, 0xdf, 0x00, 0x00}, // ?? - {0xCA, 0xCA, 0xCA, 0xCA}, // ?? -}; - -uint8_t id_list_cyfral[16][2] = { - {0x00, 0x00}, // Null bytes - {0xFF, 0xFF}, // Only FF - {0x11, 0x11}, // Only 11 - {0x22, 0x22}, // Only 22 - {0x33, 0x33}, // Only 33 - {0x44, 0x44}, // Only 44 - {0x55, 0x55}, // Only 55 - {0x66, 0x66}, // Only 66 - {0x77, 0x77}, // Only 77 - {0x88, 0x88}, // Only 88 - {0x99, 0x99}, // Only 99 - {0x12, 0x34}, // Incremental UID - {0x56, 0x34}, // Decremental UID - {0xCA, 0xCA}, // ?? - {0x8E, 0xC9}, // Elevator code - {0x6A, 0x50}, // VERY fresh code from smartkey -}; - -void ibtnfuzzer_scene_run_attack_on_enter(iBtnFuzzerState* context) { - context->time_between_cards = 8; - context->attack_step = 0; - context->attack_stop_called = false; - context->protocols = ibutton_protocols_alloc(); - context->key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(context->protocols)); - context->worker = ibutton_worker_alloc(context->protocols); - if(context->proto == Metakom) { - context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "Metakom"); - } else if(context->proto == Cyfral) { - context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "Cyfral"); - } else { - context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "DS1990"); - } - context->workr_rund = false; -} - -void ibtnfuzzer_scene_run_attack_on_exit(iBtnFuzzerState* context) { - if(context->workr_rund) { - ibutton_worker_stop(context->worker); - ibutton_worker_stop_thread(context->worker); - context->workr_rund = false; - } - ibutton_key_free(context->key); - ibutton_worker_free(context->worker); - ibutton_protocols_free(context->protocols); - notification_message(context->notify, &sequence_blink_stop); -} - -void ibtnfuzzer_scene_run_attack_on_tick(iBtnFuzzerState* context) { - if(context->is_attacking) { - if(1 == counter) { - ibutton_worker_start_thread(context->worker); - ibutton_key_set_protocol_id(context->key, context->keytype); - iButtonEditableData data; - ibutton_protocols_get_editable_data(context->protocols, context->key, &data); - data.size = sizeof(context->payload); - for(size_t i = 0; i < data.size; i++) { - data.ptr[i] = context->payload[i]; - } - - ibutton_worker_emulate_start(context->worker, context->key); - context->workr_rund = true; - } else if(0 == counter) { - if(context->workr_rund) { - ibutton_worker_stop(context->worker); - ibutton_worker_stop_thread(context->worker); - context->workr_rund = false; - furi_delay_ms(500); - } - switch(context->attack) { - case iBtnFuzzerAttackDefaultValues: - if(context->proto == DS1990) { - context->payload[0] = id_list_ds1990[context->attack_step][0]; - context->payload[1] = id_list_ds1990[context->attack_step][1]; - context->payload[2] = id_list_ds1990[context->attack_step][2]; - context->payload[3] = id_list_ds1990[context->attack_step][3]; - context->payload[4] = id_list_ds1990[context->attack_step][4]; - context->payload[5] = id_list_ds1990[context->attack_step][5]; - context->payload[6] = id_list_ds1990[context->attack_step][6]; - context->payload[7] = id_list_ds1990[context->attack_step][7]; - - if(context->attack_step == 17) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else if(context->proto == Metakom) { - context->payload[0] = id_list_metakom[context->attack_step][0]; - context->payload[1] = id_list_metakom[context->attack_step][1]; - context->payload[2] = id_list_metakom[context->attack_step][2]; - context->payload[3] = id_list_metakom[context->attack_step][3]; - - if(context->attack_step == 16) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } else { - context->payload[0] = id_list_cyfral[context->attack_step][0]; - context->payload[1] = id_list_cyfral[context->attack_step][1]; - - if(context->attack_step == 15) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } else { - context->attack_step++; - } - break; - } - case iBtnFuzzerAttackLoadFile: - if(context->proto == DS1990) { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - context->payload[3] = context->data[3]; - context->payload[4] = context->data[4]; - context->payload[5] = context->data[5]; - context->payload[6] = context->data[6]; - context->payload[7] = context->data[7]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } else if(context->proto == Cyfral) { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } else { - context->payload[0] = context->data[0]; - context->payload[1] = context->data[1]; - context->payload[2] = context->data[2]; - context->payload[3] = context->data[3]; - - context->payload[context->key_index] = context->attack_step; - - if(context->attack_step == 255) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - break; - } else { - context->attack_step++; - } - break; - } - - case iBtnFuzzerAttackLoadFileCustomUids: - if(context->proto == DS1990) { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - } - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 17) break; - break; - } - if(end_of_list) break; - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(furi_string_size(context->data_str) != 17) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - } - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 8; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } else if(context->proto == Cyfral) { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - } - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 5) break; - break; - } - if(end_of_list) break; - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(furi_string_size(context->data_str) != 5) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - } - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 2; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } else { - bool end_of_list = false; - while(true) { - furi_string_reset(context->data_str); - if(!stream_read_line(context->uids_stream, context->data_str)) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - stream_rewind(context->uids_stream); - end_of_list = true; - break; - } - if(furi_string_get_char(context->data_str, 0) == '#') continue; - if(furi_string_size(context->data_str) != 9) break; - break; - } - FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str)); - if(end_of_list) break; - if(furi_string_size(context->data_str) != 9) { - context->attack_step = 0; - counter = 0; - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_error); - break; - } - - // string is valid, parse it in context->payload - for(uint8_t i = 0; i < 4; i++) { - char temp_str[3]; - temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2]; - temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1]; - temp_str[2] = '\0'; - context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); - } - break; - } - } - } - - if(counter > context->time_between_cards) { - counter = 0; - } else { - counter++; - } - } -} - -void ibtnfuzzer_scene_run_attack_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - switch(event.key) { - case InputKeyDown: - break; - case InputKeyUp: - break; - case InputKeyLeft: - if(!context->is_attacking) { - if(context->time_between_cards > 4) { - context->time_between_cards--; - } - } - break; - case InputKeyRight: - if(!context->is_attacking) { - if(context->time_between_cards < 80) { - context->time_between_cards++; - } - } - break; - case InputKeyOk: - counter = 0; - if(!context->is_attacking) { - notification_message(context->notify, &sequence_blink_start_blue); - context->is_attacking = true; - } else { - context->is_attacking = false; - notification_message(context->notify, &sequence_blink_stop); - notification_message(context->notify, &sequence_single_vibro); - } - break; - case InputKeyBack: - context->is_attacking = false; - counter = 0; - - notification_message(context->notify, &sequence_blink_stop); - if(context->attack_stop_called) { - context->attack_stop_called = false; - context->attack_step = 0; - if(context->attack == iBtnFuzzerAttackLoadFileCustomUids) { - furi_string_reset(context->data_str); - stream_rewind(context->uids_stream); - buffered_file_stream_close(context->uids_stream); - } - - furi_string_reset(context->notification_msg); - context->current_scene = SceneEntryPoint; - } - - context->attack_stop_called = true; - break; - default: - break; - } - } - if(event.input_type == InputTypeLong) { - switch(event.key) { - case InputKeyLeft: - if(!context->is_attacking) { - if(context->time_between_cards > 4) { - if((context->time_between_cards - 10) > 4) { - context->time_between_cards -= 10; - } - } - } - break; - case InputKeyRight: - if(!context->is_attacking) { - if(context->time_between_cards < 80) { - context->time_between_cards += 10; - } - } - break; - default: - break; - } - } - } -} - -void ibtnfuzzer_scene_run_attack_on_draw(Canvas* canvas, iBtnFuzzerState* context) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - // Frame - //canvas_draw_frame(canvas, 0, 0, 128, 64); - - // Title - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned( - canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(context->attack_name)); - - char uid[25]; - char speed[16]; - if(context->proto == Metakom) { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2], - context->payload[3]); - } else if(context->proto == Cyfral) { - snprintf(uid, sizeof(uid), "%02X:%02X", context->payload[0], context->payload[1]); - } else { - snprintf( - uid, - sizeof(uid), - "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", - context->payload[0], - context->payload[1], - context->payload[2], - context->payload[3], - context->payload[4], - context->payload[5], - context->payload[6], - context->payload[7]); - } - - canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, uid); - - canvas_set_font(canvas, FontSecondary); - - canvas_draw_str_aligned( - canvas, 64, 26, AlignCenter, AlignTop, furi_string_get_cstr(context->proto_name)); - - snprintf(speed, sizeof(speed), "Time delay: %d", context->time_between_cards); - - //canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Speed:"); - canvas_draw_str_aligned(canvas, 64, 14, AlignCenter, AlignTop, speed); - //char start_stop_msg[20]; - if(context->is_attacking) { - elements_button_center(canvas, "Stop"); - //snprintf(start_stop_msg, sizeof(start_stop_msg), " Press OK to stop "); - } else { - elements_button_center(canvas, "Start"); - elements_button_left(canvas, "TD -"); - elements_button_right(canvas, "+ TD"); - } - //canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, start_stop_msg); -} diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.h b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.h deleted file mode 100644 index 9e44478f7..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_run_attack.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../ibtnfuzzer.h" - -void ibtnfuzzer_scene_run_attack_on_enter(iBtnFuzzerState* context); -void ibtnfuzzer_scene_run_attack_on_exit(iBtnFuzzerState* context); -void ibtnfuzzer_scene_run_attack_on_tick(iBtnFuzzerState* context); -void ibtnfuzzer_scene_run_attack_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context); -void ibtnfuzzer_scene_run_attack_on_draw(Canvas* canvas, iBtnFuzzerState* context); diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.c b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.c deleted file mode 100644 index f3217f65e..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.c +++ /dev/null @@ -1,160 +0,0 @@ -#include "ibtnfuzzer_scene_select_field.h" - -void ibtnfuzzer_center_displayed_key(iBtnFuzzerState* context, uint8_t index) { - char key_cstr[25]; - uint8_t key_len = 25; - uint8_t str_index = (index * 3); - int data_len = sizeof(context->data) / sizeof(context->data[0]); - int key_index = 0; - - if(context->proto == DS1990) { - key_len = 25; - } - if(context->proto == Metakom) { - key_len = 13; - } - if(context->proto == Cyfral) { - key_len = 7; - } - - for(uint8_t i = 0; i < data_len; i++) { - if(context->data[i] < 9) { - key_index += - snprintf(&key_cstr[key_index], key_len - key_index, "0%X ", context->data[i]); - } else { - key_index += - snprintf(&key_cstr[key_index], key_len - key_index, "%X ", context->data[i]); - } - } - - char display_menu[17] = { - 'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'}; - - if(index > 1) { - display_menu[0] = key_cstr[str_index - 6]; - display_menu[1] = key_cstr[str_index - 5]; - } 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] = ' '; - } - - furi_string_reset(context->notification_msg); - furi_string_set(context->notification_msg, display_menu); -} - -void ibtnfuzzer_scene_select_field_on_enter(iBtnFuzzerState* context) { - furi_string_reset(context->notification_msg); -} - -void ibtnfuzzer_scene_select_field_on_exit(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_select_field_on_tick(iBtnFuzzerState* context) { - UNUSED(context); -} - -void ibtnfuzzer_scene_select_field_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) { - if(event.evt_type == EventTypeKey) { - if(event.input_type == InputTypeShort) { - const char* key_cstr = furi_string_get_cstr(context->data_str); - int data_len = sizeof(context->data) / sizeof(context->data[0]); - - // don't look, it's ugly but I'm a python dev so... - uint8_t nb_bytes = 0; - for(uint8_t i = 0; i < strlen(key_cstr); i++) { - if(' ' == key_cstr[i]) { - nb_bytes++; - } - } - - switch(event.key) { - case InputKeyDown: - for(uint8_t i = 0; i < data_len; i++) { - if(context->key_index == i) { - context->data[i] = (context->data[i] - 1); - } - } - break; - case InputKeyUp: - for(uint8_t i = 0; i < data_len; i++) { - if(context->key_index == i) { - context->data[i] = (context->data[i] + 1); - } - } - break; - case InputKeyLeft: - if(context->key_index > 0) { - context->key_index = context->key_index - 1; - } - break; - case InputKeyRight: - if(context->key_index < nb_bytes) { - context->key_index = context->key_index + 1; - } - break; - case InputKeyOk: - furi_string_reset(context->notification_msg); - context->current_scene = SceneAttack; - break; - case InputKeyBack: - context->key_index = 0; - furi_string_reset(context->notification_msg); - context->current_scene = SceneSelectFile; - break; - default: - break; - } - FURI_LOG_D(TAG, "Position: %d/%d", context->key_index, nb_bytes); - } - } -} - -void ibtnfuzzer_scene_select_field_on_draw(Canvas* canvas, iBtnFuzzerState* context) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - // Frame - //canvas_draw_frame(canvas, 0, 0, 128, 64); - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 12, 5, AlignLeft, AlignTop, "Left and right: select byte"); - canvas_draw_str_aligned(canvas, 12, 15, AlignLeft, AlignTop, "Up and down: adjust byte"); - - char msg_index[18]; - canvas_set_font(canvas, FontPrimary); - snprintf(msg_index, sizeof(msg_index), "Field index : %d", context->key_index); - canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignTop, msg_index); - - ibtnfuzzer_center_displayed_key(context, context->key_index); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, 64, 45, AlignCenter, AlignTop, furi_string_get_cstr(context->notification_msg)); -} diff --git a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.h b/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.h deleted file mode 100644 index b6c684c3b..000000000 --- a/applications/external/ibtn_fuzzer/scene/ibtnfuzzer_scene_select_field.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "../ibtnfuzzer.h" - -void ibtnfuzzer_scene_select_field_on_enter(iBtnFuzzerState* context); -void ibtnfuzzer_scene_select_field_on_exit(iBtnFuzzerState* context); -void ibtnfuzzer_scene_select_field_on_tick(iBtnFuzzerState* context); -void ibtnfuzzer_scene_select_field_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context); -void ibtnfuzzer_scene_select_field_on_draw(Canvas* canvas, iBtnFuzzerState* context); -void center_displayed_key(iBtnFuzzerState* context, uint8_t index); \ No newline at end of file diff --git a/applications/external/multi_fuzzer/application.fam b/applications/external/multi_fuzzer/application.fam new file mode 100644 index 000000000..a0ce1be0a --- /dev/null +++ b/applications/external/multi_fuzzer/application.fam @@ -0,0 +1,49 @@ +App( + appid="fuzzer_ibtn", + name="iButton Fuzzer", + apptype=FlipperAppType.EXTERNAL, + entry_point="fuzzer_start_ibtn", + requires=[ + "gui", + "storage", + "dialogs", + "input", + "notification", + ], + stack_size=2 * 1024, + fap_icon="icons/ibutt_10px.png", + fap_category="Tools", + fap_private_libs=[ + Lib( + name="worker", + cdefines=["IBUTTON_PROTOCOL"], + ), + ], + fap_icon_assets="icons", + fap_icon_assets_symbol="fuzzer", +) + +App( + appid="fuzzer_rfid", + name="RFID Fuzzer", + apptype=FlipperAppType.EXTERNAL, + entry_point="fuzzer_start_rfid", + requires=[ + "gui", + "storage", + "dialogs", + "input", + "notification", + ], + stack_size=2 * 1024, + fap_icon="icons/rfid_10px.png", + fap_category="Tools", + fap_private_libs=[ + Lib( + name="worker", + cdefines=["RFID_125_PROTOCOL"], + ), + ], + fap_icon_assets="icons", + fap_icon_assets_symbol="fuzzer", +) diff --git a/applications/external/multi_fuzzer/fuzzer.c b/applications/external/multi_fuzzer/fuzzer.c new file mode 100644 index 000000000..c4cf441e4 --- /dev/null +++ b/applications/external/multi_fuzzer/fuzzer.c @@ -0,0 +1,163 @@ +#include "fuzzer_i.h" +#include "helpers/fuzzer_types.h" +#include + +static bool fuzzer_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + PacsFuzzerApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool fuzzer_app_back_event_callback(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void fuzzer_app_tick_event_callback(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +PacsFuzzerApp* fuzzer_app_alloc() { + DOLPHIN_DEED(DolphinDeedPluginStart); + + PacsFuzzerApp* app = malloc(sizeof(PacsFuzzerApp)); + + app->fuzzer_state.menu_index = 0; + app->fuzzer_state.proto_index = 0; + + app->worker = fuzzer_worker_alloc(); + app->payload = fuzzer_payload_alloc(); + + app->file_path = furi_string_alloc(); + + // GUI + app->gui = furi_record_open(RECORD_GUI); + + // Dialog + app->dialogs = furi_record_open(RECORD_DIALOGS); + + // Open Notification record + app->notifications = furi_record_open(RECORD_NOTIFICATION); + + // View Dispatcher + app->view_dispatcher = view_dispatcher_alloc(); + + // Popup + app->popup = popup_alloc(); + view_dispatcher_add_view(app->view_dispatcher, FuzzerViewIDPopup, popup_get_view(app->popup)); + + // Main view + app->main_view = fuzzer_view_main_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, FuzzerViewIDMain, fuzzer_view_main_get_view(app->main_view)); + + // Attack view + app->attack_view = fuzzer_view_attack_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, FuzzerViewIDAttack, fuzzer_view_attack_get_view(app->attack_view)); + + // FieldEditor view + app->field_editor_view = fuzzer_view_field_editor_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + FuzzerViewIDFieldEditor, + fuzzer_view_field_editor_get_view(app->field_editor_view)); + + app->scene_manager = scene_manager_alloc(&fuzzer_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, fuzzer_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, fuzzer_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, fuzzer_app_tick_event_callback, 100); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + scene_manager_next_scene(app->scene_manager, FuzzerSceneMain); + + return app; +} + +void fuzzer_app_free(PacsFuzzerApp* app) { + furi_assert(app); + + // Remote view + view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDMain); + fuzzer_view_main_free(app->main_view); + + // Attack view + view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDAttack); + fuzzer_view_attack_free(app->attack_view); + + // FieldEditor view + view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDFieldEditor); + fuzzer_view_field_editor_free(app->field_editor_view); + + // Popup + view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDPopup); + popup_free(app->popup); + + scene_manager_free(app->scene_manager); + view_dispatcher_free(app->view_dispatcher); + + // Dialog + furi_record_close(RECORD_DIALOGS); + + // Close records + furi_record_close(RECORD_GUI); + + // Notifications + furi_record_close(RECORD_NOTIFICATION); + app->notifications = NULL; + + furi_string_free(app->file_path); + + fuzzer_payload_free(app->payload); + fuzzer_worker_free(app->worker); + + free(app); +} + +int32_t fuzzer_start_ibtn(void* p) { + UNUSED(p); + PacsFuzzerApp* fuzzer_app = fuzzer_app_alloc(); + + FuzzerConsts app_const = { + .custom_dict_folder = "/ext/ibtnfuzzer", + .custom_dict_extension = ".txt", + .key_extension = ".ibtn", + .path_key_folder = "/ext/ibutton", + .key_icon = &I_ibutt_10px, + }; + fuzzer_app->fuzzer_const = &app_const; + + view_dispatcher_run(fuzzer_app->view_dispatcher); + + fuzzer_app_free(fuzzer_app); + return 0; +} + +int32_t fuzzer_start_rfid(void* p) { + UNUSED(p); + PacsFuzzerApp* fuzzer_app = fuzzer_app_alloc(); + + FuzzerConsts app_const = { + .custom_dict_folder = "/ext/rfidfuzzer", + .custom_dict_extension = ".txt", + .key_extension = ".rfid", + .path_key_folder = "/ext/lfrfid", + .key_icon = &I_125_10px, + }; + fuzzer_app->fuzzer_const = &app_const; + + view_dispatcher_run(fuzzer_app->view_dispatcher); + + fuzzer_app_free(fuzzer_app); + return 0; +} diff --git a/applications/external/multi_fuzzer/fuzzer_i.h b/applications/external/multi_fuzzer/fuzzer_i.h new file mode 100644 index 000000000..5b58e59d8 --- /dev/null +++ b/applications/external/multi_fuzzer/fuzzer_i.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "scenes/fuzzer_scene.h" +#include "views/main_menu.h" +#include "views/attack.h" +#include "views/field_editor.h" + +#include "helpers/fuzzer_types.h" +#include "lib/worker/fake_worker.h" + +#include +#include "fuzzer_icons.h" + +#define FUZZ_TIME_DELAY_MAX (80) + +typedef struct { + const char* custom_dict_extension; + const char* custom_dict_folder; + const char* key_extension; + const char* path_key_folder; + const Icon* key_icon; +} FuzzerConsts; + +typedef struct { + Gui* gui; + NotificationApp* notifications; + + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + Popup* popup; + DialogsApp* dialogs; + FuzzerViewMain* main_view; + FuzzerViewAttack* attack_view; + FuzzerViewFieldEditor* field_editor_view; + + FuriString* file_path; + + FuzzerState fuzzer_state; + FuzzerConsts* fuzzer_const; + + FuzzerWorker* worker; + FuzzerPayload* payload; +} PacsFuzzerApp; \ No newline at end of file diff --git a/applications/external/multi_fuzzer/helpers/fuzzer_custom_event.h b/applications/external/multi_fuzzer/helpers/fuzzer_custom_event.h new file mode 100644 index 000000000..321187722 --- /dev/null +++ b/applications/external/multi_fuzzer/helpers/fuzzer_custom_event.h @@ -0,0 +1,17 @@ +#pragma once + +typedef enum { + + // FuzzerCustomEvent + FuzzerCustomEventViewMainBack = 100, + FuzzerCustomEventViewMainOk, + FuzzerCustomEventViewMainPopupErr, + + FuzzerCustomEventViewAttackBack, + FuzzerCustomEventViewAttackOk, + // FuzzerCustomEventViewAttackTick, // now not use + FuzzerCustomEventViewAttackEnd, + + FuzzerCustomEventViewFieldEditorBack, + FuzzerCustomEventViewFieldEditorOk, +} FuzzerCustomEvent; \ No newline at end of file diff --git a/applications/external/multi_fuzzer/helpers/fuzzer_types.h b/applications/external/multi_fuzzer/helpers/fuzzer_types.h new file mode 100644 index 000000000..bb608a5f1 --- /dev/null +++ b/applications/external/multi_fuzzer/helpers/fuzzer_types.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +typedef struct { + uint8_t menu_index; + uint8_t proto_index; +} FuzzerState; + +typedef enum { + FuzzerAttackStateOff = 0, + FuzzerAttackStateIdle, + FuzzerAttackStateRunning, + FuzzerAttackStateEnd, + +} FuzzerAttackState; + +typedef enum { + FuzzerFieldEditorStateEditingOn = 0, + FuzzerFieldEditorStateEditingOff, + +} FuzzerFieldEditorState; + +typedef enum { + FuzzerViewIDPopup, + + FuzzerViewIDMain, + FuzzerViewIDAttack, + FuzzerViewIDFieldEditor, +} FuzzerViewID; \ No newline at end of file diff --git a/applications/external/flipfrid/images/125_10px.png b/applications/external/multi_fuzzer/icons/125_10px.png similarity index 100% rename from applications/external/flipfrid/images/125_10px.png rename to applications/external/multi_fuzzer/icons/125_10px.png diff --git a/applications/external/multi_fuzzer/icons/ButtonLeft_4x7.png b/applications/external/multi_fuzzer/icons/ButtonLeft_4x7.png new file mode 100644 index 000000000..0b4655d43 Binary files /dev/null and b/applications/external/multi_fuzzer/icons/ButtonLeft_4x7.png differ diff --git a/applications/external/multi_fuzzer/icons/ButtonRight_4x7.png b/applications/external/multi_fuzzer/icons/ButtonRight_4x7.png new file mode 100644 index 000000000..8e1c74c1c Binary files /dev/null and b/applications/external/multi_fuzzer/icons/ButtonRight_4x7.png differ diff --git a/applications/external/multi_fuzzer/icons/Ok_btn_9x9.png b/applications/external/multi_fuzzer/icons/Ok_btn_9x9.png new file mode 100644 index 000000000..9a1539da2 Binary files /dev/null and b/applications/external/multi_fuzzer/icons/Ok_btn_9x9.png differ diff --git a/applications/external/multi_fuzzer/icons/Pin_arrow_up_7x9.png b/applications/external/multi_fuzzer/icons/Pin_arrow_up_7x9.png new file mode 100644 index 000000000..a91a6fd5e Binary files /dev/null and b/applications/external/multi_fuzzer/icons/Pin_arrow_up_7x9.png differ diff --git a/applications/external/multi_fuzzer/icons/Pin_back_arrow_10x8.png b/applications/external/multi_fuzzer/icons/Pin_back_arrow_10x8.png new file mode 100644 index 000000000..3bafabd14 Binary files /dev/null and b/applications/external/multi_fuzzer/icons/Pin_back_arrow_10x8.png differ diff --git a/applications/external/ibtn_fuzzer/ibutt_10px.png b/applications/external/multi_fuzzer/icons/ibutt_10px.png similarity index 100% rename from applications/external/ibtn_fuzzer/ibutt_10px.png rename to applications/external/multi_fuzzer/icons/ibutt_10px.png diff --git a/applications/external/flipfrid/rfid_10px.png b/applications/external/multi_fuzzer/icons/rfid_10px.png similarity index 100% rename from applications/external/flipfrid/rfid_10px.png rename to applications/external/multi_fuzzer/icons/rfid_10px.png diff --git a/applications/external/multi_fuzzer/lib/worker/fake_worker.c b/applications/external/multi_fuzzer/lib/worker/fake_worker.c new file mode 100644 index 000000000..07b0479b4 --- /dev/null +++ b/applications/external/multi_fuzzer/lib/worker/fake_worker.c @@ -0,0 +1,485 @@ +#include "fake_worker.h" +#include "protocol_i.h" + +#include + +#include +#include +#include + +#define TAG "Fuzzer worker" + +#if defined(RFID_125_PROTOCOL) + +#include +#include +#include + +#else + +#include +#include + +#endif + +#include + +struct FuzzerWorker { +#if defined(RFID_125_PROTOCOL) + LFRFIDWorker* proto_worker; + ProtocolId protocol_id; + ProtocolDict* protocols_items; +#else + iButtonWorker* proto_worker; + iButtonProtocolId protocol_id; // TODO + iButtonProtocols* protocols_items; + iButtonKey* key; +#endif + + const FuzzerProtocol* protocol; + FuzzerWorkerAttackType attack_type; + uint16_t timer_idle_time_ms; + uint16_t timer_emu_time_ms; + + uint8_t payload[MAX_PAYLOAD_SIZE]; + Stream* uids_stream; + uint16_t index; + uint8_t chusen_byte; + + bool treead_running; + bool in_emu_phase; + FuriTimer* timer; + + FuzzerWorkerUidChagedCallback tick_callback; + void* tick_context; + + FuzzerWorkerEndCallback end_callback; + void* end_context; +}; + +static bool fuzzer_worker_load_key(FuzzerWorker* instance, bool next) { + furi_assert(instance); + furi_assert(instance->protocol); + bool res = false; + + const FuzzerProtocol* protocol = instance->protocol; + + switch(instance->attack_type) { + case FuzzerWorkerAttackTypeDefaultDict: + if(next) { + instance->index++; + } + if(instance->index < protocol->dict.len) { + memcpy( + instance->payload, + &protocol->dict.val[instance->index * protocol->data_size], + protocol->data_size); + res = true; + } + break; + + case FuzzerWorkerAttackTypeLoadFileCustomUids: { + if(next) { + instance->index++; + } + uint8_t str_len = protocol->data_size * 2 + 1; + FuriString* data_str = furi_string_alloc(); + while(true) { + furi_string_reset(data_str); + if(!stream_read_line(instance->uids_stream, data_str)) { + stream_rewind(instance->uids_stream); + // TODO Check empty file & close stream and storage + break; + } else if(furi_string_get_char(data_str, 0) == '#') { + // Skip comment string + continue; + } else if(furi_string_size(data_str) != str_len) { + // Ignore strin with bad length + FURI_LOG_W(TAG, "Bad string length"); + continue; + } else { + FURI_LOG_D(TAG, "Uid candidate: \"%s\"", furi_string_get_cstr(data_str)); + bool parse_ok = true; + for(uint8_t i = 0; i < protocol->data_size; i++) { + if(!hex_char_to_uint8( + furi_string_get_cstr(data_str)[i * 2], + furi_string_get_cstr(data_str)[i * 2 + 1], + &instance->payload[i])) { + parse_ok = false; + break; + } + } + res = parse_ok; + } + break; + } + } + + break; + + case FuzzerWorkerAttackTypeLoadFile: + if(instance->payload[instance->index] != 0xFF) { + instance->payload[instance->index]++; + res = true; + } + + break; + + default: + break; + } +#if defined(RFID_125_PROTOCOL) + protocol_dict_set_data( + instance->protocols_items, instance->protocol_id, instance->payload, MAX_PAYLOAD_SIZE); +#else + ibutton_key_set_protocol_id(instance->key, instance->protocol_id); + iButtonEditableData data; + ibutton_protocols_get_editable_data(instance->protocols_items, instance->key, &data); + + // TODO check data.size logic + data.size = MAX_PAYLOAD_SIZE; + memcpy(data.ptr, instance->payload, MAX_PAYLOAD_SIZE); // data.size); +#endif + return res; +} + +static void fuzzer_worker_on_tick_callback(void* context) { + furi_assert(context); + + FuzzerWorker* instance = context; + + if(instance->in_emu_phase) { + if(instance->treead_running) { +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_stop(instance->proto_worker); +#else + ibutton_worker_stop(instance->proto_worker); +#endif + } + instance->in_emu_phase = false; + furi_timer_start(instance->timer, furi_ms_to_ticks(instance->timer_idle_time_ms)); + } else { + if(!fuzzer_worker_load_key(instance, true)) { + fuzzer_worker_pause(instance); // XXX + if(instance->end_callback) { + instance->end_callback(instance->end_context); + } + } else { + if(instance->treead_running) { +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_emulate_start(instance->proto_worker, instance->protocol_id); +#else + ibutton_worker_emulate_start(instance->proto_worker, instance->key); +#endif + } + instance->in_emu_phase = true; + furi_timer_start(instance->timer, furi_ms_to_ticks(instance->timer_emu_time_ms)); + if(instance->tick_callback) { + instance->tick_callback(instance->tick_context); + } + } + } +} + +void fuzzer_worker_get_current_key(FuzzerWorker* instance, FuzzerPayload* output_key) { + furi_assert(instance); + furi_assert(output_key); + furi_assert(instance->protocol); + + output_key->data_size = instance->protocol->data_size; + memcpy(output_key->data, instance->payload, instance->protocol->data_size); +} + +static void fuzzer_worker_set_protocol(FuzzerWorker* instance, FuzzerProtocolsID protocol_index) { + instance->protocol = &fuzzer_proto_items[protocol_index]; + +#if defined(RFID_125_PROTOCOL) + instance->protocol_id = + protocol_dict_get_protocol_by_name(instance->protocols_items, instance->protocol->name); +#else + // TODO iButtonProtocolIdInvalid check + instance->protocol_id = + ibutton_protocols_get_id_by_name(instance->protocols_items, instance->protocol->name); +#endif +} + +bool fuzzer_worker_init_attack_dict(FuzzerWorker* instance, FuzzerProtocolsID protocol_index) { + furi_assert(instance); + + bool res = false; + fuzzer_worker_set_protocol(instance, protocol_index); + + instance->attack_type = FuzzerWorkerAttackTypeDefaultDict; + instance->index = 0; + + if(!fuzzer_worker_load_key(instance, false)) { + instance->attack_type = FuzzerWorkerAttackTypeMax; + } else { + res = true; + } + + return res; +} + +bool fuzzer_worker_init_attack_file_dict( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + FuriString* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool res = false; + fuzzer_worker_set_protocol(instance, protocol_index); + + Storage* storage = furi_record_open(RECORD_STORAGE); + instance->uids_stream = buffered_file_stream_alloc(storage); + + if(!buffered_file_stream_open( + instance->uids_stream, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + buffered_file_stream_close(instance->uids_stream); + return res; + } + + instance->attack_type = FuzzerWorkerAttackTypeLoadFileCustomUids; + instance->index = 0; + + if(!fuzzer_worker_load_key(instance, false)) { + instance->attack_type = FuzzerWorkerAttackTypeMax; + buffered_file_stream_close(instance->uids_stream); + furi_record_close(RECORD_STORAGE); + } else { + res = true; + } + + return res; +} + +bool fuzzer_worker_init_attack_bf_byte( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + const FuzzerPayload* new_uid, + uint8_t chusen) { + furi_assert(instance); + + bool res = false; + fuzzer_worker_set_protocol(instance, protocol_index); + + instance->attack_type = FuzzerWorkerAttackTypeLoadFile; + instance->index = chusen; + + memcpy(instance->payload, new_uid->data, instance->protocol->data_size); + + res = true; + + return res; +} + +// TODO make it protocol independent +bool fuzzer_worker_load_key_from_file( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + const char* filename) { + furi_assert(instance); + + bool res = false; + fuzzer_worker_set_protocol(instance, protocol_index); + +#if defined(RFID_125_PROTOCOL) + ProtocolId loaded_proto_id = lfrfid_dict_file_load(instance->protocols_items, filename); + if(loaded_proto_id == PROTOCOL_NO) { + // Err Cant load file + FURI_LOG_W(TAG, "Cant load file"); + } else if(instance->protocol_id != loaded_proto_id) { // Err wrong protocol + FURI_LOG_W(TAG, "Wrong protocol"); + FURI_LOG_W( + TAG, + "Selected: %s Loaded: %s", + instance->protocol->name, + protocol_dict_get_name(instance->protocols_items, loaded_proto_id)); + } else { + protocol_dict_get_data( + instance->protocols_items, instance->protocol_id, instance->payload, MAX_PAYLOAD_SIZE); + res = true; + } +#else + if(!ibutton_protocols_load(instance->protocols_items, instance->key, filename)) { + // Err Cant load file + FURI_LOG_W(TAG, "Cant load file"); + } else { + if(instance->protocol_id != ibutton_key_get_protocol_id(instance->key)) { + // Err wrong protocol + FURI_LOG_W(TAG, "Wrong protocol"); + FURI_LOG_W( + TAG, + "Selected: %s Loaded: %s", + instance->protocol->name, + ibutton_protocols_get_name( + instance->protocols_items, ibutton_key_get_protocol_id(instance->key))); + } else { + iButtonEditableData data; + ibutton_protocols_get_editable_data(instance->protocols_items, instance->key, &data); + memcpy(instance->payload, data.ptr, data.size); + res = true; + } + } +#endif + + return res; +} + +FuzzerWorker* fuzzer_worker_alloc() { + FuzzerWorker* instance = malloc(sizeof(FuzzerWorker)); + +#if defined(RFID_125_PROTOCOL) + instance->protocols_items = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); + + instance->proto_worker = lfrfid_worker_alloc(instance->protocols_items); +#else + instance->protocols_items = ibutton_protocols_alloc(); + instance->key = + ibutton_key_alloc(ibutton_protocols_get_max_data_size(instance->protocols_items)); + + instance->proto_worker = ibutton_worker_alloc(instance->protocols_items); +#endif + instance->attack_type = FuzzerWorkerAttackTypeMax; + instance->index = 0; + instance->treead_running = false; + instance->in_emu_phase = false; + + memset(instance->payload, 0x00, sizeof(instance->payload)); + + instance->timer_idle_time_ms = PROTOCOL_DEF_IDLE_TIME * 100; + instance->timer_emu_time_ms = PROTOCOL_DEF_EMU_TIME * 100; + + instance->timer = + furi_timer_alloc(fuzzer_worker_on_tick_callback, FuriTimerTypeOnce, instance); + + return instance; +} + +void fuzzer_worker_free(FuzzerWorker* instance) { + furi_assert(instance); + + fuzzer_worker_stop(instance); + + furi_timer_free(instance->timer); + +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_free(instance->proto_worker); + + protocol_dict_free(instance->protocols_items); +#else + ibutton_worker_free(instance->proto_worker); + + ibutton_key_free(instance->key); + ibutton_protocols_free(instance->protocols_items); +#endif + + free(instance); +} + +bool fuzzer_worker_start(FuzzerWorker* instance, uint8_t idle_time, uint8_t emu_time) { + furi_assert(instance); + + if(instance->attack_type < FuzzerWorkerAttackTypeMax) { + if(idle_time == 0) { + instance->timer_idle_time_ms = 10; + } else { + instance->timer_idle_time_ms = idle_time * 100; + } + if(emu_time == 0) { + instance->timer_emu_time_ms = 10; + } else { + instance->timer_emu_time_ms = emu_time * 100; + } + + FURI_LOG_D( + TAG, + "Emu_time %u ms Idle_time %u ms", + instance->timer_emu_time_ms, + instance->timer_idle_time_ms); + + if(!instance->treead_running) { +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_start_thread(instance->proto_worker); +#else + ibutton_worker_start_thread(instance->proto_worker); +#endif + FURI_LOG_D(TAG, "Worker Starting"); + instance->treead_running = true; + } else { + FURI_LOG_D(TAG, "Worker UnPaused"); + } + +#if defined(RFID_125_PROTOCOL) + // lfrfid_worker_start_thread(instance->proto_worker); + lfrfid_worker_emulate_start(instance->proto_worker, instance->protocol_id); +#else + // ibutton_worker_start_thread(instance->proto_worker); + ibutton_worker_emulate_start(instance->proto_worker, instance->key); +#endif + instance->in_emu_phase = true; + furi_timer_start(instance->timer, furi_ms_to_ticks(instance->timer_emu_time_ms)); + return true; + } + return false; +} + +void fuzzer_worker_pause(FuzzerWorker* instance) { + furi_assert(instance); + + furi_timer_stop(instance->timer); + + if(instance->treead_running) { +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_stop(instance->proto_worker); +#else + ibutton_worker_stop(instance->proto_worker); +#endif + FURI_LOG_D(TAG, "Worker Paused"); + } +} + +void fuzzer_worker_stop(FuzzerWorker* instance) { + furi_assert(instance); + + furi_timer_stop(instance->timer); + + if(instance->treead_running) { +#if defined(RFID_125_PROTOCOL) + lfrfid_worker_stop(instance->proto_worker); + lfrfid_worker_stop_thread(instance->proto_worker); +#else + ibutton_worker_stop(instance->proto_worker); + ibutton_worker_stop_thread(instance->proto_worker); +#endif + FURI_LOG_D(TAG, "Worker Stopping"); + instance->treead_running = false; + } + + if(instance->attack_type == FuzzerWorkerAttackTypeLoadFileCustomUids) { + buffered_file_stream_close(instance->uids_stream); + furi_record_close(RECORD_STORAGE); + instance->attack_type = FuzzerWorkerAttackTypeMax; + } + + // TODO anything else +} + +void fuzzer_worker_set_uid_chaged_callback( + FuzzerWorker* instance, + FuzzerWorkerUidChagedCallback callback, + void* context) { + furi_assert(instance); + instance->tick_callback = callback; + instance->tick_context = context; +} + +void fuzzer_worker_set_end_callback( + FuzzerWorker* instance, + FuzzerWorkerEndCallback callback, + void* context) { + furi_assert(instance); + instance->end_callback = callback; + instance->end_context = context; +} diff --git a/applications/external/multi_fuzzer/lib/worker/fake_worker.h b/applications/external/multi_fuzzer/lib/worker/fake_worker.h new file mode 100644 index 000000000..8b934f300 --- /dev/null +++ b/applications/external/multi_fuzzer/lib/worker/fake_worker.h @@ -0,0 +1,138 @@ +#pragma once + +#include + +#include "protocol.h" + +typedef enum { + FuzzerWorkerAttackTypeDefaultDict = 0, + FuzzerWorkerAttackTypeLoadFile, + FuzzerWorkerAttackTypeLoadFileCustomUids, + + FuzzerWorkerAttackTypeMax, +} FuzzerWorkerAttackType; + +typedef void (*FuzzerWorkerUidChagedCallback)(void* context); +typedef void (*FuzzerWorkerEndCallback)(void* context); + +typedef struct FuzzerWorker FuzzerWorker; + +/** + * Allocate FuzzerWorker + * + * @return FuzzerWorker* pointer to FuzzerWorker + */ +FuzzerWorker* fuzzer_worker_alloc(); + +/** + * Free FuzzerWorker + * + * @param instance Pointer to a FuzzerWorker + */ +void fuzzer_worker_free(FuzzerWorker* instance); + +/** + * Start or continue emulation + * + * @param instance Pointer to a FuzzerWorker + * @param idle_time Delay between emulations in tenths of a second + * @param emu_time Emulation time of one UID in tenths of a second + * @return bool True if emulation has started + */ +bool fuzzer_worker_start(FuzzerWorker* instance, uint8_t idle_time, uint8_t emu_time); + +/** + * Stop emulation and deinit worker + * + * @param instance Pointer to a FuzzerWorker + */ +void fuzzer_worker_stop(FuzzerWorker* instance); + +/** + * Suspend emulation + * + * @param instance Pointer to a FuzzerWorker + */ +void fuzzer_worker_pause(FuzzerWorker* instance); + +/** + * Init attack by default dictionary + * + * @param instance Pointer to a FuzzerWorker + * @param protocol_index index of the selected protocol + * @return bool True if initialization is successful + */ +bool fuzzer_worker_init_attack_dict(FuzzerWorker* instance, FuzzerProtocolsID protocol_index); + +/** + * Init attack by custom dictionary + * + * @param instance Pointer to a FuzzerWorker + * @param protocol_index index of the selected protocol + * @param file_path file path to the dictionary + * @return bool True if initialization is successful + */ +bool fuzzer_worker_init_attack_file_dict( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + FuriString* file_path); + +/** + * Init attack brute force one of byte + * + * @param instance Pointer to a FuzzerWorker + * @param protocol_index index of the selected protocol + * @param new_uid Pointer to a FuzzerPayload with UID for brute force + * @param chosen index of chusen byte + * @return bool True if initialization is successful + */ +bool fuzzer_worker_init_attack_bf_byte( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + const FuzzerPayload* new_uid, + uint8_t chusen); + +/** + * Get current UID + * + * @param instance Pointer to a FuzzerWorker + * @param output_key Pointer to a FuzzerPayload + */ +void fuzzer_worker_get_current_key(FuzzerWorker* instance, FuzzerPayload* output_key); + +/** + * Load UID from Flipper Format Key file + * + * @param instance Pointer to a FuzzerWorker + * @param protocol_index index of the selected protocol + * @param filename file path to the key file + * @return bool True if loading is successful + */ +bool fuzzer_worker_load_key_from_file( + FuzzerWorker* instance, + FuzzerProtocolsID protocol_index, + const char* filename); + +/** + * Set callback for uid changed + * + * @param instance Pointer to a FuzzerWorker + * @param callback Callback for uid changed + * @param context Context for callback + */ +void fuzzer_worker_set_uid_chaged_callback( + FuzzerWorker* instance, + FuzzerWorkerUidChagedCallback callback, + void* context); + +/** + * Set callback for end of emulation + * + * @param instance Pointer to a FuzzerWorker + * @param callback Callback for end of emulation + * @param context Context for callback + */ +void fuzzer_worker_set_end_callback( + FuzzerWorker* instance, + FuzzerWorkerEndCallback callback, + void* context); \ No newline at end of file diff --git a/applications/external/multi_fuzzer/lib/worker/protocol.c b/applications/external/multi_fuzzer/lib/worker/protocol.c new file mode 100644 index 000000000..a64fe8767 --- /dev/null +++ b/applications/external/multi_fuzzer/lib/worker/protocol.c @@ -0,0 +1,291 @@ +#include "protocol_i.h" +#include "furi.h" + +// ####################### +// ## Ibutton Protocols ## +// ####################### +#define DS1990_DATA_SIZE (8) +#define Metakom_DATA_SIZE (4) +#define Cyfral_DATA_SIZE (2) + +const uint8_t uid_list_ds1990[][DS1990_DATA_SIZE] = { + {0x01, 0xBE, 0x40, 0x11, 0x5A, 0x36, 0x00, 0xE1}, //– код универсального ключа, для Vizit + {0x01, 0xBE, 0x40, 0x11, 0x5A, 0x56, 0x00, 0xBB}, //- проверен работает + {0x01, 0xBE, 0x40, 0x11, 0x00, 0x00, 0x00, 0x77}, //- проверен работает + {0x01, 0xBE, 0x40, 0x11, 0x0A, 0x00, 0x00, 0x1D}, //- проверен работает Визит иногда КЕЙМАНЫ + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F}, //- проверен(метаком, цифрал, ВИЗИТ). + {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x9B}, //- проверен Визит, Метакомы, КОНДОР + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14}, //???-Открываает 98% Метаком и некоторые Цифрал + {0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x19, 0xFF}, //???-Отлично работает на старых домофонах + {0x01, 0x6F, 0x2E, 0x88, 0x8A, 0x00, 0x00, 0x4D}, //???-Открывать что-то должен + {0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x7E, 0x88}, //???-Cyfral, Metakom + {0x01, 0x53, 0xD4, 0xFE, 0x00, 0x00, 0x00, 0x6F}, //???-домофоны Визит (Vizit) - до 99% + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D}, //???-домофоны Cyfral CCD-20 - до 70% + {0x01, 0x00, 0xBE, 0x11, 0xAA, 0x00, 0x00, 0xFB}, //???-домофоны Кейман (KEYMAN) + {0x01, 0x76, 0xB8, 0x2E, 0x0F, 0x00, 0x00, 0x5C}, //???-домофоны Форвард + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14}, // Only FF + {0x01, 0x78, 0x00, 0x48, 0xFD, 0xFF, 0xFF, 0xD1}, // StarNew Uni5 + {0x01, 0xA9, 0xE4, 0x3C, 0x09, 0x00, 0x00, 0xE6}, // Eltis Uni +}; + +const uint8_t uid_list_metakom[][Metakom_DATA_SIZE] = { + {0x00, 0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF, 0xFF}, // Only FF + {0x11, 0x11, 0x11, 0x11}, // Only 11 + {0x22, 0x22, 0x22, 0x22}, // Only 22 + {0x33, 0x33, 0x33, 0x33}, // Only 33 + {0x44, 0x44, 0x44, 0x44}, // Only 44 + {0x55, 0x55, 0x55, 0x55}, // Only 55 + {0x66, 0x66, 0x66, 0x66}, // Only 66 + {0x77, 0x77, 0x77, 0x77}, // Only 77 + {0x88, 0x88, 0x88, 0x88}, // Only 88 + {0x99, 0x99, 0x99, 0x99}, // Only 99 + {0x12, 0x34, 0x56, 0x78}, // Incremental UID + {0x9A, 0x78, 0x56, 0x34}, // Decremental UID + {0x04, 0xd0, 0x9b, 0x0d}, // ?? + {0x34, 0x00, 0x29, 0x3d}, // ?? + {0x04, 0xdf, 0x00, 0x00}, // ?? + {0xCA, 0xCA, 0xCA, 0xCA}, // ?? +}; + +const uint8_t uid_list_cyfral[][Cyfral_DATA_SIZE] = { + {0x00, 0x00}, // Null bytes + {0xFF, 0xFF}, // Only FF + {0x11, 0x11}, // Only 11 + {0x22, 0x22}, // Only 22 + {0x33, 0x33}, // Only 33 + {0x44, 0x44}, // Only 44 + {0x55, 0x55}, // Only 55 + {0x66, 0x66}, // Only 66 + {0x77, 0x77}, // Only 77 + {0x88, 0x88}, // Only 88 + {0x99, 0x99}, // Only 99 + {0x12, 0x34}, // Incremental UID + {0x56, 0x34}, // Decremental UID + {0xCA, 0xCA}, // ?? + {0x8E, 0xC9}, // Elevator code + {0x6A, 0x50}, // VERY fresh code from smartkey +}; + +// ########################### +// ## Rfid_125khz Protocols ## +// ########################### +#define EM4100_DATA_SIZE (5) +#define HIDProx_DATA_SIZE (6) +#define PAC_DATA_SIZE (4) +#define H10301_DATA_SIZE (3) + +const uint8_t uid_list_em4100[][EM4100_DATA_SIZE] = { + {0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF + {0x11, 0x11, 0x11, 0x11, 0x11}, // Only 11 + {0x22, 0x22, 0x22, 0x22, 0x22}, // Only 22 + {0x33, 0x33, 0x33, 0x33, 0x33}, // Only 33 + {0x44, 0x44, 0x44, 0x44, 0x44}, // Only 44 + {0x55, 0x55, 0x55, 0x55, 0x55}, // Only 55 + {0x66, 0x66, 0x66, 0x66, 0x66}, // Only 66 + {0x77, 0x77, 0x77, 0x77, 0x77}, // Only 77 + {0x88, 0x88, 0x88, 0x88, 0x88}, // Only 88 + {0x99, 0x99, 0x99, 0x99, 0x99}, // Only 99 + {0x12, 0x34, 0x56, 0x78, 0x9A}, // Incremental UID + {0x9A, 0x78, 0x56, 0x34, 0x12}, // Decremental UID + {0x04, 0xd0, 0x9b, 0x0d, 0x6a}, // From arha + {0x34, 0x00, 0x29, 0x3d, 0x9e}, // From arha + {0x04, 0xdf, 0x00, 0x00, 0x01}, // From arha + {0xCA, 0xCA, 0xCA, 0xCA, 0xCA}, // From arha +}; + +const uint8_t uid_list_hid[][HIDProx_DATA_SIZE] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, // Only 11 + {0x22, 0x22, 0x22, 0x22, 0x22, 0x22}, // Only 22 + {0x33, 0x33, 0x33, 0x33, 0x33, 0x33}, // Only 33 + {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, // Only 44 + {0x55, 0x55, 0x55, 0x55, 0x55, 0x55}, // Only 55 + {0x66, 0x66, 0x66, 0x66, 0x66, 0x66}, // Only 66 + {0x77, 0x77, 0x77, 0x77, 0x77, 0x77}, // Only 77 + {0x88, 0x88, 0x88, 0x88, 0x88, 0x88}, // Only 88 + {0x99, 0x99, 0x99, 0x99, 0x99, 0x99}, // Only 99 + {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}, // Incremental UID + {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}, // Decremental UID + {0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA}, // From arha +}; + +const uint8_t uid_list_pac[][PAC_DATA_SIZE] = { + {0x00, 0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF, 0xFF}, // Only FF + {0x11, 0x11, 0x11, 0x11}, // Only 11 + {0x22, 0x22, 0x22, 0x22}, // Only 22 + {0x33, 0x33, 0x33, 0x33}, // Only 33 + {0x44, 0x44, 0x44, 0x44}, // Only 44 + {0x55, 0x55, 0x55, 0x55}, // Only 55 + {0x66, 0x66, 0x66, 0x66}, // Only 66 + {0x77, 0x77, 0x77, 0x77}, // Only 77 + {0x88, 0x88, 0x88, 0x88}, // Only 88 + {0x99, 0x99, 0x99, 0x99}, // Only 99 + {0x12, 0x34, 0x56, 0x78}, // Incremental UID + {0x9A, 0x78, 0x56, 0x34}, // Decremental UID + {0x04, 0xd0, 0x9b, 0x0d}, // From arha + {0x34, 0x00, 0x29, 0x3d}, // From arha + {0x04, 0xdf, 0x00, 0x00}, // From arha + {0xCA, 0xCA, 0xCA, 0xCA}, // From arha +}; + +const uint8_t uid_list_h10301[][H10301_DATA_SIZE] = { + {0x00, 0x00, 0x00}, // Null bytes + {0xFF, 0xFF, 0xFF}, // Only FF + {0x11, 0x11, 0x11}, // Only 11 + {0x22, 0x22, 0x22}, // Only 22 + {0x33, 0x33, 0x33}, // Only 33 + {0x44, 0x44, 0x44}, // Only 44 + {0x55, 0x55, 0x55}, // Only 55 + {0x66, 0x66, 0x66}, // Only 66 + {0x77, 0x77, 0x77}, // Only 77 + {0x88, 0x88, 0x88}, // Only 88 + {0x99, 0x99, 0x99}, // Only 99 + {0x12, 0x34, 0x56}, // Incremental UID + {0x56, 0x34, 0x12}, // Decremental UID + {0xCA, 0xCA, 0xCA}, // From arha +}; + +#if defined(RFID_125_PROTOCOL) +const FuzzerProtocol fuzzer_proto_items[] = { + [EM4100] = + { + .name = "EM4100", + .data_size = EM4100_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_em4100, + .len = COUNT_OF(uid_list_em4100), + }, + }, + [HIDProx] = + { + .name = "HIDProx", + .data_size = HIDProx_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_hid, + .len = COUNT_OF(uid_list_hid), + }, + }, + [PAC] = + { + .name = "PAC/Stanley", + .data_size = PAC_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_pac, + .len = COUNT_OF(uid_list_pac), + }, + }, + [H10301] = + { + .name = "H10301", + .data_size = H10301_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_h10301, + .len = COUNT_OF(uid_list_h10301), + }, + }, +}; +#else +const FuzzerProtocol fuzzer_proto_items[] = { + [DS1990] = + { + .name = "DS1990", + .data_size = DS1990_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_ds1990, + .len = COUNT_OF(uid_list_ds1990), + }, + }, + [Metakom] = + { + .name = "Metakom", + .data_size = Metakom_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_metakom, + .len = COUNT_OF(uid_list_metakom), + }, + }, + [Cyfral] = + { + .name = "Cyfral", + .data_size = Cyfral_DATA_SIZE, + .dict = + { + .val = (const uint8_t*)&uid_list_cyfral, + .len = COUNT_OF(uid_list_cyfral), + }, + }, +}; +#endif + +typedef struct { + const char* menu_label; + FuzzerAttackId attack_id; +} FuzzerMenuItems; + +const FuzzerMenuItems fuzzer_menu_items[] = { + {"Default Values", FuzzerAttackIdDefaultValues}, +#ifdef RFID_125_PROTOCOL + {"BF Customer ID", FuzzerAttackIdBFCustomerID}, +#endif + {"Load File", FuzzerAttackIdLoadFile}, + {"Load UIDs from file", FuzzerAttackIdLoadFileCustomUids}, +}; + +FuzzerPayload* fuzzer_payload_alloc() { + FuzzerPayload* payload = malloc(sizeof(FuzzerPayload)); + payload->data = malloc(sizeof(payload->data[0]) * MAX_PAYLOAD_SIZE); + + return payload; +} + +void fuzzer_payload_free(FuzzerPayload* payload) { + furi_assert(payload); + + if(payload->data) { + free(payload->data); + } + free(payload); +} + +const char* fuzzer_proto_get_name(FuzzerProtocolsID index) { + return fuzzer_proto_items[index].name; +} + +uint8_t fuzzer_proto_get_count_of_protocols() { + return COUNT_OF(fuzzer_proto_items); +} + +uint8_t fuzzer_proto_get_max_data_size() { + return MAX_PAYLOAD_SIZE; +} + +uint8_t fuzzer_proto_get_def_emu_time() { + return PROTOCOL_DEF_EMU_TIME; +} + +uint8_t fuzzer_proto_get_def_idle_time() { + return PROTOCOL_DEF_IDLE_TIME; +} + +const char* fuzzer_proto_get_menu_label(uint8_t index) { + return fuzzer_menu_items[index].menu_label; +} + +FuzzerAttackId fuzzer_proto_get_attack_id_by_index(uint8_t index) { + return fuzzer_menu_items[index].attack_id; +} + +uint8_t fuzzer_proto_get_count_of_menu_items() { + return COUNT_OF(fuzzer_menu_items); +} diff --git a/applications/external/multi_fuzzer/lib/worker/protocol.h b/applications/external/multi_fuzzer/lib/worker/protocol.h new file mode 100644 index 000000000..9c5315d00 --- /dev/null +++ b/applications/external/multi_fuzzer/lib/worker/protocol.h @@ -0,0 +1,89 @@ +#pragma once + +#include + +// #define RFID_125_PROTOCOL + +typedef struct FuzzerPayload FuzzerPayload; + +typedef enum { +#if defined(RFID_125_PROTOCOL) + EM4100, + HIDProx, + PAC, + H10301, +#else + DS1990, + Metakom, + Cyfral, +#endif +} FuzzerProtocolsID; + +typedef enum { + FuzzerAttackIdDefaultValues = 0, + FuzzerAttackIdLoadFile, + FuzzerAttackIdLoadFileCustomUids, + FuzzerAttackIdBFCustomerID, +} FuzzerAttackId; + +struct FuzzerPayload { + uint8_t* data; + uint8_t data_size; +}; + +/** + * Allocate FuzzerPayload + * + * @return FuzzerPayload* pointer to FuzzerPayload + */ +FuzzerPayload* fuzzer_payload_alloc(); + +/** + * Free FuzzerPayload + * + * @param instance Pointer to a FuzzerPayload + */ +void fuzzer_payload_free(FuzzerPayload*); + +/** + * Get maximum length of UID among all supported protocols + * @return Maximum length of UID + */ +uint8_t fuzzer_proto_get_max_data_size(); + +// TODO add description +uint8_t fuzzer_proto_get_def_emu_time(); +uint8_t fuzzer_proto_get_def_idle_time(); + +/** + * Get protocol name based on its index + * @param index protocol index + * @return pointer to a string containing the name + */ +const char* fuzzer_proto_get_name(FuzzerProtocolsID index); + +/** + * Get number of protocols + * @return number of protocols + */ +uint8_t fuzzer_proto_get_count_of_protocols(); + +/** + * Get menu label based on its index + * @param index menu index + * @return pointer to a string containing the menu label + */ +const char* fuzzer_proto_get_menu_label(uint8_t index); + +/** + * Get FuzzerAttackId based on its index + * @param index menu index + * @return FuzzerAttackId + */ +FuzzerAttackId fuzzer_proto_get_attack_id_by_index(uint8_t index); + +/** + * Get number of menu items + * @return number of menu items + */ +uint8_t fuzzer_proto_get_count_of_menu_items(); \ No newline at end of file diff --git a/applications/external/multi_fuzzer/lib/worker/protocol_i.h b/applications/external/multi_fuzzer/lib/worker/protocol_i.h new file mode 100644 index 000000000..2f1c65fd7 --- /dev/null +++ b/applications/external/multi_fuzzer/lib/worker/protocol_i.h @@ -0,0 +1,43 @@ +#pragma once + +#include "protocol.h" + +#if defined(RFID_125_PROTOCOL) +#define MAX_PAYLOAD_SIZE (6) +#define PROTOCOL_DEF_IDLE_TIME (4) +#define PROTOCOL_DEF_EMU_TIME (5) +#define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME +#else +#define MAX_PAYLOAD_SIZE (8) +#define PROTOCOL_DEF_IDLE_TIME (2) +#define PROTOCOL_DEF_EMU_TIME (2) +#define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME +#endif + +typedef struct ProtoDict ProtoDict; +typedef struct FuzzerProtocol FuzzerProtocol; + +struct ProtoDict { + const uint8_t* val; + const uint8_t len; +}; + +struct FuzzerProtocol { + const char* name; + const uint8_t data_size; + const ProtoDict dict; +}; + +// #define MAX_PAYLOAD_SIZE 6 + +// #define FUZZ_TIME_DELAY_MIN (5) +// #define FUZZ_TIME_DELAY_DEFAULT (10) +// #define FUZZ_TIME_DELAY_MAX (70) + +// #define MAX_PAYLOAD_SIZE 8 + +// #define FUZZ_TIME_DELAY_MIN (4) +// #define FUZZ_TIME_DELAY_DEFAULT (8) +// #define FUZZ_TIME_DELAY_MAX (80) + +extern const FuzzerProtocol fuzzer_proto_items[]; \ No newline at end of file diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene.c b/applications/external/multi_fuzzer/scenes/fuzzer_scene.c new file mode 100644 index 000000000..0fe0f558d --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene.c @@ -0,0 +1,30 @@ +#include "fuzzer_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const fuzzer_scene_on_enter_handlers[])(void*) = { +#include "fuzzer_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const fuzzer_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "fuzzer_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const fuzzer_scene_on_exit_handlers[])(void* context) = { +#include "fuzzer_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers fuzzer_scene_handlers = { + .on_enter_handlers = fuzzer_scene_on_enter_handlers, + .on_event_handlers = fuzzer_scene_on_event_handlers, + .on_exit_handlers = fuzzer_scene_on_exit_handlers, + .scene_num = FuzzerSceneNum, +}; diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene.h b/applications/external/multi_fuzzer/scenes/fuzzer_scene.h new file mode 100644 index 000000000..280654510 --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) FuzzerScene##id, +typedef enum { +#include "fuzzer_scene_config.h" + FuzzerSceneNum, +} FuzzerScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers fuzzer_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "fuzzer_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "fuzzer_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "fuzzer_scene_config.h" +#undef ADD_SCENE diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene_attack.c b/applications/external/multi_fuzzer/scenes/fuzzer_scene_attack.c new file mode 100644 index 000000000..6424e62b5 --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene_attack.c @@ -0,0 +1,162 @@ +#include "../fuzzer_i.h" +#include "../helpers/fuzzer_custom_event.h" + +const NotificationSequence sequence_one_green_50_on_blink_blue = { + &message_red_255, + &message_delay_50, + &message_red_0, + &message_blink_start_10, + &message_blink_set_color_blue, + &message_do_not_reset, + NULL, +}; + +static void fuzzer_scene_attack_update_uid(PacsFuzzerApp* app) { + furi_assert(app); + furi_assert(app->worker); + furi_assert(app->attack_view); + + fuzzer_worker_get_current_key(app->worker, app->payload); + + fuzzer_view_attack_set_uid(app->attack_view, app->payload); +} + +static void fuzzer_scene_attack_set_state(PacsFuzzerApp* app, FuzzerAttackState state) { + furi_assert(app); + + scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, state); + switch(state) { + case FuzzerAttackStateIdle: + notification_message(app->notifications, &sequence_blink_stop); + fuzzer_view_attack_pause(app->attack_view); + break; + + case FuzzerAttackStateRunning: + notification_message(app->notifications, &sequence_blink_start_blue); + fuzzer_view_attack_start(app->attack_view); + break; + + case FuzzerAttackStateEnd: + notification_message(app->notifications, &sequence_blink_stop); + notification_message(app->notifications, &sequence_single_vibro); + fuzzer_view_attack_end(app->attack_view); + break; + + case FuzzerAttackStateOff: + notification_message(app->notifications, &sequence_blink_stop); + fuzzer_view_attack_stop(app->attack_view); + break; + } +} + +void fuzzer_scene_attack_worker_tick_callback(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + notification_message(app->notifications, &sequence_one_green_50_on_blink_blue); + fuzzer_scene_attack_update_uid(app); + + // view_dispatcher_send_custom_event(app->view_dispatcher, FuzzerCustomEventViewAttackTick); +} + +void fuzzer_scene_attack_worker_end_callback(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, FuzzerCustomEventViewAttackEnd); +} + +void fuzzer_scene_attack_callback(FuzzerCustomEvent event, void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void fuzzer_scene_attack_on_enter(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + fuzzer_view_attack_set_callback(app->attack_view, fuzzer_scene_attack_callback, app); + + fuzzer_worker_set_uid_chaged_callback( + app->worker, fuzzer_scene_attack_worker_tick_callback, app); + + fuzzer_worker_set_end_callback(app->worker, fuzzer_scene_attack_worker_end_callback, app); + + fuzzer_view_attack_reset_data( + app->attack_view, + fuzzer_proto_get_menu_label(app->fuzzer_state.menu_index), + fuzzer_proto_get_name(app->fuzzer_state.proto_index)); + + fuzzer_scene_attack_update_uid(app); + + scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, FuzzerAttackStateIdle); + + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDAttack); +} + +bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + PacsFuzzerApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == FuzzerCustomEventViewAttackBack) { + if(scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack) == + FuzzerAttackStateRunning) { + // Pause if attack running + fuzzer_worker_pause(app->worker); + + fuzzer_scene_attack_set_state(app, FuzzerAttackStateIdle); + } else { + // Exit + fuzzer_worker_stop(app->worker); + + fuzzer_scene_attack_set_state(app, FuzzerAttackStateOff); + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + } + consumed = true; + } else if(event.event == FuzzerCustomEventViewAttackOk) { + if(scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack) == + FuzzerAttackStateIdle) { + // Start or Continue Attack + if(fuzzer_worker_start( + app->worker, + fuzzer_view_attack_get_time_delay(app->attack_view), + fuzzer_view_attack_get_emu_time(app->attack_view))) { + fuzzer_scene_attack_set_state(app, FuzzerAttackStateRunning); + } else { + // Error? + } + } else if( + scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack) == + FuzzerAttackStateRunning) { + // Pause if attack running + fuzzer_worker_pause(app->worker); + + fuzzer_scene_attack_set_state(app, FuzzerAttackStateIdle); + } + consumed = true; + // } else if(event.event == FuzzerCustomEventViewAttackTick) { + // consumed = true; + } else if(event.event == FuzzerCustomEventViewAttackEnd) { + fuzzer_scene_attack_set_state(app, FuzzerAttackStateEnd); + consumed = true; + } + } + + return consumed; +} + +void fuzzer_scene_attack_on_exit(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + // XXX the scene has no descendants, and the return will be processed in on_event + // fuzzer_worker_stop(); + + fuzzer_worker_set_uid_chaged_callback(app->worker, NULL, NULL); + fuzzer_worker_set_end_callback(app->worker, NULL, NULL); +} diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene_config.h b/applications/external/multi_fuzzer/scenes/fuzzer_scene_config.h new file mode 100644 index 000000000..711ebe1c4 --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(fuzzer, main, Main) +ADD_SCENE(fuzzer, attack, Attack) +ADD_SCENE(fuzzer, field_editor, FieldEditor) \ No newline at end of file diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene_field_editor.c b/applications/external/multi_fuzzer/scenes/fuzzer_scene_field_editor.c new file mode 100644 index 000000000..ccea123dc --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene_field_editor.c @@ -0,0 +1,66 @@ +#include "../fuzzer_i.h" +#include "../helpers/fuzzer_custom_event.h" + +void fuzzer_scene_field_editor_callback(FuzzerCustomEvent event, void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void fuzzer_scene_field_editor_on_enter(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + fuzzer_view_field_editor_set_callback( + app->field_editor_view, fuzzer_scene_field_editor_callback, app); + + fuzzer_worker_get_current_key(app->worker, app->payload); + + switch(scene_manager_get_scene_state(app->scene_manager, FuzzerSceneFieldEditor)) { + case FuzzerFieldEditorStateEditingOn: + fuzzer_view_field_editor_reset_data(app->field_editor_view, app->payload, true); + break; + + case FuzzerFieldEditorStateEditingOff: + fuzzer_view_field_editor_reset_data(app->field_editor_view, app->payload, false); + break; + + default: + break; + } + + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDFieldEditor); +} + +bool fuzzer_scene_field_editor_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + PacsFuzzerApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == FuzzerCustomEventViewFieldEditorBack) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + } else if(event.event == FuzzerCustomEventViewFieldEditorOk) { + fuzzer_view_field_editor_get_uid(app->field_editor_view, app->payload); + if(fuzzer_worker_init_attack_bf_byte( + app->worker, + app->fuzzer_state.proto_index, + app->payload, + fuzzer_view_field_editor_get_index(app->field_editor_view))) { + scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); + } + } + } + + return consumed; +} + +void fuzzer_scene_field_editor_on_exit(void* context) { + // furi_assert(context); + // PacsFuzzerApp* app = context; + UNUSED(context); +} diff --git a/applications/external/multi_fuzzer/scenes/fuzzer_scene_main.c b/applications/external/multi_fuzzer/scenes/fuzzer_scene_main.c new file mode 100644 index 000000000..0d074a121 --- /dev/null +++ b/applications/external/multi_fuzzer/scenes/fuzzer_scene_main.c @@ -0,0 +1,189 @@ +#include "../fuzzer_i.h" +#include "../helpers/fuzzer_custom_event.h" + +#include "../lib/worker/protocol.h" + +void fuzzer_scene_main_callback(FuzzerCustomEvent event, void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void fuzzer_scene_main_error_popup_callback(void* context) { + PacsFuzzerApp* app = context; + notification_message(app->notifications, &sequence_reset_rgb); + view_dispatcher_send_custom_event(app->view_dispatcher, FuzzerCustomEventViewMainPopupErr); +} + +static bool fuzzer_scene_main_load_custom_dict(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + FuzzerConsts* consts = app->fuzzer_const; + + furi_string_set_str(app->file_path, consts->custom_dict_folder); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, consts->custom_dict_extension, &I_rfid_10px); + browser_options.base_path = consts->custom_dict_folder; + browser_options.hide_ext = false; + + bool res = + dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); + + return res; +} + +static bool fuzzer_scene_main_load_key(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + FuzzerConsts* consts = app->fuzzer_const; + + furi_string_set_str(app->file_path, consts->path_key_folder); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, consts->key_extension, consts->key_icon); + browser_options.base_path = consts->path_key_folder; + browser_options.hide_ext = true; + + bool res = + dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); + + return res; +} + +static void fuzzer_scene_main_show_error(void* context, const char* erre_str) { + furi_assert(context); + PacsFuzzerApp* app = context; + popup_set_header(app->popup, erre_str, 64, 20, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_set_red_255); + notification_message(app->notifications, &sequence_double_vibro); + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDPopup); +} + +void fuzzer_scene_main_on_enter(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + + fuzzer_view_main_set_callback(app->main_view, fuzzer_scene_main_callback, app); + + fuzzer_view_main_update_data(app->main_view, app->fuzzer_state); + + // Setup view + Popup* popup = app->popup; + // popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48); + popup_set_timeout(popup, 2500); + popup_set_context(popup, app); + popup_set_callback(popup, fuzzer_scene_main_error_popup_callback); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDMain); +} + +bool fuzzer_scene_main_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + PacsFuzzerApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == FuzzerCustomEventViewMainBack) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + } else if(event.event == FuzzerCustomEventViewMainPopupErr) { + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDMain); + consumed = true; + } else if(event.event == FuzzerCustomEventViewMainOk) { + fuzzer_view_main_get_state(app->main_view, &app->fuzzer_state); + + // TODO error logic + bool loading_ok = false; + + switch(fuzzer_proto_get_attack_id_by_index(app->fuzzer_state.menu_index)) { + case FuzzerAttackIdDefaultValues: + loading_ok = + fuzzer_worker_init_attack_dict(app->worker, app->fuzzer_state.proto_index); + + if(!loading_ok) { + // error + fuzzer_scene_main_show_error(app, "Default dictionary\nis empty"); + } + break; + + case FuzzerAttackIdBFCustomerID: + // TODO + app->payload->data_size = fuzzer_proto_get_max_data_size(); + memset(app->payload->data, 0x00, app->payload->data_size); + + if(fuzzer_worker_init_attack_bf_byte( + app->worker, app->fuzzer_state.proto_index, app->payload, 0)) { + scene_manager_set_scene_state( + app->scene_manager, + FuzzerSceneFieldEditor, + FuzzerFieldEditorStateEditingOff); + scene_manager_next_scene(app->scene_manager, FuzzerSceneFieldEditor); + + } else { + // error + } + break; + + case FuzzerAttackIdLoadFile: + if(!fuzzer_scene_main_load_key(app)) { + break; + } else { + if(fuzzer_worker_load_key_from_file( + app->worker, + app->fuzzer_state.proto_index, + furi_string_get_cstr(app->file_path))) { + scene_manager_set_scene_state( + app->scene_manager, + FuzzerSceneFieldEditor, + FuzzerFieldEditorStateEditingOn); + scene_manager_next_scene(app->scene_manager, FuzzerSceneFieldEditor); + FURI_LOG_I("Scene", "Load ok"); + } else { + fuzzer_scene_main_show_error(app, "Unsupported protocol\nor broken file"); + FURI_LOG_W("Scene", "Load err"); + } + } + break; + + case FuzzerAttackIdLoadFileCustomUids: + if(!fuzzer_scene_main_load_custom_dict(app)) { + break; + } else { + loading_ok = fuzzer_worker_init_attack_file_dict( + app->worker, app->fuzzer_state.proto_index, app->file_path); + if(!loading_ok) { + fuzzer_scene_main_show_error(app, "Incorrect key format\nor length"); + // error + } + } + break; + + default: + fuzzer_scene_main_show_error(app, "Unsuported attack"); + break; + } + + if(loading_ok) { + scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); + } + consumed = true; + } + } + + return consumed; +} + +void fuzzer_scene_main_on_exit(void* context) { + // furi_assert(context); + // PacsFuzzerApp* app = context; + UNUSED(context); +} diff --git a/applications/external/multi_fuzzer/todo.md b/applications/external/multi_fuzzer/todo.md new file mode 100644 index 000000000..4e3b0e17d --- /dev/null +++ b/applications/external/multi_fuzzer/todo.md @@ -0,0 +1,44 @@ +## Working Improvement + +#### Quality of life + +- [ ] Make the "Load File" independent of the current protocol +- [x] Add pause + - [ ] Switching UIDs if possible +- [x] Led and sound Notification + - [x] Led + - [x] Vibro + - [ ] Sound? +- [x] Error Notification + - [x] Custom UIDs dict loading + - [x] Key file loading + - [ ] Anything else + +#### App functionality + +- [x] Add `BFCustomerID` attack + - [x] Add the ability to select index +- [ ] Save key logic + +## Code Improvement + +- [ ] GUI + - [x] Rewrite `gui_const` logic + - [x] Icon in dialog + - [x] Description and buttons in `field_editor` view + - [ ] Protocol carousel in `main_menu` + - [x] prototype + - [x] Add the ability to edit emulation time and downtime separately + - [x] Decide on the display +- [x] UID + - [x] Simplify the storage and exchange of `uids.data` `uid.data_size` in `views` + - [x] Using `FuzzerPayload` to store the uid + - [x] `UID_MAX_SIZE` +- [x] Add pause + - [x] Fix `Custom dict` attack when ended +- [ ] Pause V2 + - [ ] Save logic + - [ ] Switching UIDs if possible +- [ ] Worker + - [ ] Use `prtocol_id` instead of protocol name + - [x] this can be simplified `fuzzer_proto_items` \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/attack.c b/applications/external/multi_fuzzer/views/attack.c new file mode 100644 index 000000000..87aa9f659 --- /dev/null +++ b/applications/external/multi_fuzzer/views/attack.c @@ -0,0 +1,384 @@ +#include "attack.h" +#include "../fuzzer_i.h" + +#include +#include + +#define ATTACK_SCENE_MAX_UID_LENGTH 25 +#define UID_MAX_DISPLAYED_LEN (8U) +#define LIFT_RIGHT_OFFSET (3) + +struct FuzzerViewAttack { + View* view; + FuzzerViewAttackCallback callback; + void* context; +}; + +typedef struct { + uint8_t time_delay; // 1 = 100ms + uint8_t time_delay_min; // 1 = 100ms + uint8_t emu_time; // 1 = 100ms + uint8_t emu_time_min; // 1 = 100ms + bool td_emt_cursor; // false - time_delay, true - emu_time + const char* attack_name; + const char* protocol_name; + FuzzerAttackState attack_state; + FuriString* uid_str; +} FuzzerViewAttackModel; + +void fuzzer_view_attack_reset_data( + FuzzerViewAttack* view, + const char* attack_name, + const char* protocol_name) { + furi_assert(view); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { + model->attack_name = attack_name; + model->protocol_name = protocol_name; + model->attack_state = FuzzerAttackStateIdle; + furi_string_set_str(model->uid_str, "Not_set"); + }, + true); +} + +void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const FuzzerPayload* uid) { + furi_assert(view); + furi_assert(uid->data); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { + furi_string_printf(model->uid_str, "%02X", uid->data[0]); + for(uint8_t i = 1; i < uid->data_size; i++) { + furi_string_cat_printf(model->uid_str, ":%02X", uid->data[i]); + } + }, + true); +} + +void fuzzer_view_attack_start(FuzzerViewAttack* view) { + furi_assert(view); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { model->attack_state = FuzzerAttackStateRunning; }, + true); +} + +void fuzzer_view_attack_stop(FuzzerViewAttack* view) { + furi_assert(view); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { model->attack_state = FuzzerAttackStateOff; }, + true); +} + +void fuzzer_view_attack_pause(FuzzerViewAttack* view) { + furi_assert(view); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { model->attack_state = FuzzerAttackStateIdle; }, + true); +} + +void fuzzer_view_attack_end(FuzzerViewAttack* view) { + furi_assert(view); + + with_view_model( + view->view, + FuzzerViewAttackModel * model, + { model->attack_state = FuzzerAttackStateEnd; }, + true); +} + +void fuzzer_view_attack_set_callback( + FuzzerViewAttack* view_attack, + FuzzerViewAttackCallback callback, + void* context) { + furi_assert(view_attack); + + view_attack->callback = callback; + view_attack->context = context; +} + +void fuzzer_view_attack_draw(Canvas* canvas, FuzzerViewAttackModel* model) { + char temp_str[50]; + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, model->attack_name); + + uint16_t crt; + canvas_set_font(canvas, FontPrimary); + + if(!model->td_emt_cursor) { + canvas_set_font(canvas, FontSecondary); + snprintf(temp_str, sizeof(temp_str), "Time delay:"); + canvas_draw_str_aligned(canvas, LIFT_RIGHT_OFFSET, 21, AlignLeft, AlignBottom, temp_str); + crt = canvas_string_width(canvas, temp_str); + + canvas_set_font(canvas, FontPrimary); + snprintf( + temp_str, sizeof(temp_str), "%d.%d", model->time_delay / 10, model->time_delay % 10); + canvas_draw_str_aligned( + canvas, crt + LIFT_RIGHT_OFFSET + 3, 21, AlignLeft, AlignBottom, temp_str); + + canvas_set_font(canvas, FontSecondary); + snprintf( + temp_str, sizeof(temp_str), "EmT: %d.%d", model->emu_time / 10, model->emu_time % 10); + canvas_draw_str_aligned( + canvas, 128 - LIFT_RIGHT_OFFSET, 21, AlignRight, AlignBottom, temp_str); + } else { + canvas_set_font(canvas, FontSecondary); + snprintf( + temp_str, + sizeof(temp_str), + "TD: %d.%d", + model->time_delay / 10, + model->time_delay % 10); + + canvas_draw_str_aligned(canvas, LIFT_RIGHT_OFFSET, 21, AlignLeft, AlignBottom, temp_str); + + canvas_set_font(canvas, FontPrimary); + snprintf(temp_str, sizeof(temp_str), "%d.%d", model->emu_time / 10, model->emu_time % 10); + canvas_draw_str_aligned( + canvas, 128 - LIFT_RIGHT_OFFSET, 21, AlignRight, AlignBottom, temp_str); + crt = canvas_string_width(canvas, temp_str); + + canvas_set_font(canvas, FontSecondary); + snprintf(temp_str, sizeof(temp_str), "Emulation time:"); + canvas_draw_str_aligned( + canvas, 128 - LIFT_RIGHT_OFFSET - crt - 3, 21, AlignRight, AlignBottom, temp_str); + } + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignTop, model->protocol_name); + + canvas_set_font(canvas, FontPrimary); + if(128 < canvas_string_width(canvas, furi_string_get_cstr(model->uid_str))) { + canvas_set_font(canvas, FontSecondary); + } + canvas_draw_str_aligned( + canvas, 64, 38, AlignCenter, AlignTop, furi_string_get_cstr(model->uid_str)); + + canvas_set_font(canvas, FontSecondary); + if(model->attack_state == FuzzerAttackStateRunning) { + elements_button_center(canvas, "Stop"); + } else if(model->attack_state == FuzzerAttackStateIdle) { + if(model->td_emt_cursor) { + elements_button_center(canvas, "Start"); + elements_button_left(canvas, "EmT -"); + elements_button_right(canvas, "+ EmT"); + } else { + elements_button_center(canvas, "Start"); + elements_button_left(canvas, "TD -"); + elements_button_right(canvas, "+ TD"); + } + + } else if(model->attack_state == FuzzerAttackStateEnd) { + // elements_button_center(canvas, "Restart"); // Reset + elements_button_left(canvas, "Exit"); + } +} + +bool fuzzer_view_attack_input(InputEvent* event, void* context) { + furi_assert(context); + FuzzerViewAttack* view_attack = context; + + if(event->key == InputKeyBack && event->type == InputTypeShort) { + view_attack->callback(FuzzerCustomEventViewAttackBack, view_attack->context); + return true; + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + view_attack->callback(FuzzerCustomEventViewAttackOk, view_attack->context); + return true; + } else if(event->key == InputKeyLeft) { + with_view_model( + view_attack->view, + FuzzerViewAttackModel * model, + { + if(model->attack_state == FuzzerAttackStateIdle) { + if(!model->td_emt_cursor) { + // TimeDelay -- + if(event->type == InputTypeShort) { + if(model->time_delay > model->time_delay_min) { + model->time_delay--; + } + } else if(event->type == InputTypeLong) { + if((model->time_delay - 10) >= model->time_delay_min) { + model->time_delay -= 10; + } else { + model->time_delay = model->time_delay_min; + } + } + } else { + // EmuTime -- + if(event->type == InputTypeShort) { + if(model->emu_time > model->emu_time_min) { + model->emu_time--; + } + } else if(event->type == InputTypeLong) { + if((model->emu_time - 10) >= model->emu_time_min) { + model->emu_time -= 10; + } else { + model->emu_time = model->emu_time_min; + } + } + } + } else if( + (model->attack_state == FuzzerAttackStateEnd) && + (event->type == InputTypeShort)) { + // Exit if Ended + view_attack->callback(FuzzerCustomEventViewAttackBack, view_attack->context); + } + }, + true); + return true; + } else if(event->key == InputKeyRight) { + with_view_model( + view_attack->view, + FuzzerViewAttackModel * model, + { + if(model->attack_state == FuzzerAttackStateIdle) { + if(!model->td_emt_cursor) { + // TimeDelay ++ + if(event->type == InputTypeShort) { + if(model->time_delay < FUZZ_TIME_DELAY_MAX) { + model->time_delay++; + } + } else if(event->type == InputTypeLong) { + model->time_delay += 10; + if(model->time_delay > FUZZ_TIME_DELAY_MAX) { + model->time_delay = FUZZ_TIME_DELAY_MAX; + } + } + } else { + // EmuTime ++ + if(event->type == InputTypeShort) { + if(model->emu_time < FUZZ_TIME_DELAY_MAX) { + model->emu_time++; + } + } else if(event->type == InputTypeLong) { + model->emu_time += 10; + if(model->emu_time > FUZZ_TIME_DELAY_MAX) { + model->emu_time = FUZZ_TIME_DELAY_MAX; + } + } + } + } else { + // Nothing + } + }, + true); + return true; + } else if( + (event->key == InputKeyUp || event->key == InputKeyDown) && + event->type == InputTypeShort) { + with_view_model( + view_attack->view, + FuzzerViewAttackModel * model, + { model->td_emt_cursor = !model->td_emt_cursor; }, + true); + return true; + } + + return true; +} + +void fuzzer_view_attack_enter(void* context) { + furi_assert(context); +} + +void fuzzer_view_attack_exit(void* context) { + furi_assert(context); + FuzzerViewAttack* view_attack = context; + with_view_model( + view_attack->view, FuzzerViewAttackModel * model, { model->td_emt_cursor = false; }, true); +} + +FuzzerViewAttack* fuzzer_view_attack_alloc() { + if(fuzzer_proto_get_max_data_size() > UID_MAX_DISPLAYED_LEN) { + furi_crash("Maximum of displayed bytes exceeded"); + } + + FuzzerViewAttack* view_attack = malloc(sizeof(FuzzerViewAttack)); + + // View allocation and configuration + view_attack->view = view_alloc(); + view_allocate_model(view_attack->view, ViewModelTypeLocking, sizeof(FuzzerViewAttackModel)); + view_set_context(view_attack->view, view_attack); + view_set_draw_callback(view_attack->view, (ViewDrawCallback)fuzzer_view_attack_draw); + view_set_input_callback(view_attack->view, fuzzer_view_attack_input); + view_set_enter_callback(view_attack->view, fuzzer_view_attack_enter); + view_set_exit_callback(view_attack->view, fuzzer_view_attack_exit); + + with_view_model( + view_attack->view, + FuzzerViewAttackModel * model, + { + model->time_delay = fuzzer_proto_get_def_idle_time(); + model->time_delay_min = 0; // model->time_delay; + + model->emu_time = fuzzer_proto_get_def_emu_time(); + + model->emu_time_min = 2; // model->emu_time; + + model->uid_str = furi_string_alloc_set_str("Not_set"); + // malloc(ATTACK_SCENE_MAX_UID_LENGTH + 1); + model->attack_state = FuzzerAttackStateOff; + model->td_emt_cursor = false; + + // strcpy(model->uid_str, "Not_set"); + model->attack_name = "Not_set"; + model->protocol_name = "Not_set"; + }, + true); + return view_attack; +} + +void fuzzer_view_attack_free(FuzzerViewAttack* view_attack) { + furi_assert(view_attack); + + with_view_model( + view_attack->view, + FuzzerViewAttackModel * model, + { furi_string_free(model->uid_str); }, + true); + view_free(view_attack->view); + free(view_attack); +} + +View* fuzzer_view_attack_get_view(FuzzerViewAttack* view_attack) { + furi_assert(view_attack); + return view_attack->view; +} + +uint8_t fuzzer_view_attack_get_time_delay(FuzzerViewAttack* view) { + furi_assert(view); + uint8_t time_delay; + + with_view_model( + view->view, FuzzerViewAttackModel * model, { time_delay = model->time_delay; }, false); + + return time_delay; +} + +uint8_t fuzzer_view_attack_get_emu_time(FuzzerViewAttack* view) { + furi_assert(view); + uint8_t emu_time; + + with_view_model( + view->view, FuzzerViewAttackModel * model, { emu_time = model->emu_time; }, false); + + return emu_time; +} \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/attack.h b/applications/external/multi_fuzzer/views/attack.h new file mode 100644 index 000000000..66e96d7d6 --- /dev/null +++ b/applications/external/multi_fuzzer/views/attack.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include "../helpers/fuzzer_custom_event.h" +#include "../helpers/fuzzer_types.h" + +#include "../lib/worker/protocol.h" + +typedef struct FuzzerViewAttack FuzzerViewAttack; + +typedef void (*FuzzerViewAttackCallback)(FuzzerCustomEvent event, void* context); + +void fuzzer_view_attack_set_callback( + FuzzerViewAttack* view_attack, + FuzzerViewAttackCallback callback, + void* context); + +FuzzerViewAttack* fuzzer_view_attack_alloc(); + +void fuzzer_view_attack_free(FuzzerViewAttack* view_attack); + +View* fuzzer_view_attack_get_view(FuzzerViewAttack* view_attack); + +void fuzzer_view_attack_reset_data( + FuzzerViewAttack* view, + const char* attack_name, + const char* protocol_name); + +void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const FuzzerPayload* uid); + +void fuzzer_view_attack_start(FuzzerViewAttack* view); + +void fuzzer_view_attack_stop(FuzzerViewAttack* view); + +void fuzzer_view_attack_pause(FuzzerViewAttack* view); + +void fuzzer_view_attack_end(FuzzerViewAttack* view); + +uint8_t fuzzer_view_attack_get_time_delay(FuzzerViewAttack* view); + +uint8_t fuzzer_view_attack_get_emu_time(FuzzerViewAttack* view); \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/field_editor.c b/applications/external/multi_fuzzer/views/field_editor.c new file mode 100644 index 000000000..bdce0a516 --- /dev/null +++ b/applications/external/multi_fuzzer/views/field_editor.c @@ -0,0 +1,358 @@ +#include "field_editor.h" +#include "../fuzzer_i.h" + +#include +#include +#include + +#define FIELD_EDITOR_V2 + +#define GUI_DISPLAY_WIDTH 128 +#define GUI_DISPLAY_HEIGHT 64 + +#define GUI_DISPLAY_HORIZONTAL_CENTER 64 +#define GUI_DISPLAY_VERTICAL_CENTER 32 + +#define UID_STR_LENGTH 25 + +#ifdef FIELD_EDITOR_V2 +#define EDITOR_STRING_Y 38 +#else +#define EDITOR_STRING_Y 50 +#endif + +struct FuzzerViewFieldEditor { + View* view; + FuzzerViewFieldEditorCallback callback; + void* context; +}; + +typedef struct { + uint8_t* uid; + uint8_t uid_size; + + FuriString* uid_str; + + uint8_t index; + bool lo; + bool allow_edit; +} FuzzerViewFieldEditorModel; + +void fuzzer_view_field_editor_set_callback( + FuzzerViewFieldEditor* view_edit, + FuzzerViewFieldEditorCallback callback, + void* context) { + furi_assert(view_edit); + + view_edit->callback = callback; + view_edit->context = context; +} + +void fuzzer_view_field_editor_reset_data( + FuzzerViewFieldEditor* view_edit, + const FuzzerPayload* new_uid, + bool allow_edit) { + furi_assert(view_edit); + furi_assert(new_uid->data); + + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + memcpy(model->uid, new_uid->data, new_uid->data_size); + model->index = 0; + model->lo = false; + model->uid_size = new_uid->data_size; + model->allow_edit = allow_edit; + }, + true); +} + +void fuzzer_view_field_editor_get_uid(FuzzerViewFieldEditor* view_edit, FuzzerPayload* output_uid) { + furi_assert(view_edit); + furi_assert(output_uid); + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + output_uid->data_size = model->uid_size; + memcpy(output_uid->data, model->uid, model->uid_size); + }, + true); +} + +uint8_t fuzzer_view_field_editor_get_index(FuzzerViewFieldEditor* view_edit) { + furi_assert(view_edit); + uint8_t index; + with_view_model( + view_edit->view, FuzzerViewFieldEditorModel * model, { index = model->index; }, true); + return index; +} + +void fuzzer_view_field_editor_draw(Canvas* canvas, FuzzerViewFieldEditorModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + +#ifdef FIELD_EDITOR_V2 + + canvas_set_font(canvas, FontSecondary); + if(model->allow_edit) { + canvas_draw_icon(canvas, 2, 4, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 8, 4, &I_ButtonRight_4x7); + + canvas_draw_icon_ex(canvas, 62, 3, &I_Pin_arrow_up_7x9, IconRotation180); + canvas_draw_icon(canvas, 69, 3, &I_Pin_arrow_up_7x9); + + canvas_draw_str(canvas, 14, 10, "select byte"); + canvas_draw_str(canvas, 79, 10, "adjust byte"); + } else { + canvas_draw_icon(canvas, 35, 4, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 41, 4, &I_ButtonRight_4x7); + canvas_draw_str(canvas, 49, 10, "select byte"); + } + + char msg_index[18]; + canvas_set_font(canvas, FontPrimary); + snprintf(msg_index, sizeof(msg_index), "Field index : %d", model->index); + + canvas_draw_str_aligned( + canvas, GUI_DISPLAY_HORIZONTAL_CENTER, 24, AlignCenter, AlignBottom, msg_index); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_icon(canvas, 4, 52, &I_Pin_back_arrow_10x8); + canvas_draw_icon(canvas, 85, 52, &I_Ok_btn_9x9); + + canvas_draw_str(canvas, 16, 60, "Back"); + canvas_draw_str(canvas, 96, 60, "Attack"); +#else + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, + GUI_DISPLAY_HORIZONTAL_CENTER, + 5, + AlignCenter, + AlignTop, + "Left and right: select byte"); + canvas_draw_str_aligned( + canvas, + GUI_DISPLAY_HORIZONTAL_CENTER, + 15, + AlignCenter, + AlignTop, + "Up and down: adjust byte"); + + char msg_index[18]; + canvas_set_font(canvas, FontPrimary); + snprintf(msg_index, sizeof(msg_index), "Field index : %d", model->index); + canvas_draw_str_aligned( + canvas, GUI_DISPLAY_HORIZONTAL_CENTER, 28, AlignCenter, AlignTop, msg_index); +#endif + // ####### Editor ####### + FuriString* temp_s = model->uid_str; + canvas_set_font(canvas, FontSecondary); + + furi_string_reset(temp_s); + for(int i = -3; i != 0; i++) { + if(0 <= (model->index + i)) { + furi_string_cat_printf(temp_s, "%02X ", model->uid[model->index + i]); + } + } + canvas_draw_str_aligned( + canvas, 52, EDITOR_STRING_Y, AlignRight, AlignBottom, furi_string_get_cstr(temp_s)); + + furi_string_reset(temp_s); + for(int i = 1; i != 4; i++) { + if((model->index + i) < model->uid_size) { + furi_string_cat_printf(temp_s, " %02X", model->uid[model->index + i]); + } + } + canvas_draw_str_aligned( + canvas, 77, EDITOR_STRING_Y, AlignLeft, AlignBottom, furi_string_get_cstr(temp_s)); + + canvas_set_font(canvas, FontPrimary); + + furi_string_reset(temp_s); + furi_string_cat_printf(temp_s, "<%02X>", model->uid[model->index]); + canvas_draw_str_aligned( + canvas, + GUI_DISPLAY_HORIZONTAL_CENTER, + EDITOR_STRING_Y, + AlignCenter, + AlignBottom, + furi_string_get_cstr(temp_s)); + + uint16_t w = canvas_string_width(canvas, furi_string_get_cstr(temp_s)); + w -= 11; // '<' & '>' + w /= 2; + + if(model->allow_edit) { + if(model->lo) { + canvas_draw_line( + canvas, + GUI_DISPLAY_HORIZONTAL_CENTER + 1, + EDITOR_STRING_Y + 2, + GUI_DISPLAY_HORIZONTAL_CENTER + w, + EDITOR_STRING_Y + 2); + } else { + canvas_draw_line( + canvas, + GUI_DISPLAY_HORIZONTAL_CENTER - w, + EDITOR_STRING_Y + 2, + GUI_DISPLAY_HORIZONTAL_CENTER - 1, + EDITOR_STRING_Y + 2); + } + } else { + // canvas_draw_line( + // canvas, + // GUI_DISPLAY_HORIZONTAL_CENTER - w, + // EDITOR_STRING_Y + 2, + // GUI_DISPLAY_HORIZONTAL_CENTER + w, + // EDITOR_STRING_Y + 2); + } + // ####### Editor ####### +} + +bool fuzzer_view_field_editor_input(InputEvent* event, void* context) { + furi_assert(context); + FuzzerViewFieldEditor* view_edit = context; + + if(event->key == InputKeyBack && event->type == InputTypeShort) { + view_edit->callback(FuzzerCustomEventViewFieldEditorBack, view_edit->context); + return true; + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + view_edit->callback(FuzzerCustomEventViewFieldEditorOk, view_edit->context); + return true; + } else if(event->key == InputKeyLeft) { + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + if(event->type == InputTypeShort) { + if(!model->allow_edit) { + model->lo = false; + } + if(model->index > 0 || model->lo) { + if(!model->lo) { + model->index--; + } + model->lo = !model->lo; + } + } else if(event->type == InputTypeLong) { + model->index = 0; + model->lo = false; + } + }, + true); + return true; + } else if(event->key == InputKeyRight) { + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + if(event->type == InputTypeShort) { + if(!model->allow_edit) { + model->lo = true; + } + if(model->index < (model->uid_size - 1) || !model->lo) { + if(model->lo) { + model->index++; + } + model->lo = !model->lo; + } + } else if(event->type == InputTypeLong) { + model->index = model->uid_size - 1; + model->lo = true; + } + }, + true); + return true; + } else if(event->key == InputKeyUp) { + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + if(event->type == InputTypeShort && model->allow_edit) { + if(model->lo) { + model->uid[model->index] = (model->uid[model->index] & 0xF0) | + ((model->uid[model->index] + 1) & 0x0F); + } else { + model->uid[model->index] = ((model->uid[model->index] + 0x10) & 0xF0) | + (model->uid[model->index] & 0x0F); + } + } + }, + true); + return true; + } else if(event->key == InputKeyDown) { + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + if(event->type == InputTypeShort && model->allow_edit) { + if(model->lo) { + model->uid[model->index] = (model->uid[model->index] & 0xF0) | + ((model->uid[model->index] - 1) & 0x0F); + } else { + model->uid[model->index] = ((model->uid[model->index] - 0x10) & 0xF0) | + (model->uid[model->index] & 0x0F); + } + } + }, + true); + return true; + } + + return true; +} + +void fuzzer_view_field_editor_enter(void* context) { + furi_assert(context); +} + +void fuzzer_view_field_editor_exit(void* context) { + furi_assert(context); +} + +FuzzerViewFieldEditor* fuzzer_view_field_editor_alloc() { + FuzzerViewFieldEditor* view_edit = malloc(sizeof(FuzzerViewFieldEditor)); + + // View allocation and configuration + view_edit->view = view_alloc(); + view_allocate_model(view_edit->view, ViewModelTypeLocking, sizeof(FuzzerViewFieldEditorModel)); + view_set_context(view_edit->view, view_edit); + view_set_draw_callback(view_edit->view, (ViewDrawCallback)fuzzer_view_field_editor_draw); + view_set_input_callback(view_edit->view, fuzzer_view_field_editor_input); + view_set_enter_callback(view_edit->view, fuzzer_view_field_editor_enter); + view_set_exit_callback(view_edit->view, fuzzer_view_field_editor_exit); + + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + model->uid_str = furi_string_alloc(); + model->uid = malloc(fuzzer_proto_get_max_data_size()); + }, + true); + + return view_edit; +} + +void fuzzer_view_field_editor_free(FuzzerViewFieldEditor* view_edit) { + furi_assert(view_edit); + + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + furi_string_free(model->uid_str); + free(model->uid); + }, + true); + view_free(view_edit->view); + free(view_edit); +} + +View* fuzzer_view_field_editor_get_view(FuzzerViewFieldEditor* view_edit) { + furi_assert(view_edit); + return view_edit->view; +} \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/field_editor.h b/applications/external/multi_fuzzer/views/field_editor.h new file mode 100644 index 000000000..d81538bf8 --- /dev/null +++ b/applications/external/multi_fuzzer/views/field_editor.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include "../helpers/fuzzer_custom_event.h" +#include "../lib/worker/protocol.h" + +typedef struct FuzzerViewFieldEditor FuzzerViewFieldEditor; + +typedef void (*FuzzerViewFieldEditorCallback)(FuzzerCustomEvent event, void* context); + +void fuzzer_view_field_editor_set_callback( + FuzzerViewFieldEditor* view_attack, + FuzzerViewFieldEditorCallback callback, + void* context); + +FuzzerViewFieldEditor* fuzzer_view_field_editor_alloc(); + +void fuzzer_view_field_editor_free(FuzzerViewFieldEditor* view_attack); + +View* fuzzer_view_field_editor_get_view(FuzzerViewFieldEditor* view_attack); + +void fuzzer_view_field_editor_reset_data( + FuzzerViewFieldEditor* view_edit, + const FuzzerPayload* new_uid, + bool allow_edit); + +void fuzzer_view_field_editor_get_uid(FuzzerViewFieldEditor* view_edit, FuzzerPayload* output_uid); + +uint8_t fuzzer_view_field_editor_get_index(FuzzerViewFieldEditor* view_edit); \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/main_menu.c b/applications/external/multi_fuzzer/views/main_menu.c new file mode 100644 index 000000000..14422145b --- /dev/null +++ b/applications/external/multi_fuzzer/views/main_menu.c @@ -0,0 +1,235 @@ +#include "main_menu.h" +#include "../fuzzer_i.h" + +#include + +#include "../lib/worker/protocol.h" + +#define PROTOCOL_NAME_Y 12 +// #define PROTOCOL_CAROUSEL + +struct FuzzerViewMain { + View* view; + FuzzerViewMainCallback callback; + void* context; +}; + +typedef struct { + uint8_t proto_index; + uint8_t menu_index; + uint8_t proto_max; + uint8_t menu_max; +} FuzzerViewMainModel; + +void fuzzer_view_main_update_data(FuzzerViewMain* view, FuzzerState state) { + furi_assert(view); + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + model->proto_index = state.proto_index; + model->menu_index = state.menu_index; + }, + true); +} + +void fuzzer_view_main_get_state(FuzzerViewMain* view, FuzzerState* state) { + furi_assert(view); + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + state->proto_index = model->proto_index; + state->menu_index = model->menu_index; + }, + true); +} + +void fuzzer_view_main_set_callback( + FuzzerViewMain* view, + FuzzerViewMainCallback callback, + void* context) { + furi_assert(view); + + view->callback = callback; + view->context = context; +} + +void fuzzer_view_main_draw(Canvas* canvas, FuzzerViewMainModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + + if(model->menu_index > 0) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, + 64, + 24, + AlignCenter, + AlignTop, + fuzzer_proto_get_menu_label(model->menu_index - 1)); + } + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned( + canvas, 64, 36, AlignCenter, AlignTop, fuzzer_proto_get_menu_label(model->menu_index)); + + if(model->menu_index < (model->menu_max - 1)) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, + 64, + 48, + AlignCenter, + AlignTop, + fuzzer_proto_get_menu_label(model->menu_index + 1)); + } + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 27, PROTOCOL_NAME_Y, AlignCenter, AlignBottom, "<"); + canvas_draw_str_aligned( + canvas, + 64, + PROTOCOL_NAME_Y, + AlignCenter, + AlignBottom, + fuzzer_proto_get_name(model->proto_index)); + canvas_draw_str_aligned(canvas, 101, PROTOCOL_NAME_Y, AlignCenter, AlignBottom, ">"); + +#ifdef PROTOCOL_CAROUSEL + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned( + canvas, + 20, + PROTOCOL_NAME_Y, + AlignRight, + AlignBottom, + (model->proto_index > 0) ? fuzzer_proto_get_name(model->proto_index - 1) : + fuzzer_proto_get_name((model->proto_max - 1))); + canvas_draw_str_aligned( + canvas, + 108, + PROTOCOL_NAME_Y, + AlignLeft, + AlignBottom, + (model->proto_index < (model->proto_max - 1)) ? + fuzzer_proto_get_name(model->proto_index + 1) : + fuzzer_proto_get_name(0)); +#endif +} + +bool fuzzer_view_main_input(InputEvent* event, void* context) { + furi_assert(context); + FuzzerViewMain* view = context; + + if(event->key == InputKeyBack && + (event->type == InputTypeLong || event->type == InputTypeShort)) { + view->callback(FuzzerCustomEventViewMainBack, view->context); + return true; + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + view->callback(FuzzerCustomEventViewMainOk, view->context); + return true; + } else if(event->key == InputKeyDown && event->type == InputTypeShort) { + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + if(model->menu_index < (model->menu_max - 1)) { + model->menu_index++; + } + }, + true); + return true; + } else if(event->key == InputKeyUp && event->type == InputTypeShort) { + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + if(model->menu_index != 0) { + model->menu_index--; + } + }, + true); + return true; + } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + if(model->proto_index != 0) { + model->proto_index--; + } else { + model->proto_index = (model->proto_max - 1); + } + }, + true); + return true; + } else if(event->key == InputKeyRight && event->type == InputTypeShort) { + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + if(model->proto_index == (model->proto_max - 1)) { + model->proto_index = 0; + } else { + model->proto_index++; + } + }, + true); + return true; + } + + return true; +} + +void fuzzer_view_main_enter(void* context) { + furi_assert(context); +} + +void fuzzer_view_main_exit(void* context) { + furi_assert(context); +} + +FuzzerViewMain* fuzzer_view_main_alloc() { + FuzzerViewMain* view = malloc(sizeof(FuzzerViewMain)); + + // View allocation and configuration + view->view = view_alloc(); + view_allocate_model(view->view, ViewModelTypeLocking, sizeof(FuzzerViewMainModel)); + view_set_context(view->view, view); + view_set_draw_callback(view->view, (ViewDrawCallback)fuzzer_view_main_draw); + view_set_input_callback(view->view, fuzzer_view_main_input); + view_set_enter_callback(view->view, fuzzer_view_main_enter); + view_set_exit_callback(view->view, fuzzer_view_main_exit); + + with_view_model( + view->view, + FuzzerViewMainModel * model, + { + model->proto_index = 0; + model->proto_max = fuzzer_proto_get_count_of_protocols(); + model->menu_index = 0; + model->menu_max = fuzzer_proto_get_count_of_menu_items(); + }, + true); + return view; +} + +void fuzzer_view_main_free(FuzzerViewMain* view) { + furi_assert(view); + + // with_view_model( + // view->view, + // FuzzerViewMainModel * model, + // { + + // }, + // true); + view_free(view->view); + free(view); +} + +View* fuzzer_view_main_get_view(FuzzerViewMain* view) { + furi_assert(view); + return view->view; +} \ No newline at end of file diff --git a/applications/external/multi_fuzzer/views/main_menu.h b/applications/external/multi_fuzzer/views/main_menu.h new file mode 100644 index 000000000..262d54405 --- /dev/null +++ b/applications/external/multi_fuzzer/views/main_menu.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include "../helpers/fuzzer_custom_event.h" +#include "../helpers/fuzzer_types.h" + +typedef struct FuzzerViewMain FuzzerViewMain; + +typedef void (*FuzzerViewMainCallback)(FuzzerCustomEvent event, void* context); + +void fuzzer_view_main_set_callback( + FuzzerViewMain* fuzzer_view_main, + FuzzerViewMainCallback callback, + void* context); + +FuzzerViewMain* fuzzer_view_main_alloc(); + +void fuzzer_view_main_free(FuzzerViewMain* view); + +View* fuzzer_view_main_get_view(FuzzerViewMain* view); + +void fuzzer_view_main_update_data(FuzzerViewMain* view, FuzzerState state); +void fuzzer_view_main_get_state(FuzzerViewMain* view, FuzzerState* state); \ No newline at end of file diff --git a/applications/external/protoview/signal_file.c b/applications/external/protoview/signal_file.c index c60a6a181..886573a06 100644 --- a/applications/external/protoview/signal_file.c +++ b/applications/external/protoview/signal_file.c @@ -48,8 +48,9 @@ bool save_signal(ProtoViewApp* app, const char* filename) { for(int j = 0; regs[j]; j += 2) { furi_string_cat_printf(custom, "%02X %02X ", (int)regs[j], (int)regs[j + 1]); } - size_t len = furi_string_size(file_content); - furi_string_set_char(custom, len - 1, '\n'); + //size_t len = furi_string_size(file_content); + //furi_string_set_char(custom, len - 1, '\n'); + furi_string_cat(custom, "\n"); furi_string_cat(file_content, custom); furi_string_free(custom); } diff --git a/applications/external/unitemp/Sensors.c b/applications/external/unitemp/Sensors.c index 666438bfa..ae90ce4d5 100644 --- a/applications/external/unitemp/Sensors.c +++ b/applications/external/unitemp/Sensors.c @@ -78,7 +78,8 @@ const Interface SPI = { static const SensorType* sensorTypes[] = {&DHT11, &DHT12_SW, &DHT20, &DHT21, &DHT22, &Dallas, &AM2320_SW, &AM2320_I2C, &HTU21x, &AHT10, &SHT30, &GXHT30, &LM75, &HDC1080, &BMP180, - &BMP280, &BME280, &BME680, &MAX31855, &MAX6675}; + &BMP280, &BME280, &BME680, &MAX31855, &MAX6675, + &SCD30}; const SensorType* unitemp_sensors_getTypeFromInt(uint8_t index) { if(index > SENSOR_TYPES_COUNT) return NULL; diff --git a/applications/external/unitemp/Sensors.h b/applications/external/unitemp/Sensors.h index d2b7c07af..25b9cb49e 100644 --- a/applications/external/unitemp/Sensors.h +++ b/applications/external/unitemp/Sensors.h @@ -24,6 +24,7 @@ #define UT_TEMPERATURE 0b00000001 #define UT_HUMIDITY 0b00000010 #define UT_PRESSURE 0b00000100 +#define UT_CO2 0b00001000 //Статусы опроса датчика typedef enum { @@ -31,6 +32,7 @@ typedef enum { UT_DATA_TYPE_TEMP_HUM = UT_TEMPERATURE | UT_HUMIDITY, UT_DATA_TYPE_TEMP_PRESS = UT_TEMPERATURE | UT_PRESSURE, UT_DATA_TYPE_TEMP_HUM_PRESS = UT_TEMPERATURE | UT_HUMIDITY | UT_PRESSURE, + UT_DATA_TYPE_TEMP_HUM_CO2 = UT_TEMPERATURE | UT_HUMIDITY | UT_CO2, } SensorDataType; //Типы возвращаемых данных @@ -121,6 +123,8 @@ typedef struct Sensor { float hum; //Атмосферное давление float pressure; + // Концентрация CO2 + float co2; //Тип датчика const SensorType* type; //Статус последнего опроса датчика @@ -329,4 +333,5 @@ const GPIO* #include "./sensors/HDC1080.h" #include "./sensors/MAX31855.h" #include "./sensors/MAX6675.h" +#include "./sensors/SCD30.h" #endif diff --git a/applications/external/unitemp/assets/co2_11x14.png b/applications/external/unitemp/assets/co2_11x14.png new file mode 100644 index 000000000..2a2b5e068 Binary files /dev/null and b/applications/external/unitemp/assets/co2_11x14.png differ diff --git a/applications/external/unitemp/sensors/SCD30.c b/applications/external/unitemp/sensors/SCD30.c new file mode 100644 index 000000000..627130da7 --- /dev/null +++ b/applications/external/unitemp/sensors/SCD30.c @@ -0,0 +1,438 @@ +/* + Unitemp - Universal temperature reader + Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n) + Contributed by divinebird (https://github.com/divinebird) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// Some information may be seen on https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library + +#include "SCD30.h" +#include "../interfaces/I2CSensor.h" +//#include <3rdparty/everest/include/everest/kremlin/c_endianness.h> + +inline static uint16_t load16(uint8_t* b) { + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t load32(uint8_t* b) { + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static void store16(uint8_t* b, uint16_t i) { + memcpy(b, &i, 2); +} + +inline static void store32(uint8_t* b, uint32_t i) { + memcpy(b, &i, 4); +} + +#if BYTE_ORDER == BIG_ENDIAN +#define htobe16(x) (x) +#define htobe32(x) (x) +#define htole16(x) __builtin_bswap16(x) +#define htole32(x) __builtin_bswap32(x) +#define be16toh(x) (x) +#define be32toh(x) (x) +#define le16toh(x) __builtin_bswap16(x) +#define le32toh(x) __builtin_bswap32(x) +#elif BYTE_ORDER == LITTLE_ENDIAN +#define htobe16(x) __builtin_bswap16(x) +#define htobe32(x) __builtin_bswap32(x) +#define htole16(x) (x) +#define htole32(x) (x) +#define be16toh(x) __builtin_bswap16(x) +#define be32toh(x) __builtin_bswap32(x) +#define le16toh(x) (x) +#define le32toh(x) (x) +#else +#error "What kind of system is this?" +#endif + +#define load16_le(b) (le16toh(load16(b))) +#define load32_le(b) (le32toh(load32(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define store32_le(b, i) (store32(b, htole32(i))) + +#define load16_be(b) (be16toh(load16(b))) +#define load32_be(b) (be32toh(load32(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +typedef union { + uint16_t array16[2]; + uint8_t array8[4]; + float value; +} ByteToFl; + +bool unitemp_SCD30_alloc(Sensor* sensor, char* args); +bool unitemp_SCD30_init(Sensor* sensor); +bool unitemp_SCD30_deinit(Sensor* sensor); +UnitempStatus unitemp_SCD30_update(Sensor* sensor); +bool unitemp_SCD30_free(Sensor* sensor); + +const SensorType SCD30 = { + .typename = "SCD30", + .interface = &I2C, + .datatype = UT_DATA_TYPE_TEMP_HUM_CO2, + .pollingInterval = 2000, + .allocator = unitemp_SCD30_alloc, + .mem_releaser = unitemp_SCD30_free, + .initializer = unitemp_SCD30_init, + .deinitializer = unitemp_SCD30_deinit, + .updater = unitemp_SCD30_update}; + +#define SCD30_ID 0x61 + +#define COMMAND_CONTINUOUS_MEASUREMENT 0x0010 +#define COMMAND_SET_MEASUREMENT_INTERVAL 0x4600 +#define COMMAND_GET_DATA_READY 0x0202 +#define COMMAND_READ_MEASUREMENT 0x0300 +#define COMMAND_AUTOMATIC_SELF_CALIBRATION 0x5306 +#define COMMAND_SET_FORCED_RECALIBRATION_FACTOR 0x5204 +#define COMMAND_SET_TEMPERATURE_OFFSET 0x5403 +#define COMMAND_SET_ALTITUDE_COMPENSATION 0x5102 +#define COMMAND_RESET 0xD304 // Soft reset +#define COMMAND_STOP_MEAS 0x0104 +#define COMMAND_READ_FW_VER 0xD100 + +static bool dataAvailable(Sensor* sensor) __attribute__((unused)); +static bool readMeasurement(Sensor* sensor) __attribute__((unused)); +static void reset(Sensor* sensor) __attribute__((unused)); + +static bool setAutoSelfCalibration(Sensor* sensor, bool enable) __attribute__((unused)); +static bool getAutoSelfCalibration(Sensor* sensor) __attribute__((unused)); + +static bool getFirmwareVersion(Sensor* sensor, uint16_t* val) __attribute__((unused)); + +static bool setForcedRecalibrationFactor(Sensor* sensor, uint16_t concentration) + __attribute__((unused)); +static uint16_t getAltitudeCompensation(Sensor* sensor) __attribute__((unused)); +static bool setAltitudeCompensation(Sensor* sensor, uint16_t altitude) __attribute__((unused)); +static bool setAmbientPressure(Sensor* sensor, uint16_t pressure_mbar) __attribute__((unused)); + +static float getTemperatureOffset(Sensor* sensor) __attribute__((unused)); +static bool setTemperatureOffset(Sensor* sensor, float tempOffset) __attribute__((unused)); + +static bool beginMeasuringWithSettings(Sensor* sensor, uint16_t pressureOffset) + __attribute__((unused)); +static bool beginMeasuring(Sensor* sensor) __attribute__((unused)); +static bool stopMeasurement(Sensor* sensor) __attribute__((unused)); + +static bool setMeasurementInterval(Sensor* sensor, uint16_t interval) __attribute__((unused)); +static uint16_t getMeasurementInterval(Sensor* sensor) __attribute__((unused)); + +bool unitemp_SCD30_alloc(Sensor* sensor, char* args) { + UNUSED(args); + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + + i2c_sensor->minI2CAdr = SCD30_ID << 1; + i2c_sensor->maxI2CAdr = SCD30_ID << 1; + return true; +} + +bool unitemp_SCD30_free(Sensor* sensor) { + //Нечего высвобождать, так как ничего не было выделено + UNUSED(sensor); + return true; +} + +bool unitemp_SCD30_init(Sensor* sensor) { + if(beginMeasuring(sensor) == true) { // Start continuous measurements + setMeasurementInterval(sensor, SCD30.pollingInterval / 1000); + setAutoSelfCalibration(sensor, true); + setAmbientPressure(sensor, 0); + } else + return false; + + return true; +} + +bool unitemp_SCD30_deinit(Sensor* sensor) { + return stopMeasurement(sensor); +} + +UnitempStatus unitemp_SCD30_update(Sensor* sensor) { + readMeasurement(sensor); + return UT_SENSORSTATUS_OK; +} + +static uint8_t computeCRC8(uint8_t* message, uint8_t len) { + uint8_t crc = 0xFF; // Init with 0xFF + for(uint8_t x = 0; x < len; x++) { + crc ^= message[x]; // XOR-in the next input byte + for(uint8_t i = 0; i < 8; i++) { + if((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ 0x31); + else + crc <<= 1; + } + } + return crc; // No output reflection +} + +// Sends a command along with arguments and CRC +static bool sendCommandWithCRC(Sensor* sensor, uint16_t command, uint16_t arguments) { + static const uint8_t cmdSize = 5; + + uint8_t bytes[cmdSize]; + uint8_t* pointer = bytes; + store16_be(pointer, command); + pointer += 2; + uint8_t* argPos = pointer; + store16_be(pointer, arguments); + pointer += 2; + *pointer = computeCRC8(argPos, pointer - argPos); + + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + return unitemp_i2c_writeArray(i2c_sensor, cmdSize, bytes); +} + +// Sends just a command, no arguments, no CRC +static bool sendCommand(Sensor* sensor, uint16_t command) { + static const uint8_t cmdSize = 2; + + uint8_t bytes[cmdSize]; + store16_be(bytes, command); + + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + return unitemp_i2c_writeArray(i2c_sensor, cmdSize, bytes); +} + +static uint16_t readRegister(Sensor* sensor, uint16_t registerAddress) { + static const uint8_t regSize = 2; + + if(!sendCommand(sensor, registerAddress)) return 0; // Sensor did not ACK + + furi_delay_ms(3); + + uint8_t bytes[regSize]; + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + if(!unitemp_i2c_readArray(i2c_sensor, regSize, bytes)) return 0; + + return load16_be(bytes); +} + +static bool loadWord(uint8_t* buff, uint16_t* val) { + uint16_t tmp = load16_be(buff); + uint8_t expectedCRC = computeCRC8(buff, 2); + if(buff[2] != expectedCRC) return false; + *val = tmp; + return true; +} + +static bool getSettingValue(Sensor* sensor, uint16_t registerAddress, uint16_t* val) { + static const uint8_t respSize = 3; + + if(!sendCommand(sensor, registerAddress)) return false; // Sensor did not ACK + + furi_delay_ms(3); + + uint8_t bytes[respSize]; + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + if(!unitemp_i2c_readArray(i2c_sensor, respSize, bytes)) return false; + + return loadWord(bytes, val); +} + +static bool loadFloat(uint8_t* buff, float* val) { + // ByteToFl tmp; + size_t cntr = 0; + uint8_t floatBuff[4]; + for(size_t i = 0; i < 2; i++) { + floatBuff[cntr++] = buff[0]; + floatBuff[cntr++] = buff[1]; + uint8_t expectedCRC = computeCRC8(buff, 2); + if(buff[2] != expectedCRC) return false; + buff += 3; + } + uint32_t tmpVal = load32_be(floatBuff); + memcpy(val, &tmpVal, sizeof(float)); + return true; +} + +// Get 18 bytes from SCD30 +// Updates global variables with floats +// Returns true if success +static bool readMeasurement(Sensor* sensor) { + // Verify we have data from the sensor + if(!dataAvailable(sensor)) { + return false; + } + + if(!sendCommand(sensor, COMMAND_READ_MEASUREMENT)) { + FURI_LOG_E(APP_NAME, "Sensor did not ACK"); + return false; // Sensor did not ACK + } + + float tempCO2 = 0; + float tempHumidity = 0; + float tempTemperature = 0; + + furi_delay_ms(3); + + static const uint8_t respSize = 18; + uint8_t buff[respSize]; + uint8_t* bytes = buff; + I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance; + if(!unitemp_i2c_readArray(i2c_sensor, respSize, bytes)) { + FURI_LOG_E(APP_NAME, "Error while read measures"); + return false; + } + + bool error = false; + if(loadFloat(bytes, &tempCO2)) { + sensor->co2 = tempCO2; + } else { + FURI_LOG_E(APP_NAME, "Error while parsing CO2"); + error = true; + } + + bytes += 6; + if(loadFloat(bytes, &tempTemperature)) { + sensor->temp = tempTemperature; + } else { + FURI_LOG_E(APP_NAME, "Error while parsing temp"); + error = true; + } + + bytes += 6; + if(loadFloat(bytes, &tempHumidity)) { + sensor->hum = tempHumidity; + } else { + FURI_LOG_E(APP_NAME, "Error while parsing humidity"); + error = true; + } + + return !error; +} + +static void reset(Sensor* sensor) { + sendCommand(sensor, COMMAND_RESET); +} + +static bool setAutoSelfCalibration(Sensor* sensor, bool enable) { + return sendCommandWithCRC( + sensor, COMMAND_AUTOMATIC_SELF_CALIBRATION, enable); // Activate continuous ASC +} + +// Get the current ASC setting +static bool getAutoSelfCalibration(Sensor* sensor) { + return 1 == readRegister(sensor, COMMAND_AUTOMATIC_SELF_CALIBRATION); +} + +static bool getFirmwareVersion(Sensor* sensor, uint16_t* val) { + return getSettingValue(sensor, COMMAND_READ_FW_VER, val); +} + +// Set the forced recalibration factor. See 1.3.7. +// The reference CO2 concentration has to be within the range 400 ppm ≤ cref(CO2) ≤ 2000 ppm. +static bool setForcedRecalibrationFactor(Sensor* sensor, uint16_t concentration) { + if(concentration < 400 || concentration > 2000) { + return false; // Error check. + } + return sendCommandWithCRC(sensor, COMMAND_SET_FORCED_RECALIBRATION_FACTOR, concentration); +} + +// Get the temperature offset. See 1.3.8. +static float getTemperatureOffset(Sensor* sensor) { + union { + int16_t signed16; + uint16_t unsigned16; + } signedUnsigned; // Avoid any ambiguity casting int16_t to uint16_t + signedUnsigned.unsigned16 = readRegister(sensor, COMMAND_SET_TEMPERATURE_OFFSET); + + return ((float)signedUnsigned.signed16) / 100.0; +} + +static bool setTemperatureOffset(Sensor* sensor, float tempOffset) { + // Temp offset is only positive. See: https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library/issues/27#issuecomment-971986826 + //"The SCD30 offset temperature is obtained by subtracting the reference temperature from the SCD30 output temperature" + // https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/9.5_CO2/Sensirion_CO2_Sensors_SCD30_Low_Power_Mode.pdf + + if(tempOffset < 0.0) return false; + + uint16_t value = tempOffset * 100; + + return sendCommandWithCRC(sensor, COMMAND_SET_TEMPERATURE_OFFSET, value); +} + +// Get the altitude compenstation. See 1.3.9. +static uint16_t getAltitudeCompensation(Sensor* sensor) { + return readRegister(sensor, COMMAND_SET_ALTITUDE_COMPENSATION); +} + +// Set the altitude compenstation. See 1.3.9. +static bool setAltitudeCompensation(Sensor* sensor, uint16_t altitude) { + return sendCommandWithCRC(sensor, COMMAND_SET_ALTITUDE_COMPENSATION, altitude); +} + +// Set the pressure compenstation. This is passed during measurement startup. +// mbar can be 700 to 1200 +static bool setAmbientPressure(Sensor* sensor, uint16_t pressure_mbar) { + if(pressure_mbar != 0 || pressure_mbar < 700 || pressure_mbar > 1200) { + return false; + } + return sendCommandWithCRC(sensor, COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar); +} + +// Begins continuous measurements +// Continuous measurement status is saved in non-volatile memory. When the sensor +// is powered down while continuous measurement mode is active SCD30 will measure +// continuously after repowering without sending the measurement command. +// Returns true if successful +static bool beginMeasuringWithSettings(Sensor* sensor, uint16_t pressureOffset) { + return sendCommandWithCRC(sensor, COMMAND_CONTINUOUS_MEASUREMENT, pressureOffset); +} + +// Overload - no pressureOffset +static bool beginMeasuring(Sensor* sensor) { + return beginMeasuringWithSettings(sensor, 0); +} + +// Stop continuous measurement +static bool stopMeasurement(Sensor* sensor) { + return sendCommand(sensor, COMMAND_STOP_MEAS); +} + +// Sets interval between measurements +// 2 seconds to 1800 seconds (30 minutes) +static bool setMeasurementInterval(Sensor* sensor, uint16_t interval) { + if(interval < 2 || interval > 1800) return false; + if(!sendCommandWithCRC(sensor, COMMAND_SET_MEASUREMENT_INTERVAL, interval)) return false; + uint16_t verInterval = readRegister(sensor, COMMAND_SET_MEASUREMENT_INTERVAL); + if(verInterval != interval) { + FURI_LOG_E(APP_NAME, "Measure interval wrong! Val: %02x", verInterval); + return false; + } + return true; +} + +// Gets interval between measurements +// 2 seconds to 1800 seconds (30 minutes) +static uint16_t getMeasurementInterval(Sensor* sensor) { + uint16_t interval = 0; + getSettingValue(sensor, COMMAND_SET_MEASUREMENT_INTERVAL, &interval); + return interval; +} + +// Returns true when data is available +static bool dataAvailable(Sensor* sensor) { + return 1 == readRegister(sensor, COMMAND_GET_DATA_READY); +} \ No newline at end of file diff --git a/applications/external/unitemp/sensors/SCD30.h b/applications/external/unitemp/sensors/SCD30.h new file mode 100644 index 000000000..1ebfbb411 --- /dev/null +++ b/applications/external/unitemp/sensors/SCD30.h @@ -0,0 +1,59 @@ +/* + Unitemp - Universal temperature reader + Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n) + Contributed by divinebird (https://github.com/divinebird) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#ifndef UNITEMP_SCD30 +#define UNITEMP_SCD30 + +#include "../unitemp.h" +#include "../Sensors.h" + +extern const SensorType SCD30; +/** + * @brief Выделение памяти и установка начальных значений датчика SCD30 + * @param sensor Указатель на создаваемый датчик + * @return Истина при успехе + */ +bool unitemp_SCD30_alloc(Sensor* sensor, char* args); + +/** + * @brief Инициализации датчика SCD30 + * @param sensor Указатель на датчик + * @return Истина если инициализация упспешная + */ +bool unitemp_SCD30_init(Sensor* sensor); + +/** + * @brief Деинициализация датчика + * @param sensor Указатель на датчик + */ +bool unitemp_SCD30_deinit(Sensor* sensor); + +/** + * @brief Обновление значений из датчика + * @param sensor Указатель на датчик + * @return Статус опроса датчика + */ +UnitempStatus unitemp_SCD30_update(Sensor* sensor); + +/** + * @brief Высвободить память датчика + * @param sensor Указатель на датчик + */ +bool unitemp_SCD30_free(Sensor* sensor); + +#endif \ No newline at end of file diff --git a/applications/external/unitemp/unitemp.h b/applications/external/unitemp/unitemp.h index 4d184b2c3..69cd8cf4f 100644 --- a/applications/external/unitemp/unitemp.h +++ b/applications/external/unitemp/unitemp.h @@ -40,7 +40,7 @@ //Имя приложения #define APP_NAME "Unitemp" //Версия приложения -#define UNITEMP_APP_VER "1.2" +#define UNITEMP_APP_VER "1.3" //Путь хранения файлов плагина #define APP_PATH_FOLDER "/ext/unitemp" //Имя файла с настройками diff --git a/applications/external/unitemp/views/General_view.c b/applications/external/unitemp/views/General_view.c index 2c8d389bf..22d724935 100644 --- a/applications/external/unitemp/views/General_view.c +++ b/applications/external/unitemp/views/General_view.c @@ -162,6 +162,35 @@ static void _draw_pressure(Canvas* canvas, Sensor* sensor) { } } +static void _draw_co2(Canvas* canvas, Sensor* sensor, Color color) { + const uint8_t x = 29, y = 39; + //Рисование рамки + canvas_draw_rframe(canvas, x, y, 75, 20, 3); + if(color == ColorBlack) { + canvas_draw_rbox(canvas, x, y, 75, 19, 3); + canvas_invert_color(canvas); + } else { + canvas_draw_rframe(canvas, x, y, 75, 19, 3); + } + + //Рисование иконки + canvas_draw_icon(canvas, x + 3, y + 3, &I_co2_11x14); + + int16_t concentration_int = sensor->co2; + // int8_t concentration_dec = (int16_t)(sensor->co2 * 10) % 10; + + //Целая часть + if(concentration_int > 9999) { + snprintf(app->buff, BUFF_SIZE, "MAX "); + canvas_set_font(canvas, FontPrimary); + } else { + snprintf(app->buff, BUFF_SIZE, "%d", concentration_int); + canvas_set_font(canvas, FontBigNumbers); + } + + canvas_draw_str_aligned(canvas, x + 70, y + 10, AlignRight, AlignCenter, app->buff); +} + static void _draw_singleSensor(Canvas* canvas, Sensor* sensor, const uint8_t pos[2], Color color) { canvas_set_font(canvas, FontPrimary); @@ -320,6 +349,17 @@ static void _draw_carousel_values(Canvas* canvas) { canvas, unitemp_sensor_getActive(generalview_sensor_index), hum_positions[1]); _draw_pressure(canvas, unitemp_sensor_getActive(generalview_sensor_index)); break; + case UT_DATA_TYPE_TEMP_HUM_CO2: + _draw_temperature( + canvas, + unitemp_sensor_getActive(generalview_sensor_index), + temp_positions[2][0], + temp_positions[2][1], + ColorWhite); + _draw_humidity( + canvas, unitemp_sensor_getActive(generalview_sensor_index), hum_positions[1]); + _draw_co2(canvas, unitemp_sensor_getActive(generalview_sensor_index), ColorWhite); + break; } } diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 39cb128a7..e3014fcc4 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -213,7 +213,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { flipper_format_free(temp_fm_preset3); - // # HND - FM presets + // # HND - FM preset FlipperFormat* temp_fm_preset4 = flipper_format_string_alloc(); flipper_format_write_string_cstr( temp_fm_preset4, @@ -223,16 +223,6 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz_setting_load_custom_preset(setting, (const char*)"HND_1", temp_fm_preset4); flipper_format_free(temp_fm_preset4); - - FlipperFormat* temp_fm_preset5 = flipper_format_string_alloc(); - flipper_format_write_string_cstr( - temp_fm_preset5, - (const char*)"Custom_preset_data", - (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 07 11 36 10 E9 15 32 18 18 19 16 1D 92 1C 40 1B 03 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); - flipper_format_rewind(temp_fm_preset5); - subghz_setting_load_custom_preset(setting, (const char*)"HND_2", temp_fm_preset5); - - flipper_format_free(temp_fm_preset5); } // custom presets loading - end diff --git a/assets/resources/lfrfid/rfidfuzzer/example_uids_em4100.txt b/assets/resources/rfidfuzzer/example_uids_em4100.txt similarity index 100% rename from assets/resources/lfrfid/rfidfuzzer/example_uids_em4100.txt rename to assets/resources/rfidfuzzer/example_uids_em4100.txt diff --git a/assets/resources/lfrfid/rfidfuzzer/example_uids_h10301.txt b/assets/resources/rfidfuzzer/example_uids_h10301.txt similarity index 100% rename from assets/resources/lfrfid/rfidfuzzer/example_uids_h10301.txt rename to assets/resources/rfidfuzzer/example_uids_h10301.txt diff --git a/assets/resources/lfrfid/rfidfuzzer/example_uids_hidprox.txt b/assets/resources/rfidfuzzer/example_uids_hidprox.txt similarity index 100% rename from assets/resources/lfrfid/rfidfuzzer/example_uids_hidprox.txt rename to assets/resources/rfidfuzzer/example_uids_hidprox.txt diff --git a/assets/resources/lfrfid/rfidfuzzer/example_uids_pac.txt b/assets/resources/rfidfuzzer/example_uids_pac.txt similarity index 100% rename from assets/resources/lfrfid/rfidfuzzer/example_uids_pac.txt rename to assets/resources/rfidfuzzer/example_uids_pac.txt