From 70edcf3f6a1797cef169dfe524a3e744be309109 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Sat, 3 Jun 2023 00:32:32 +0300 Subject: [PATCH] Fuzzer App: worker --- applications/external/pacs_fuzzer/fuzzer.c | 4 + applications/external/pacs_fuzzer/fuzzer_i.h | 3 + .../pacs_fuzzer/helpers/fake_worker.c | 183 ++++++++++++++++++ .../pacs_fuzzer/helpers/fake_worker.h | 40 ++++ .../pacs_fuzzer/helpers/fuzzer_custom_event.h | 2 + .../external/pacs_fuzzer/helpers/protocol.h | 2 + .../pacs_fuzzer/scenes/fuzzer_scene_attack.c | 73 ++++++- .../pacs_fuzzer/scenes/fuzzer_scene_main.c | 13 ++ .../external/pacs_fuzzer/views/attack.c | 21 +- .../external/pacs_fuzzer/views/attack.h | 6 +- 10 files changed, 336 insertions(+), 11 deletions(-) create mode 100644 applications/external/pacs_fuzzer/helpers/fake_worker.c create mode 100644 applications/external/pacs_fuzzer/helpers/fake_worker.h diff --git a/applications/external/pacs_fuzzer/fuzzer.c b/applications/external/pacs_fuzzer/fuzzer.c index 42c7d1e47..5a6a4c9b6 100644 --- a/applications/external/pacs_fuzzer/fuzzer.c +++ b/applications/external/pacs_fuzzer/fuzzer.c @@ -25,6 +25,8 @@ PacsFuzzerApp* fuzzer_app_alloc() { app->fuzzer_state.menu_index = 0; app->fuzzer_state.proto_index = 0; + app->worker = fuzzer_worker_alloc(); + // GUI app->gui = furi_record_open(RECORD_GUI); @@ -76,6 +78,8 @@ void fuzzer_app_free(PacsFuzzerApp* app) { // Close records furi_record_close(RECORD_GUI); + fuzzer_worker_free(app->worker); + free(app); } diff --git a/applications/external/pacs_fuzzer/fuzzer_i.h b/applications/external/pacs_fuzzer/fuzzer_i.h index 8f84a558d..bd4833c5b 100644 --- a/applications/external/pacs_fuzzer/fuzzer_i.h +++ b/applications/external/pacs_fuzzer/fuzzer_i.h @@ -10,6 +10,7 @@ #include "views/attack.h" #include "helpers/fuzzer_types.h" +#include "helpers/fake_worker.h" #include @@ -22,4 +23,6 @@ typedef struct { FuzzerViewAttack* attack_view; FuzzerState fuzzer_state; + + FuzzerWorker* worker; } PacsFuzzerApp; \ No newline at end of file diff --git a/applications/external/pacs_fuzzer/helpers/fake_worker.c b/applications/external/pacs_fuzzer/helpers/fake_worker.c new file mode 100644 index 000000000..15e3e035a --- /dev/null +++ b/applications/external/pacs_fuzzer/helpers/fake_worker.c @@ -0,0 +1,183 @@ +#include "fake_worker.h" + +#include +#include + +#include +#include + +#include + +struct FuzzerWorker { + iButtonWorker* proto_worker; + iButtonProtocolId protocol_id; + iButtonProtocols* protocols_items; + iButtonKey* key; + + const FuzzerProtocol* protocol; + FuzzerWorkerAttackType attack_type; + uint8_t timeer_delay; + + uint8_t payload[MAX_PAYLOAD_SIZE]; + Stream* uids_stream; + uint16_t index; + + bool treead_running; + FuriTimer* timer; + + FuzzerWorkerUidChagedCallback tick_callback; + void* tick_context; + + FuzzerWorkerEndCallback end_callback; + void* end_context; +}; + +static bool fuzzer_worker_load_key(FuzzerWorker* worker, bool next) { + furi_assert(worker); + furi_assert(worker->protocol); + bool res = false; + + const FuzzerProtocol* protocol = worker->protocol; + + if(next) { + worker->index++; + } + + switch(worker->attack_type) { + case FuzzerWorkerAttackTypeDefaultDict: + if(worker->index < protocol->dict.len) { + memcpy( + worker->payload, + &protocol->dict.val[worker->index * protocol->data_size], + protocol->data_size); + res = true; + } + break; + + default: + break; + } + + return res; +} + +static void fuzzer_worker_on_tick_callback(void* context) { + furi_assert(context); + + FuzzerWorker* worker = context; + + if(!fuzzer_worker_load_key(worker, true)) { + fuzzer_worker_stop(worker); + if(worker->end_callback) { + worker->end_callback(worker->end_context); + } + } else { + if(worker->tick_callback) { + worker->tick_callback(worker->tick_context); + } + } + + // TODO load ibutton key +} + +void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key) { + furi_assert(worker); + furi_assert(worker->protocol); + + memcpy(key, worker->payload, worker->protocol->data_size); +} + +bool fuzzer_worker_attack_dict(FuzzerWorker* worker, FuzzerProtos protocol_index) { + furi_assert(worker); + + worker->attack_type = FuzzerWorkerAttackTypeDefaultDict; + worker->protocol = &fuzzer_proto_items[protocol_index]; + worker->index = 0; + + return fuzzer_worker_load_key(worker, false); +} + +FuzzerWorker* fuzzer_worker_alloc() { + FuzzerWorker* worker = malloc(sizeof(FuzzerWorker)); + + worker->protocols_items = ibutton_protocols_alloc(); + worker->key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(worker->protocols_items)); + + worker->proto_worker = ibutton_worker_alloc(worker->protocols_items); + + worker->index = 0; + worker->treead_running = false; + + memset(worker->payload, 0x00, sizeof(worker->payload)); + + worker->timeer_delay = FUZZ_TIME_DELAY_DEFAULT; + + worker->timer = + furi_timer_alloc(fuzzer_worker_on_tick_callback, FuriTimerTypePeriodic, worker); + + return worker; +} + +void fuzzer_worker_free(FuzzerWorker* worker) { + furi_assert(worker); + + fuzzer_worker_stop(worker); + + furi_timer_free(worker->timer); + + ibutton_worker_free(worker->proto_worker); + + ibutton_key_free(worker->key); + ibutton_protocols_free(worker->protocols_items); + // TODO delete + UNUSED(fuzzer_worker_on_tick_callback); + free(worker); +} + +void fuzzer_worker_start(FuzzerWorker* worker, uint8_t timer_dellay) { + furi_assert(worker); + + worker->timeer_delay = timer_dellay; + + furi_timer_start(worker->timer, furi_ms_to_ticks(timer_dellay * 100)); + + // TODO start timer + // worker->treead_running = true; + // ibutton_worker_start_thread(worker->proto_worker); + + // TODO load ibutton key + + // ibutton_worker_emulate_start(worker->proto_worker, worker->key); +} + +void fuzzer_worker_stop(FuzzerWorker* worker) { + furi_assert(worker); + + furi_timer_stop(worker->timer); + + if(worker->treead_running) { + ibutton_worker_stop(worker->proto_worker); + ibutton_worker_stop_thread(worker->proto_worker); + worker->treead_running = false; + } + + // TODO stop timer, anything else +} + +void fuzzer_worker_set_uid_chaged_callback( + FuzzerWorker* worker, + FuzzerWorkerUidChagedCallback callback, + void* context) { + furi_assert(worker); + worker->tick_callback = callback; + worker->tick_context = context; +} + +void fuzzer_worker_set_end_callback( + FuzzerWorker* worker, + FuzzerWorkerEndCallback callback, + void* context) { + furi_assert(worker); + worker->end_callback = callback; + worker->end_context = context; +} diff --git a/applications/external/pacs_fuzzer/helpers/fake_worker.h b/applications/external/pacs_fuzzer/helpers/fake_worker.h new file mode 100644 index 000000000..00e3cb23f --- /dev/null +++ b/applications/external/pacs_fuzzer/helpers/fake_worker.h @@ -0,0 +1,40 @@ +#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; + +FuzzerWorker* fuzzer_worker_alloc(); + +void fuzzer_worker_free(FuzzerWorker* worker); + +void 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); + +void fuzzer_worker_get_current_key(FuzzerWorker* worker, uint8_t* key); + +void fuzzer_worker_set_uid_chaged_callback( + FuzzerWorker* worker, + FuzzerWorkerUidChagedCallback callback, + void* context); + +void fuzzer_worker_set_end_callback( + FuzzerWorker* worker, + FuzzerWorkerEndCallback callback, + void* context); \ No newline at end of file diff --git a/applications/external/pacs_fuzzer/helpers/fuzzer_custom_event.h b/applications/external/pacs_fuzzer/helpers/fuzzer_custom_event.h index 189d72ef4..890d961db 100644 --- a/applications/external/pacs_fuzzer/helpers/fuzzer_custom_event.h +++ b/applications/external/pacs_fuzzer/helpers/fuzzer_custom_event.h @@ -8,4 +8,6 @@ typedef enum { FuzzerCustomEventViewAttackBack, FuzzerCustomEventViewAttackOk, + FuzzerCustomEventViewAttackTick, + FuzzerCustomEventViewAttackEnd, } FuzzerCustomEvent; \ No newline at end of file diff --git a/applications/external/pacs_fuzzer/helpers/protocol.h b/applications/external/pacs_fuzzer/helpers/protocol.h index aedeedd8d..c0dd5dd15 100644 --- a/applications/external/pacs_fuzzer/helpers/protocol.h +++ b/applications/external/pacs_fuzzer/helpers/protocol.h @@ -2,6 +2,8 @@ #include +#define MAX_PAYLOAD_SIZE 8 + #define FUZZ_TIME_DELAY_MIN (4) #define FUZZ_TIME_DELAY_DEFAULT (8) #define FUZZ_TIME_DELAY_MAX (80) diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c index 71d38650c..f80cc9b29 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_attack.c @@ -1,9 +1,22 @@ #include "../fuzzer_i.h" #include "../helpers/fuzzer_custom_event.h" -#include "../helpers/protocol.h" #include "../helpers/gui_const.h" +// TODO simlify callbacks and attack state + +void fuzzer_scene_attack_worker_tick_callback(void* context) { + furi_assert(context); + PacsFuzzerApp* app = context; + 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; @@ -23,7 +36,20 @@ void fuzzer_scene_attack_on_enter(void* context) { fuzzer_attack_names[app->fuzzer_state.menu_index], proto.name, proto.data_size); - fuzzer_view_attack_set_uid(app->attack_view, &proto.dict.val[0], false); + + 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]; + + fuzzer_worker_get_current_key(app->worker, temp_uid); + + fuzzer_view_attack_set_attack(app->attack_view, false); + fuzzer_view_attack_set_uid(app->attack_view, (uint8_t*)&temp_uid); + + scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, false); view_dispatcher_switch_to_view(app->view_dispatcher, FuzzerViewIDAttack); } @@ -35,11 +61,40 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == FuzzerCustomEventViewAttackBack) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); + if(!scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack)) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + } else { + scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, false); + fuzzer_view_attack_set_attack(app->attack_view, false); + fuzzer_worker_stop(app->worker); } consumed = true; + } else if(event.event == FuzzerCustomEventViewAttackOk) { + if(!scene_manager_get_scene_state(app->scene_manager, FuzzerSceneAttack)) { + 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); + fuzzer_worker_stop(app->worker); + } + consumed = true; + } else if(event.event == FuzzerCustomEventViewAttackTick) { + uint8_t temp_uid[MAX_PAYLOAD_SIZE]; + + fuzzer_worker_get_current_key(app->worker, temp_uid); + + fuzzer_view_attack_set_uid(app->attack_view, (uint8_t*)&temp_uid); + consumed = true; + } else if(event.event == FuzzerCustomEventViewAttackEnd) { + scene_manager_set_scene_state(app->scene_manager, FuzzerSceneAttack, false); + fuzzer_view_attack_set_attack(app->attack_view, false); + consumed = true; } } @@ -47,7 +102,9 @@ bool fuzzer_scene_attack_on_event(void* context, SceneManagerEvent event) { } void fuzzer_scene_attack_on_exit(void* context) { - // furi_assert(context); - // PacsFuzzerApp* app = context; - UNUSED(context); + furi_assert(context); + PacsFuzzerApp* app = context; + + fuzzer_worker_set_uid_chaged_callback(app->worker, NULL, NULL); + fuzzer_worker_set_end_callback(app->worker, NULL, NULL); } diff --git a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c index 812e063ab..00ecdc543 100644 --- a/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c +++ b/applications/external/pacs_fuzzer/scenes/fuzzer_scene_main.c @@ -1,6 +1,9 @@ #include "../fuzzer_i.h" #include "../helpers/fuzzer_custom_event.h" +#include "../helpers/protocol.h" +#include "../helpers/gui_const.h" + void fuzzer_scene_main_callback(FuzzerCustomEvent event, void* context) { furi_assert(context); PacsFuzzerApp* app = context; @@ -32,6 +35,16 @@ bool fuzzer_scene_main_on_event(void* context, SceneManagerEvent event) { consumed = true; } else if(event.event == FuzzerCustomEventViewMainOk) { fuzzer_view_main_get_state(app->main_view, &app->fuzzer_state); + + switch(app->fuzzer_state.menu_index) { + case FuzzerMainMenuIndexDefaultValues: + fuzzer_worker_attack_dict(app->worker, app->fuzzer_state.proto_index); + break; + + default: + break; + } + scene_manager_next_scene(app->scene_manager, FuzzerSceneAttack); consumed = true; } diff --git a/applications/external/pacs_fuzzer/views/attack.c b/applications/external/pacs_fuzzer/views/attack.c index a83740f3d..57dd4dd4b 100644 --- a/applications/external/pacs_fuzzer/views/attack.c +++ b/applications/external/pacs_fuzzer/views/attack.c @@ -42,7 +42,7 @@ void fuzzer_view_attack_reset_data( true); } -void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const uint8_t* uid, bool attack) { +void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const uint8_t* uid) { furi_assert(view); with_view_model( @@ -61,11 +61,17 @@ void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const uint8_t* uid, bool uid[5], uid[6], uid[7]); - model->attack_enabled = attack; }, true); } +void fuzzer_view_attack_set_attack(FuzzerViewAttack* view, bool attack) { + furi_assert(view); + + with_view_model( + view->view, FuzzerViewAttackModel * model, { model->attack_enabled = attack; }, true); +} + void fuzzer_view_attack_set_callback( FuzzerViewAttack* view_attack, FuzzerViewAttackCallback callback, @@ -96,6 +102,7 @@ void fuzzer_view_attack_draw(Canvas* canvas, FuzzerViewAttackModel* model) { } canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, model->uid); + canvas_set_font(canvas, FontSecondary); if(model->attack_enabled) { elements_button_center(canvas, "Stop"); } else { @@ -209,4 +216,14 @@ void fuzzer_view_attack_free(FuzzerViewAttack* 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; } \ No newline at end of file diff --git a/applications/external/pacs_fuzzer/views/attack.h b/applications/external/pacs_fuzzer/views/attack.h index 082b7ba36..c8204eb18 100644 --- a/applications/external/pacs_fuzzer/views/attack.h +++ b/applications/external/pacs_fuzzer/views/attack.h @@ -24,4 +24,8 @@ void fuzzer_view_attack_reset_data( const char* protocol_name, uint8_t uid_size); -void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const uint8_t* uid, bool attack); \ No newline at end of file +void fuzzer_view_attack_set_uid(FuzzerViewAttack* view, const uint8_t* uid); + +void fuzzer_view_attack_set_attack(FuzzerViewAttack* view, bool attack); + +uint8_t fuzzer_view_attack_get_time_delay(FuzzerViewAttack* view); \ No newline at end of file