Просмотр исходного кода

Add the ability to save the key

gid9798 2 лет назад
Родитель
Сommit
774002abbe

+ 9 - 0
fuzzer.c

@@ -46,6 +46,11 @@ PacsFuzzerApp* fuzzer_app_alloc() {
     app->popup = popup_alloc();
     app->popup = popup_alloc();
     view_dispatcher_add_view(app->view_dispatcher, FuzzerViewIDPopup, popup_get_view(app->popup));
     view_dispatcher_add_view(app->view_dispatcher, FuzzerViewIDPopup, popup_get_view(app->popup));
 
 
+    // TextInput
+    app->text_input = text_input_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, FuzzerViewIDTextInput, text_input_get_view(app->text_input));
+
     // Main view
     // Main view
     app->main_view = fuzzer_view_main_alloc();
     app->main_view = fuzzer_view_main_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
@@ -100,6 +105,10 @@ void fuzzer_app_free(PacsFuzzerApp* app) {
     view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDPopup);
     view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDPopup);
     popup_free(app->popup);
     popup_free(app->popup);
 
 
+    // TextInput
+    view_dispatcher_remove_view(app->view_dispatcher, FuzzerViewIDTextInput);
+    text_input_free(app->text_input);
+
     scene_manager_free(app->scene_manager);
     scene_manager_free(app->scene_manager);
     view_dispatcher_free(app->view_dispatcher);
     view_dispatcher_free(app->view_dispatcher);
 
 

+ 4 - 0
fuzzer_i.h

@@ -7,6 +7,7 @@
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
 #include <gui/scene_manager.h>
 #include <gui/scene_manager.h>
 #include <gui/modules/popup.h>
 #include <gui/modules/popup.h>
+#include <gui/modules/text_input.h>
 
 
 #include <dialogs/dialogs.h>
 #include <dialogs/dialogs.h>
 #include <notification/notification_messages.h>
 #include <notification/notification_messages.h>
@@ -23,6 +24,7 @@
 #include "fuzzer_icons.h"
 #include "fuzzer_icons.h"
 
 
 #define FUZZ_TIME_DELAY_MAX (80)
 #define FUZZ_TIME_DELAY_MAX (80)
