diff --git a/applications/external/pacs_fuzzer/application.fam b/applications/external/pacs_fuzzer/application.fam index 6b6b2ab36..8e67af6d4 100644 --- a/applications/external/pacs_fuzzer/application.fam +++ b/applications/external/pacs_fuzzer/application.fam @@ -2,7 +2,7 @@ App( appid="pacs_fuzzer", name="Fuzzer Gui", apptype=FlipperAppType.EXTERNAL, - entry_point="fuzzer_start", + entry_point="fuzzer_start_ibtn", requires=[ "gui", "storage", @@ -28,7 +28,7 @@ App( appid="pacs_rfid_fuzzer", name="Fuzzer Gui rfid", apptype=FlipperAppType.EXTERNAL, - entry_point="fuzzer_start", + entry_point="fuzzer_start_rfid", requires=[ "gui", "storage", diff --git a/applications/external/pacs_fuzzer/fuzzer.c b/applications/external/pacs_fuzzer/fuzzer.c index 5a6a4c9b6..b6b66fb18 100644 --- a/applications/external/pacs_fuzzer/fuzzer.c +++ b/applications/external/pacs_fuzzer/fuzzer.c @@ -27,9 +27,14 @@ PacsFuzzerApp* fuzzer_app_alloc() { app->worker = fuzzer_worker_alloc(); + app->file_path = furi_string_alloc(); + // GUI app->gui = furi_record_open(RECORD_GUI); + // Dialog + app->dialogs = furi_record_open(RECORD_DIALOGS); + // View Dispatcher app->view_dispatcher = view_dispatcher_alloc(); @@ -75,18 +80,49 @@ void fuzzer_app_free(PacsFuzzerApp* app) { 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); + furi_string_free(app->file_path); + fuzzer_worker_free(app->worker); free(app); } -int32_t fuzzer_start(void* p) { +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", + }; + 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", + }; + fuzzer_app->fuzzer_const = &app_const; + view_dispatcher_run(fuzzer_app->view_dispatcher); fuzzer_app_free(fuzzer_app); diff --git a/applications/external/pacs_fuzzer/fuzzer_i.h b/applications/external/pacs_fuzzer/fuzzer_i.h index bc31a137c..b56becd8f 100644 --- a/applications/external/pacs_fuzzer/fuzzer_i.h +++ b/applications/external/pacs_fuzzer/fuzzer_i.h @@ -1,9 +1,13 @@ #pragma once +#include +#include + #include #include #include #include +#include #include "scenes/fuzzer_scene.h" #include "views/main_menu.h" @@ -13,16 +17,31 @@ #include "lib/worker/fake_worker.h" #include +#include "fuzzer_icons.h" + +#define FUZZ_TIME_DELAY_MIN (5) +#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; +} FuzzerConsts; typedef struct { Gui* gui; ViewDispatcher* view_dispatcher; SceneManager* scene_manager; + DialogsApp* dialogs; FuzzerViewMain* main_view; FuzzerViewAttack* attack_view; + FuriString* file_path; + FuzzerState fuzzer_state; + FuzzerConsts* fuzzer_const; FuzzerWorker* worker; } PacsFuzzerApp; \ No newline at end of file diff --git a/applications/external/pacs_fuzzer/lib/worker/fake_worker.c b/applications/external/pacs_fuzzer/lib/worker/fake_worker.c index 6da2becbc..ff74f29e1 100644 --- a/applications/external/pacs_fuzzer/lib/worker/fake_worker.c +++ b/applications/external/pacs_fuzzer/lib/worker/fake_worker.c @@ -1,25 +1,28 @@ #include "fake_worker.h" -#include #include -#if defined(RFID_125_PROTOCOL) +#include +#include +#include -#else - -#endif +#define TAG "Fuzzer worker" +#define FUZZ_TIME_DELAY_DEFAULT (10) #if defined(RFID_125_PROTOCOL) +#define MAX_PAYLOAD_SIZE 6 #include #include #else +#define MAX_PAYLOAD_SIZE 8 #include #include #endif + #include struct FuzzerWorker { @@ -74,6 +77,42 @@ static bool fuzzer_worker_load_key(FuzzerWorker* worker, bool next) { } break; + case FuzzerWorkerAttackTypeLoadFileCustomUids: { + 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(worker->uids_stream, data_str)) { + stream_rewind(worker->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], + &worker->payload[i])) { + parse_ok = false; + break; + } + } + res = parse_ok; + } + break; + } + } + + break; + default: break; } @@ -134,20 +173,71 @@ void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key) { bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index) { furi_assert(worker); + bool res = false; + worker->protocol = &fuzzer_proto_items[protocol_index]; - // TODO iButtonProtocolIdInvalid check #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 worker->attack_type = FuzzerWorkerAttackTypeDefaultDict; worker->index = 0; - return fuzzer_worker_load_key(worker, false); + if(!fuzzer_worker_load_key(worker, false)) { + worker->attack_type = FuzzerWorkerAttackTypeMax; + } else { + res = true; + } + + return res; +} + +bool fuzzer_worker_attack_file_dict( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + FuriString* file_path) { + furi_assert(worker); + 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 + + Storage* storage = furi_record_open(RECORD_STORAGE); + worker->uids_stream = buffered_file_stream_alloc(storage); + + if(!buffered_file_stream_open( + worker->uids_stream, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + buffered_file_stream_close(worker->uids_stream); + return res; + } + + worker->attack_type = FuzzerWorkerAttackTypeLoadFileCustomUids; + worker->index = 0; + + if(!fuzzer_worker_load_key(worker, false)) { + worker->attack_type = FuzzerWorkerAttackTypeMax; + buffered_file_stream_close(worker->uids_stream); + furi_record_close(RECORD_STORAGE); + } else { + res = true; + } + + return res; } FuzzerWorker* fuzzer_worker_alloc() { @@ -198,7 +288,7 @@ void fuzzer_worker_free(FuzzerWorker* worker) { free(worker); } -void fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay) { +bool fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay) { furi_assert(worker); if(worker->attack_type < FuzzerWorkerAttackTypeMax) { @@ -214,7 +304,9 @@ void fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay) { ibutton_worker_start_thread(worker->proto_worker); ibutton_worker_emulate_start(worker->proto_worker, worker->key); #endif + return true; } + return false; } void fuzzer_worker_stop(FuzzerWorker* worker) { @@ -233,6 +325,12 @@ void fuzzer_worker_stop(FuzzerWorker* worker) { worker->treead_running = false; } + if(worker->attack_type == FuzzerWorkerAttackTypeLoadFileCustomUids) { + buffered_file_stream_close(worker->uids_stream); + furi_record_close(RECORD_STORAGE); + worker->attack_type = FuzzerWorkerAttackTypeMax; + } + // TODO anything else } diff --git a/applications/external/pacs_fuzzer/lib/worker/fake_worker.h b/applications/external/pacs_fuzzer/lib/worker/fake_worker.h index 00e3cb23f..2628ac649 100644 --- a/applications/external/pacs_fuzzer/lib/worker/fake_worker.h +++ b/applications/external/pacs_fuzzer/lib/worker/fake_worker.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "protocol.h" @@ -21,12 +21,17 @@ FuzzerWorker* fuzzer_worker_alloc(); void fuzzer_worker_free(FuzzerWorker* worker); -void fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay); +bool fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay); void fuzzer_worker_stop(FuzzerWorker* worker); bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index); +bool fuzzer_worker_attack_file_dict( + FuzzerWorker* worker, + FuzzerProtos protocol_index, + FuriString* file_path); + void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key); void fuzzer_worker_set_uid_chaged_callback( diff --git a/applications/external/pacs_fuzzer/lib/worker/protocol.h b/applications/external/pacs_fuzzer/lib/worker/protocol.h index c6d7c88ba..a69d3db04 100644 --- a/applications/external/pacs_fuzzer/lib/worker/protocol.h +++ b/applications/external/pacs_fuzzer/lib/worker/protocol.h @@ -4,24 +4,6 @@ // #define RFID_125_PROTOCOL -#if defined(RFID_125_PROTOCOL) - -#define MAX_PAYLOAD_SIZE 6 - -#define FUZZ_TIME_DELAY_MIN (5) -#define FUZZ_TIME_DELAY_DEFAULT (10) -#define FUZZ_TIME_DELAY_MAX (70) - -#else - -#define MAX_PAYLOAD_SIZE 8 - -#define FUZZ_TIME_DELAY_MIN (4) -#define FUZZ_TIME_DELAY_DEFAULT (8) -#define FUZZ_TIME_DELAY_MAX (80) - -#endif - typedef enum { #if defined(RFID_125_PROTOCOL) diff --git a/applications/external/pacs_fuzzer/lib/worker/protocol_i.h b/applications/external/pacs_fuzzer/lib/worker/protocol_i.h new file mode 100644 index 000000000..e0ab76cb3 --- /dev/null +++ b/applications/external/pacs_fuzzer/lib/worker/protocol_i.h @@ -0,0 +1,31 @@ +#pragma once + +#include "protocol.h" + +#if defined(RFID_125_PROTOCOL) + +#define MAX_PAYLOAD_SIZE 6 + +#define FUZZ_TIME_DELAY_MIN (5) +#define FUZZ_TIME_DELAY_DEFAULT (10) +#define FUZZ_TIME_DELAY_MAX (70) + +#define FUZZER_APP_CUSTOM_DICT_EXTENSION ".txt" +#define FUZZER_APP_CUSTOM_DICT_FOLDER "/ext/rfidfuzzer" +#define FUZZER_APP_KEY_EXTENSION ".rfid" +#define FUZZER_APP_PATH_KEY_FOLDER "/ext/lfrfid" + +#else + +#define MAX_PAYLOAD_SIZE 8 + +#define FUZZ_TIME_DELAY_MIN (4) +#define FUZZ_TIME_DELAY_DEFAULT (8) +#define FUZZ_TIME_DELAY_MAX (80) + +#define FUZZER_APP_CUSTOM_DICT_EXTENSION ".txt" +#define FUZZER_APP_CUSTOM_DICT_FOLDER "/ext/ibtnfuzzer" +#define FUZZER_APP_KEY_EXTENSION ".ibtn" +#define FUZZER_APP_PATH_KEY_FOLDER "/ext/ibutton" + +#endif diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c index f80cc9b29..c18e2cec9 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c @@ -31,21 +31,20 @@ void fuzzer_scene_attack_on_enter(void* context) { FuzzerProtocol proto = fuzzer_proto_items[app->fuzzer_state.proto_index]; - fuzzer_view_attack_reset_data( - app->attack_view, - fuzzer_attack_names[app->fuzzer_state.menu_index], - proto.name, - proto.data_size); - 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); - uint8_t temp_uid[MAX_PAYLOAD_SIZE]; + uint8_t temp_uid[proto.data_size]; fuzzer_worker_get_current_key(app->worker, temp_uid); + fuzzer_view_attack_reset_data( + app->attack_view, + fuzzer_attack_names[app->fuzzer_state.menu_index], + proto.name, + proto.data_size); fuzzer_view_attack_set_attack(app->attack_view, false); fuzzer_view_attack_set_uid(app->attack_view, (uint8_t*)&temp_uid); @@ -73,11 +72,11 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) { } consumed = true; } else if(event.event == FuzzerCustomEventViewAttackOk) { - if(!scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack)) { + if(!scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack) && + fuzzer_worker_start( + app->worker, fuzzer_view_attack_get_time_delay(app->attack_view))) { scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, true); fuzzer_view_attack_set_attack(app->attack_view, true); - fuzzer_worker_start( - app->worker, fuzzer_view_attack_get_time_delay(app->attack_view)); } else { scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, false); fuzzer_view_attack_set_attack(app->attack_view, false); @@ -85,7 +84,7 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) { } consumed = true; } else if(event.event == FuzzerCustomEventViewAttackTick) { - uint8_t temp_uid[MAX_PAYLOAD_SIZE]; + uint8_t temp_uid[fuzzer_proto_items[app->fuzzer_state.proto_index].data_size]; fuzzer_worker_get_current_key(app->worker, temp_uid); diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c index 1caf0b0ed..a42701adf 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c @@ -10,6 +10,26 @@ void fuzzer_scene_main_callback(FuzzerCustomEvent event, void* context) { view_dispatcher_send_custom_event(app->view_dispatcher, event); } +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; +} + void fuzzer_scene_main_on_enter(void* context) { furi_assert(context); PacsFuzzerApp* app = context; @@ -36,16 +56,35 @@ bool fuzzer_scene_main_on_event(void* context, SceneManagerEvent event) { } else if(event.event == FuzzerCustomEventViewMainOk) { fuzzer_view_main_get_state(app->main_view, &app->fuzzer_state); + // TODO error logic + bool loading_ok = false; + switch(app->fuzzer_state.menu_index) { case FuzzerMainMenuIndexDefaultValues: - fuzzer_worker_attack_dict(app->worker, app->fuzzer_state.proto_index); + + loading_ok = fuzzer_worker_attack_dict(app->worker, app->fuzzer_state.proto_index); + + if(!loading_ok) { + // error + } + break; + + case FuzzerMainMenuIndexLoadFileCustomUids: + if(!fuzzer_scene_main_load_custom_dict(app)) { + break; + } else { + loading_ok = fuzzer_worker_attack_file_dict( + app->worker, app->fuzzer_state.proto_index, app->file_path); + } break; default: break; } - scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); + if(loading_ok) { + scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); + } consumed = true; } }