remove
@@ -1,49 +0,0 @@
|
||||
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="iButton",
|
||||
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="RFID",
|
||||
fap_private_libs=[
|
||||
Lib(
|
||||
name="worker",
|
||||
cdefines=["RFID_125_PROTOCOL"],
|
||||
),
|
||||
],
|
||||
fap_icon_assets="icons",
|
||||
fap_icon_assets_symbol="fuzzer",
|
||||
)
|
||||
160
applications/external/multi_fuzzer/fuzzer.c
vendored
@@ -1,160 +0,0 @@
|
||||
#include "fuzzer_i.h"
|
||||
#include "helpers/fuzzer_types.h"
|
||||
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
55
applications/external/multi_fuzzer/fuzzer_i.h
vendored
@@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/popup.h>
|
||||
|
||||
#include <dialogs/dialogs.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#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 <flipper_format/flipper_format_i.h>
|
||||
#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;
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
|
||||
// FuzzerCustomEvent
|
||||
FuzzerCustomEventViewMainBack = 100,
|
||||
FuzzerCustomEventViewMainOk,
|
||||
FuzzerCustomEventViewMainPopupErr,
|
||||
|
||||
FuzzerCustomEventViewAttackBack,
|
||||
FuzzerCustomEventViewAttackOk,
|
||||
// FuzzerCustomEventViewAttackTick, // now not use
|
||||
FuzzerCustomEventViewAttackEnd,
|
||||
|
||||
FuzzerCustomEventViewFieldEditorBack,
|
||||
FuzzerCustomEventViewFieldEditorOk,
|
||||
} FuzzerCustomEvent;
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
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;
|
||||
|
Before Width: | Height: | Size: 308 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 304 B |
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -1,485 +0,0 @@
|
||||
#include "fake_worker.h"
|
||||
#include "protocol_i.h"
|
||||
|
||||
#include <timer.h>
|
||||
|
||||
#include <lib/toolbox/hex.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include <toolbox/stream/buffered_file_stream.h>
|
||||
|
||||
#define TAG "Fuzzer worker"
|
||||
|
||||
#if defined(RFID_125_PROTOCOL)
|
||||
|
||||
#include <lib/lfrfid/lfrfid_dict_file.h>
|
||||
#include <lib/lfrfid/lfrfid_worker.h>
|
||||
#include <lfrfid/protocols/lfrfid_protocols.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <lib/ibutton/ibutton_worker.h>
|
||||
#include <lib/ibutton/ibutton_key.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <toolbox/stream/stream.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#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);
|
||||
@@ -1,291 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// #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();
|
||||
@@ -1,43 +0,0 @@
|
||||
#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[];
|
||||
@@ -1,30 +0,0 @@
|
||||
#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,
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// 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
|
||||
@@ -1,162 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
ADD_SCENE(fuzzer, main, Main)
|
||||
ADD_SCENE(fuzzer, attack, Attack)
|
||||
ADD_SCENE(fuzzer, field_editor, FieldEditor)
|
||||
@@ -1,66 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
44
applications/external/multi_fuzzer/todo.md
vendored
@@ -1,44 +0,0 @@
|
||||
## 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`
|
||||
384
applications/external/multi_fuzzer/views/attack.c
vendored
@@ -1,384 +0,0 @@
|
||||
#include "attack.h"
|
||||
#include "../fuzzer_i.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
|
||||
#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);
|
||||
@@ -1,358 +0,0 @@
|
||||
#include "field_editor.h"
|
||||
#include "../fuzzer_i.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <toolbox/hex.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#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);
|
||||
235
applications/external/multi_fuzzer/views/main_menu.c
vendored
@@ -1,235 +0,0 @@
|
||||
#include "main_menu.h"
|
||||
#include "../fuzzer_i.h"
|
||||
|
||||
#include <input/input.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#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);
|
||||