+#define KEY_NAME_SIZE 22
 
 
 typedef struct {
 typedef struct {
     const char* custom_dict_extension;
     const char* custom_dict_extension;
@@ -41,11 +43,13 @@ typedef struct {
 
 
     Popup* popup;
     Popup* popup;
     DialogsApp* dialogs;
     DialogsApp* dialogs;
+    TextInput* text_input;
     FuzzerViewMain* main_view;
     FuzzerViewMain* main_view;
     FuzzerViewAttack* attack_view;
     FuzzerViewAttack* attack_view;
     FuzzerViewFieldEditor* field_editor_view;
     FuzzerViewFieldEditor* field_editor_view;
 
 
     FuriString* file_path;
     FuriString* file_path;
+    char key_name[KEY_NAME_SIZE + 1];
 
 
     FuzzerState fuzzer_state;
     FuzzerState fuzzer_state;
     FuzzerConsts* fuzzer_const;
     FuzzerConsts* fuzzer_const;

+ 5 - 1
helpers/fuzzer_custom_event.h

@@ -14,10 +14,14 @@ typedef enum {
     FuzzerCustomEventViewAttackPause,
     FuzzerCustomEventViewAttackPause,
     FuzzerCustomEventViewAttackIdle, // Setup
     FuzzerCustomEventViewAttackIdle, // Setup
     FuzzerCustomEventViewAttackEmulateCurrent,
     FuzzerCustomEventViewAttackEmulateCurrent,
-    // FuzzerCustomEventViewAttackSave,
+    FuzzerCustomEventViewAttackSave,
     FuzzerCustomEventViewAttackNextUid,
     FuzzerCustomEventViewAttackNextUid,
     FuzzerCustomEventViewAttackPrevUid,
     FuzzerCustomEventViewAttackPrevUid,
 
 
     FuzzerCustomEventViewFieldEditorBack,
     FuzzerCustomEventViewFieldEditorBack,
     FuzzerCustomEventViewFieldEditorOk,
     FuzzerCustomEventViewFieldEditorOk,
+
+    FuzzerCustomEventTextEditResult,
+
+    FuzzerCustomEventPopupClosed,
 } FuzzerCustomEvent;
 } FuzzerCustomEvent;

+ 1 - 0
helpers/fuzzer_types.h

@@ -25,6 +25,7 @@ typedef enum {
 
 
 typedef enum {
 typedef enum {
     FuzzerViewIDPopup,
     FuzzerViewIDPopup,
+    FuzzerViewIDTextInput,
 
 
     FuzzerViewIDMain,
     FuzzerViewIDMain,
     FuzzerViewIDAttack,
     FuzzerViewIDAttack,

BIN
icons/DolphinNice_96x59.png


+ 29 - 3
lib/worker/fake_worker.c

@@ -10,6 +10,7 @@
 
 
 #define TAG "Fuzzer worker"
 #define TAG "Fuzzer worker"
 #define TOTAL_PROTOCOL_COUNT fuzzer_proto_get_count_of_protocols()
 #define TOTAL_PROTOCOL_COUNT fuzzer_proto_get_count_of_protocols()
+#define PROTOCOL_KEY_FOLDER EXT_PATH(PROTOCOL_KEY_FOLDER_NAME)
 
 
 typedef uint8_t FuzzerWorkerPayload[MAX_PAYLOAD_SIZE];
 typedef uint8_t FuzzerWorkerPayload[MAX_PAYLOAD_SIZE];
 
 
@@ -90,6 +91,32 @@ FuzzerWorkerLoadKeyState fuzzer_worker_load_key_from_file(
     return res;
     return res;
 }
 }
 
 
+static bool fuzer_worker_make_key_folder() {
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+
+    const bool res = storage_simply_mkdir(storage, PROTOCOL_KEY_FOLDER);
+
+    furi_record_close(RECORD_STORAGE);
+
+    return res;
+}
+
+bool fuzzer_worker_save_key(FuzzerWorker* instance, const char* path) {
+    furi_assert(instance);
+    bool res = false;
+
+    if(!fuzer_worker_make_key_folder()) {
+        FURI_LOG_E(TAG, "Cannot create key folder");
+    } else if(!hardware_worker_save_key(instance->hw_worker, path)) {
+        FURI_LOG_E(TAG, "Cannot save key file");
+    } else {
+        FURI_LOG_D(TAG, "Save key Success");
+        res = true;
+    }
+
+    return res;
+}
+
 static bool fuzzer_worker_load_key(FuzzerWorker* instance, bool next) {
 static bool fuzzer_worker_load_key(FuzzerWorker* instance, bool next) {
     furi_assert(instance);
     furi_assert(instance);
     furi_assert(instance->protocol);
     furi_assert(instance->protocol);
@@ -301,6 +328,7 @@ bool fuzzer_worker_init_attack_file_dict(
 
 
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Storage* storage = furi_record_open(RECORD_STORAGE);
     instance->uids_stream = buffered_file_stream_alloc(storage);
     instance->uids_stream = buffered_file_stream_alloc(storage);
+    furi_record_close(RECORD_STORAGE);
 
 
     if(!buffered_file_stream_open(
     if(!buffered_file_stream_open(
            instance->uids_stream, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
            instance->uids_stream, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
@@ -315,7 +343,6 @@ bool fuzzer_worker_init_attack_file_dict(
         instance->attack_type = FuzzerWorkerAttackTypeMax;
         instance->attack_type = FuzzerWorkerAttackTypeMax;
         buffered_file_stream_close(instance->uids_stream);
         buffered_file_stream_close(instance->uids_stream);
         stream_free(instance->uids_stream);
         stream_free(instance->uids_stream);
-        furi_record_close(RECORD_STORAGE);
     } else {
     } else {
         res = true;
         res = true;
     }
     }
@@ -456,11 +483,10 @@ void fuzzer_worker_stop(FuzzerWorker* instance) {
     if(instance->attack_type == FuzzerWorkerAttackTypeLoadFileCustomUids) {
     if(instance->attack_type == FuzzerWorkerAttackTypeLoadFileCustomUids) {
         buffered_file_stream_close(instance->uids_stream);
         buffered_file_stream_close(instance->uids_stream);
         stream_free(instance->uids_stream);
         stream_free(instance->uids_stream);
-        furi_record_close(RECORD_STORAGE);
         instance->attack_type = FuzzerWorkerAttackTypeMax;
         instance->attack_type = FuzzerWorkerAttackTypeMax;
     }
     }
 
 
-    // TODO  anything else
+    // TODO anything else
 }
 }
 
 
 void fuzzer_worker_set_uid_chaged_callback(
 void fuzzer_worker_set_uid_chaged_callback(

+ 2 - 0
lib/worker/fake_worker.h

@@ -126,6 +126,8 @@ FuzzerWorkerLoadKeyState fuzzer_worker_load_key_from_file(
     FuzzerProtocolsID* protocol_index,
     FuzzerProtocolsID* protocol_index,
     const char* filename);
     const char* filename);
 
 
+bool fuzzer_worker_save_key(FuzzerWorker* instance, const char* path);
+
 /**
 /**
  * Set callback for uid changed
  * Set callback for uid changed
  * 
  * 

+ 14 - 0
lib/worker/helpers/hardware_worker.c

@@ -178,6 +178,20 @@ bool hardware_worker_load_key_from_file(HardwareWorker* instance, const char* fi
         res = true;
         res = true;
     }
     }
 
 
+#endif
+
+    return res;
+}
+
+bool hardware_worker_save_key(HardwareWorker* instance, const char* path) {
+    furi_assert(instance);
+    bool res;
+
+#if defined(RFID_125_PROTOCOL)
+    res = lfrfid_dict_file_save(instance->protocols_items, instance->protocol_id, path);
+#else
+
+    res = ibutton_protocols_save(instance->protocols_items, instance->key, path);
 #endif
 #endif
 
 
     return res;
     return res;

+ 3 - 3
lib/worker/helpers/hardware_worker.h

@@ -1,7 +1,5 @@
 #pragma once
 #pragma once
 
 
-// typedef HwProtocolID HwProtocolID;
-
 #include <stdint.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdbool.h>
 
 
@@ -45,4 +43,6 @@ bool hardware_worker_set_protocol_id_by_name(HardwareWorker* instance, const cha
 
 
 HwProtocolID hardware_worker_get_protocol_id(HardwareWorker* instance);
 HwProtocolID hardware_worker_get_protocol_id(HardwareWorker* instance);
 
 
-bool hardware_worker_load_key_from_file(HardwareWorker* instance, const char* filename);
+bool hardware_worker_load_key_from_file(HardwareWorker* instance, const char* filename);
+
+bool hardware_worker_save_key(HardwareWorker* instance, const char* path);

+ 9 - 1
lib/worker/protocol.h

@@ -40,8 +40,16 @@ void fuzzer_payload_free(FuzzerPayload*);
  */
  */
 uint8_t fuzzer_proto_get_max_data_size();
 uint8_t fuzzer_proto_get_max_data_size();
 
 
-// TODO add description
+/**
+ * Get recomended/default emulation time
+ * @return Default emulation time
+ */
 uint8_t fuzzer_proto_get_def_emu_time();
 uint8_t fuzzer_proto_get_def_emu_time();
+
+/**
+ * Get recomended/default idle time
+ * @return Default idle time
+ */
 uint8_t fuzzer_proto_get_def_idle_time();
 uint8_t fuzzer_proto_get_def_idle_time();
 
 
 /**
 /**

+ 8 - 0
lib/worker/protocol_i.h

@@ -7,11 +7,19 @@
 #define PROTOCOL_DEF_IDLE_TIME (4)
 #define PROTOCOL_DEF_IDLE_TIME (4)
 #define PROTOCOL_DEF_EMU_TIME (5)
 #define PROTOCOL_DEF_EMU_TIME (5)
 #define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME
 #define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME
+
+#define PROTOCOL_KEY_FOLDER_NAME "lfrfid"
+#define PROTOCOL_KEY_EXTENSION ".rfid"
+
 #else
 #else
+
 #define MAX_PAYLOAD_SIZE (8)
 #define MAX_PAYLOAD_SIZE (8)
 #define PROTOCOL_DEF_IDLE_TIME (2)
 #define PROTOCOL_DEF_IDLE_TIME (2)
 #define PROTOCOL_DEF_EMU_TIME (2)
 #define PROTOCOL_DEF_EMU_TIME (2)
 #define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME
 #define PROTOCOL_TIME_DELAY_MIN PROTOCOL_DEF_IDLE_TIME + PROTOCOL_DEF_EMU_TIME
+
+#define PROTOCOL_KEY_FOLDER_NAME "ibutton"
+#define PROTOCOL_KEY_EXTENSION ".ibtn"
 #endif
 #endif
 
 
 typedef struct ProtoDict ProtoDict;
 typedef struct ProtoDict ProtoDict;

+ 2 - 0
scenes/fuzzer_scene_attack.c

@@ -145,6 +145,8 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) {
             } else {
             } else {
                 notification_message(app->notifications, &sequence_blink_red_100);
                 notification_message(app->notifications, &sequence_blink_red_100);
             }
             }
+        } else if(event.event == FuzzerCustomEventViewAttackSave) {
+            scene_manager_next_scene(app->scene_manager, FuzzerSceneSaveName);
         }
         }
         // Callback from worker
         // Callback from worker
         else if(event.event == FuzzerCustomEventViewAttackEnd) {
         else if(event.event == FuzzerCustomEventViewAttackEnd) {

+ 3 - 1
scenes/fuzzer_scene_config.h

@@ -1,3 +1,5 @@
 ADD_SCENE(fuzzer, main, Main)
 ADD_SCENE(fuzzer, main, Main)
 ADD_SCENE(fuzzer, attack, Attack)
 ADD_SCENE(fuzzer, attack, Attack)
-ADD_SCENE(fuzzer, field_editor, FieldEditor)
+ADD_SCENE(fuzzer, field_editor, FieldEditor)
+ADD_SCENE(fuzzer, save_name, SaveName)
+ADD_SCENE(fuzzer, save_success, SaveSuccess)

+ 67 - 0
scenes/fuzzer_scene_save_name.c

@@ -0,0 +1,67 @@
+#include "../fuzzer_i.h"
+
+#include <toolbox/random_name.h>
+#include <toolbox/path.h>
+
+static void fuzzer_scene_save_name_text_input_callback(void* context) {
+    PacsFuzzerApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, FuzzerCustomEventTextEditResult);
+}
+
+void fuzzer_scene_save_name_on_enter(void* context) {
+    PacsFuzzerApp* app = context;
+    TextInput* text_input = app->text_input;
+
+    set_random_name(app->key_name, KEY_NAME_SIZE);
+
+    text_input_set_header_text(text_input, "Name the key");
+    text_input_set_result_callback(
+        text_input,
+        fuzzer_scene_save_name_text_input_callback,
+        app,
+        app->key_name,
+        KEY_NAME_SIZE,
+        false);
+
+    ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
+        app->fuzzer_const->path_key_folder, app->fuzzer_const->key_extension, app->key_name);
+    text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDTextInput);
+}
+
+bool fuzzer_scene_save_name_on_event(void* context, SceneManagerEvent event) {
+    PacsFuzzerApp* app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == FuzzerCustomEventTextEditResult) {
+            consumed = true;
+            furi_string_printf(
+                app->file_path,
+                "%s/%s%s",
+                app->fuzzer_const->path_key_folder,
+                app->key_name,
+                app->fuzzer_const->key_extension);
+
+            if(fuzzer_worker_save_key(app->worker, furi_string_get_cstr(app->file_path))) {
+                scene_manager_next_scene(app->scene_manager, FuzzerSceneSaveSuccess);
+            } else {
+                scene_manager_previous_scene(app->scene_manager);
+            }
+        }
+    }
+
+    return consumed;
+}
+
+void fuzzer_scene_save_name_on_exit(void* context) {
+    PacsFuzzerApp* app = context;
+    TextInput* text_input = app->text_input;
+
+    void* validator_context = text_input_get_validator_callback_context(text_input);
+    text_input_set_validator(text_input, NULL, NULL);
+    validator_is_file_free((ValidatorIsFile*)validator_context);
+
+    text_input_reset(text_input);
+}

+ 44 - 0
scenes/fuzzer_scene_save_success.c

@@ -0,0 +1,44 @@
+#include "../fuzzer_i.h"
+
+static void fuzzer_scene_save_popup_timeout_callback(void* context) {
+    PacsFuzzerApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, FuzzerCustomEventPopupClosed);
+}
+
+void fuzzer_scene_save_success_on_enter(void* context) {
+    PacsFuzzerApp* app = context;
+    Popup* popup = app->popup;
+
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
+    popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
+    popup_set_context(popup, app);
+    popup_set_callback(popup, fuzzer_scene_save_popup_timeout_callback);
+    popup_set_timeout(popup, 1500);
+    popup_enable_timeout(popup);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDPopup);
+}
+
+bool fuzzer_scene_save_success_on_event(void* context, SceneManagerEvent event) {
+    PacsFuzzerApp* app = context;
+    bool consumed = false;
+
+    if((event.type == SceneManagerEventTypeBack) ||
+       ((event.type == SceneManagerEventTypeCustom) &&
+        (event.event == FuzzerCustomEventPopupClosed))) {
+        bool result = scene_manager_search_and_switch_to_previous_scene(
+            app->scene_manager, FuzzerSceneAttack);
+        if(!result) {
+            scene_manager_search_and_switch_to_previous_scene(app->scene_manager, FuzzerSceneMain);
+        }
+        consumed = true;
+    }
+
+    return consumed;
+}
+
+void fuzzer_scene_save_success_on_exit(void* context) {
+    PacsFuzzerApp* app = context;
+
+    popup_reset(app->popup);
+}

+ 5 - 5
todo.md

@@ -4,7 +4,7 @@
 
 
 - [x] Make the "Load File" independent of the current protocol
 - [x] Make the "Load File" independent of the current protocol
 - [x] Add pause
 - [x] Add pause
-    - [X] Switching  UIDs if possible
+    - [x] Switching  UIDs if possible
 - [x] Led and sound Notification
 - [x] Led and sound Notification
     - [x] Led
     - [x] Led
     - [x] Vibro
     - [x] Vibro
@@ -18,7 +18,7 @@
 
 
 - [x] Add `BFCustomerID` attack
 - [x] Add `BFCustomerID` attack
     - [x] Add the ability to select index
     - [x] Add the ability to select index
-- [ ] Save key logic
+- [x] Save key logic
 
 
 ## Code Improvement
 ## Code Improvement
 
 
@@ -36,9 +36,9 @@
     - [x] `UID_MAX_SIZE`
     - [x] `UID_MAX_SIZE`
 - [x] Add pause
 - [x] Add pause
     - [x] Fix `Custom dict` attack when ended
     - [x] Fix `Custom dict` attack when ended
-- [X] Pause V2
-    - [ ] Save logic
-    - [X] Switching  UIDs if possible
+- [x] Pause V2
+    - [x] Save logic
+    - [x] Switching  UIDs if possible
 - [ ] Worker
 - [ ] Worker
     - [ ] Use `prtocol_id` instead of protocol name
     - [ ] Use `prtocol_id` instead of protocol name
     - [x] this can be simplified `fuzzer_proto_items`
     - [x] this can be simplified `fuzzer_proto_items`

+ 3 - 1
views/attack.c

@@ -244,7 +244,7 @@ void fuzzer_view_attack_draw(Canvas* canvas, FuzzerViewAttackModel* model) {
         fuzzer_view_attack_draw_idle(canvas, model);
         fuzzer_view_attack_draw_idle(canvas, model);
     } else if(model->attack_state == FuzzerAttackStatePause) {
     } else if(model->attack_state == FuzzerAttackStatePause) {
         elements_button_left(canvas, "Back");
         elements_button_left(canvas, "Back");
-        // elements_button_right(canvas, "Save"); // XXX
+        elements_button_right(canvas, "Save");
         elements_button_center(canvas, "Emu");
         elements_button_center(canvas, "Emu");
     } else if(model->attack_state == FuzzerAttackStateEnd) {
     } else if(model->attack_state == FuzzerAttackStateEnd) {
         fuzzer_view_attack_draw_end(canvas, model);
         fuzzer_view_attack_draw_end(canvas, model);
@@ -382,6 +382,8 @@ bool fuzzer_view_attack_input(InputEvent* event, void* context) {
                 if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
                 if((event->key == InputKeyBack || event->key == InputKeyLeft) &&
                    event->type == InputTypeShort) {
                    event->type == InputTypeShort) {
                     view_attack->callback(FuzzerCustomEventViewAttackIdle, view_attack->context);
                     view_attack->callback(FuzzerCustomEventViewAttackIdle, view_attack->context);
+                } else if(event->key == InputKeyRight && event->type == InputTypeShort) {
+                    view_attack->callback(FuzzerCustomEventViewAttackSave, view_attack->context);
                 } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
                 } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
                     view_attack->callback(
                     view_attack->callback(
                         FuzzerCustomEventViewAttackEmulateCurrent, view_attack->context);
                         FuzzerCustomEventViewAttackEmulateCurrent, view_attack->context);