diff --git a/applications/external/pacs_fuzzer/lib/worker/fake_worker.c b/applications/external/pacs_fuzzer/lib/worker/fake_worker.c index ff74f29e1..b44790ebc 100644 --- a/applications/external/pacs_fuzzer/lib/worker/fake_worker.c +++ b/applications/external/pacs_fuzzer/lib/worker/fake_worker.c @@ -12,6 +12,7 @@ #if defined(RFID_125_PROTOCOL) #define MAX_PAYLOAD_SIZE 6 +#include #include #include @@ -44,6 +45,7 @@ struct FuzzerWorker { uint8_t payload[MAX_PAYLOAD_SIZE]; Stream* uids_stream; uint16_t index; + uint8_t chusen_byte; bool treead_running; FuriTimer* timer; @@ -62,12 +64,11 @@ static bool fuzzer_worker_load_key(FuzzerWorker* worker, bool next) { const FuzzerProtocol* protocol = worker->protocol; - if(next) { - worker->index++; - } - switch(worker->attack_type) { case FuzzerWorkerAttackTypeDefaultDict: + if(next) { + worker->index++; + } if(worker->index < protocol->dict.len) { memcpy( worker->payload, @@ -78,6 +79,9 @@ static bool fuzzer_worker_load_key(FuzzerWorker* worker, bool next) { break; case FuzzerWorkerAttackTypeLoadFileCustomUids: { + if(next) { + worker->index++; + } uint8_t str_len = protocol->data_size * 2 + 1; FuriString* data_str = furi_string_alloc(); while(true) { @@ -113,6 +117,14 @@ static bool fuzzer_worker_load_key(FuzzerWorker* worker, bool next) { break; + case FuzzerWorkerAttackTypeLoadFile: + if(worker->payload[worker->index] != 0xFF) { + worker->payload[worker->index]++; + res = true; + } + + break; + default: break; } @@ -170,11 +182,7 @@ void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key) { memcpy(key, worker->payload, worker->protocol->data_size); } -bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index) { - furi_assert(worker); - - bool res = false; - +static void fuzzer_worker_set_protocol(FuzzerWorker* worker, FuzzerProtos protocol_index) { worker->protocol = &fuzzer_proto_items[protocol_index]; #if defined(RFID_125_PROTOCOL) @@ -185,6 +193,14 @@ bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index worker->protocol_id = ibutton_protocols_get_id_by_name(worker->protocols_items, worker->protocol->name); #endif +} + +bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index) { + furi_assert(worker); + + bool res = false; + fuzzer_worker_set_protocol(worker, protocol_index); + worker->attack_type = FuzzerWorkerAttackTypeDefaultDict; worker->index = 0; @@ -205,17 +221,7 @@ bool fuzzer_worker_attack_file_dict( furi_assert(file_path); bool res = false; - - worker->protocol = &fuzzer_proto_items[protocol_index]; - -#if defined(RFID_125_PROTOCOL) - worker->protocol_id = - protocol_dict_get_protocol_by_name(worker->protocols_items, worker->protocol->name); -#else - // TODO iButtonProtocolIdInvalid check - worker->protocol_id = - ibutton_protocols_get_id_by_name(worker->protocols_items, worker->protocol->name); -#endif + fuzzer_worker_set_protocol(worker, protocol_index); Storage* storage = furi_record_open(RECORD_STORAGE); worker->uids_stream = buffered_file_stream_alloc(storage); @@ -240,6 +246,79 @@ bool fuzzer_worker_attack_file_dict( return res; } +bool fuzzer_worker_attack_bf_byte( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + const uint8_t* uid, + uint8_t chusen) { + furi_assert(worker); + + bool res = false; + fuzzer_worker_set_protocol(worker, protocol_index); + + worker->attack_type = FuzzerWorkerAttackTypeLoadFile; + worker->index = chusen; + + memcpy(worker->payload, uid, worker->protocol->data_size); + + res = true; + + return res; +} + +// TODO make it protocol independent +bool fuzzer_worker_load_key_from_file( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + const char* filename) { + furi_assert(worker); + + bool res = false; + fuzzer_worker_set_protocol(worker, protocol_index); + +#if defined(RFID_125_PROTOCOL) + ProtocolId loaded_proto_id = lfrfid_dict_file_load(worker->protocols_items, filename); + if(loaded_proto_id == PROTOCOL_NO) { + // Err Cant load file + FURI_LOG_W(TAG, "Cant load file"); + } else if(worker->protocol_id != loaded_proto_id) { // Err wrong protocol + FURI_LOG_W(TAG, "Wrong protocol"); + FURI_LOG_W( + TAG, + "Selected: %s Loaded: %s", + worker->protocol->name, + protocol_dict_get_name(worker->protocols_items, loaded_proto_id)); + } else { + protocol_dict_get_data( + worker->protocols_items, worker->protocol_id, worker->payload, MAX_PAYLOAD_SIZE); + res = true; + } +#else + if(!ibutton_protocols_load(worker->protocols_items, worker->key, filename)) { + // Err Cant load file + FURI_LOG_W(TAG, "Cant load file"); + } else { + if(worker->protocol_id != ibutton_key_get_protocol_id(worker->key)) { + // Err wrong protocol + FURI_LOG_W(TAG, "Wrong protocol"); + FURI_LOG_W( + TAG, + "Selected: %s Loaded: %s", + worker->protocol->name, + ibutton_protocols_get_name( + worker->protocols_items, ibutton_key_get_protocol_id(worker->key))); + } else { + iButtonEditableData data; + ibutton_protocols_get_editable_data(worker->protocols_items, worker->key, &data); + memcpy(worker->payload, data.ptr, data.size); + res = true; + } + } +#endif + + return res; +} + FuzzerWorker* fuzzer_worker_alloc() { FuzzerWorker* worker = malloc(sizeof(FuzzerWorker)); diff --git a/applications/external/pacs_fuzzer/lib/worker/fake_worker.h b/applications/external/pacs_fuzzer/lib/worker/fake_worker.h index 2628ac649..b1eea19fb 100644 --- a/applications/external/pacs_fuzzer/lib/worker/fake_worker.h +++ b/applications/external/pacs_fuzzer/lib/worker/fake_worker.h @@ -27,6 +27,12 @@ void fuzzer_worker_stop(FuzzerWorker* worker); bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index); +bool fuzzer_worker_attack_bf_byte( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + const uint8_t* uid, + uint8_t chusen); + bool fuzzer_worker_attack_file_dict( FuzzerWorker* worker, FuzzerProtos protocol_index, @@ -34,6 +40,11 @@ bool fuzzer_worker_attack_file_dict( void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key); +bool fuzzer_worker_load_key_from_file( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + const char* filename); + void fuzzer_worker_set_uid_chaged_callback( FuzzerWorker* worker, FuzzerWorkerUidChagedCallback callback, diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_field_editor.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_field_editor.c index 197bd82c4..52e19e9e0 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_field_editor.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_field_editor.c @@ -1,6 +1,8 @@ #include "../fuzzer_i.h" #include "../helpers/fuzzer_custom_event.h" +#define UID_MAX_SIZE 8 // TODO + void fuzzer_scene_field_editor_callback(FuzzerCustomEvent event, void* context) { furi_assert(context); PacsFuzzerApp* app = context; @@ -14,6 +16,17 @@ void fuzzer_scene_field_editor_on_enter(void* context) { fuzzer_view_field_editor_set_callback( app->field_editor_view, fuzzer_scene_field_editor_callback, app); + uint8_t uid[UID_MAX_SIZE]; + + uint8_t* uid_p = &uid[0]; + + fuzzer_worker_get_current_key(app->worker, uid_p); + + fuzzer_view_field_editor_reset_data( + app->field_editor_view, + uid_p, + fuzzer_proto_items[app->fuzzer_state.proto_index].data_size); // TODO + view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDFieldEditor); } @@ -29,6 +42,15 @@ bool fuzzer_scene_field_editor_on_event(void* context, SceneManagerEvent event) view_dispatcher_stop(app->view_dispatcher); } consumed = true; + } else if(event.event == FuzzerCustomEventViewFieldEditorOk) { + // TODO + if(fuzzer_worker_attack_bf_byte( + app->worker, + app->fuzzer_state.proto_index, + fuzzer_view_field_editor_get_uid(app->field_editor_view), + fuzzer_view_field_editor_get_index(app->field_editor_view))) { + scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); + } } } diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c index cb5e97c52..3f03835fa 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c @@ -30,6 +30,26 @@ static bool fuzzer_scene_main_load_custom_dict(void* context) { 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, &I_rfid_10px); // TODO 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; +} + void fuzzer_scene_main_on_enter(void* context) { furi_assert(context); PacsFuzzerApp* app = context; @@ -70,9 +90,19 @@ bool fuzzer_scene_main_on_event(void* context, SceneManagerEvent event) { break; case FuzzerMainMenuIndexLoadFile: - // TODO Delete - scene_manager_next_scene(app->scene_manager, FuzzerSceneFieldEditor); - + 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_next_scene(app->scene_manager, FuzzerSceneFieldEditor); + FURI_LOG_I("Scene", "Load ok"); + } else { + FURI_LOG_W("Scene", "Load err"); + } + } break; case FuzzerMainMenuIndexLoadFileCustomUids: diff --git a/applications/external/pacs_fuzzer/todo.md b/applications/external/pacs_fuzzer/todo.md new file mode 100644 index 000000000..c96e897e9 --- /dev/null +++ b/applications/external/pacs_fuzzer/todo.md @@ -0,0 +1,32 @@ +## Working Improvement + +#### Quality of life + +- [ ] Make the "Load File" independent of the current protocol +- [ ] Add pause + - [ ] Switching UIDs if possible +- [ ] Led and sound Notification +- [ ] Error Notification + - [ ] Custom UIDs dict loading + - [ ] Key file loading + - [ ] Anything else + +#### App functionality + +- [ ] Add `BFCustomerID` attack +- [ ] Save key logic + +## Code Improvement + +- [ ] GUI + - [ ] Rewrite `gui_const` logic + - [ ] Separate protocol name from `fuzzer_proto_items` + - [ ] Icon in dialog + - [ ] Description and buttons in `field_editor` view + - [ ] Protocol carousel in `main_menu` +- [ ] UID + - [ ] Simplify the storage and exchange of `uids.data` `uid.data_size` in `views` + - [ ] `UID_MAX_SIZE` +- [ ] Add pause + - [ ] Fix `Custom dict` attack when ended +- [ ] this can be simplified `fuzzer_proto_items` diff --git a/applications/external/pacs_fuzzer/views/field_editor.c b/applications/external/pacs_fuzzer/views/field_editor.c index daf8e9d24..f073baf99 100644 --- a/applications/external/pacs_fuzzer/views/field_editor.c +++ b/applications/external/pacs_fuzzer/views/field_editor.c @@ -8,6 +8,8 @@ #define UID_STR_LENGTH 25 #define EDITOR_STRING_Y 50 +#define UID_MAX_SIZE 8 // TODO + struct FuzzerViewFieldEditor { View* view; FuzzerViewFieldEditorCallback callback; @@ -18,8 +20,10 @@ struct FuzzerViewFieldEditor { typedef struct { uint8_t* uid; uint8_t uid_size; - uint8_t index; + FuriString* uid_str; + + uint8_t index; bool lo; } FuzzerViewFieldEditorModel; @@ -33,6 +37,40 @@ void fuzzer_view_field_editor_set_callback( view_edit->context = context; } +void fuzzer_view_field_editor_reset_data( + FuzzerViewFieldEditor* view_edit, + uint8_t* uid, + uint8_t uid_size) { + furi_assert(view_edit); + + with_view_model( + view_edit->view, + FuzzerViewFieldEditorModel * model, + { + memcpy(model->uid, uid, uid_size); + model->index = 0; + model->lo = false; + model->uid_size = uid_size; + }, + true); +} + +const uint8_t* fuzzer_view_field_editor_get_uid(FuzzerViewFieldEditor* view_edit) { + furi_assert(view_edit); + uint8_t* uid; + with_view_model( + view_edit->view, FuzzerViewFieldEditorModel * model, { uid = model->uid; }, true); + return uid; +} + +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); @@ -223,7 +261,7 @@ FuzzerViewFieldEditor* fuzzer_view_field_editor_alloc() { { model->uid_str = furi_string_alloc(); - model->uid = malloc(8); + model->uid = malloc(UID_MAX_SIZE); }, true); diff --git a/applications/external/pacs_fuzzer/views/field_editor.h b/applications/external/pacs_fuzzer/views/field_editor.h index df3aba724..26a8a8ac9 100644 --- a/applications/external/pacs_fuzzer/views/field_editor.h +++ b/applications/external/pacs_fuzzer/views/field_editor.h @@ -16,4 +16,13 @@ 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); \ No newline at end of file +View* fuzzer_view_field_editor_get_view(FuzzerViewFieldEditor* view_attack); + +void fuzzer_view_field_editor_reset_data( + FuzzerViewFieldEditor* view_edit, + uint8_t* uid, + uint8_t uid_size); + +const uint8_t* fuzzer_view_field_editor_get_uid(FuzzerViewFieldEditor* view_edit); + +uint8_t fuzzer_view_field_editor_get_index(FuzzerViewFieldEditor* view_edit); \ No newline at end of file