This commit is contained in:
MX
2023-07-13 23:53:46 +03:00
parent ec588935b5
commit 090a912f93
31 changed files with 0 additions and 2951 deletions

View File

@@ -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",
)

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -1,17 +0,0 @@
#pragma once
typedef enum {
// FuzzerCustomEvent
FuzzerCustomEventViewMainBack = 100,
FuzzerCustomEventViewMainOk,
FuzzerCustomEventViewMainPopupErr,
FuzzerCustomEventViewAttackBack,
FuzzerCustomEventViewAttackOk,
// FuzzerCustomEventViewAttackTick, // now not use
FuzzerCustomEventViewAttackEnd,
FuzzerCustomEventViewFieldEditorBack,
FuzzerCustomEventViewFieldEditorOk,
} FuzzerCustomEvent;

View File

@@ -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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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[];

View File

@@ -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,
};

View File

@@ -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

View File

@@ -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);
}

View File

@@ -1,3 +0,0 @@
ADD_SCENE(fuzzer, main, Main)
ADD_SCENE(fuzzer, attack, Attack)
ADD_SCENE(fuzzer, field_editor, FieldEditor)

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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`

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);