Rename and remove old apps
|
@ -134,7 +134,8 @@ You can support us by using links or addresses below:
|
||||||
|
|
||||||
### Community apps included:
|
### Community apps included:
|
||||||
|
|
||||||
- **RFID Fuzzer** [(by Ganapati & @xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/54) & New protocols by @mvanzanten
|
- **RFID Fuzzer** [(by @gid9798)](https://github.com/DarkFlippers/unleashed-firmware/pull/507) (original by Ganapati & xMasterX)
|
||||||
|
- **iButton Fuzzer** [(by @gid9798)](https://github.com/DarkFlippers/unleashed-firmware/pull/507) (original by xMasterX)
|
||||||
- **Sub-GHz bruteforcer** [(by @derskythe & xMasterX)](https://github.com/derskythe/flipperzero-subbrute) [(original by Ganapati & xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/57)
|
- **Sub-GHz bruteforcer** [(by @derskythe & xMasterX)](https://github.com/derskythe/flipperzero-subbrute) [(original by Ganapati & xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/57)
|
||||||
- **Sub-GHz playlist** [(by darmiel)](https://github.com/DarkFlippers/unleashed-firmware/pull/62)
|
- **Sub-GHz playlist** [(by darmiel)](https://github.com/DarkFlippers/unleashed-firmware/pull/62)
|
||||||
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
|
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
|
||||||
|
@ -157,7 +158,6 @@ You can support us by using links or addresses below:
|
||||||
- Morse Code [(by wh00hw)](https://github.com/wh00hw/MorseCodeFAP)
|
- Morse Code [(by wh00hw)](https://github.com/wh00hw/MorseCodeFAP)
|
||||||
- **Unitemp - Temperature sensors reader** (DHT11/22, DS18B20, BMP280, HTU21x and more) [(by quen0n)](https://github.com/quen0n/unitemp-flipperzero)
|
- **Unitemp - Temperature sensors reader** (DHT11/22, DS18B20, BMP280, HTU21x and more) [(by quen0n)](https://github.com/quen0n/unitemp-flipperzero)
|
||||||
- BH1750 - Lightmeter [(by oleksiikutuzov)](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
|
- BH1750 - Lightmeter [(by oleksiikutuzov)](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
|
||||||
- **iButton Fuzzer** [(by xMasterX)](https://github.com/xMasterX/ibutton-fuzzer)
|
|
||||||
- HEX Viewer [(by QtRoS)](https://github.com/QtRoS/flipper-zero-hex-viewer)
|
- HEX Viewer [(by QtRoS)](https://github.com/QtRoS/flipper-zero-hex-viewer)
|
||||||
- POCSAG Pager [(by xMasterX & Shmuma)](https://github.com/xMasterX/flipper-pager)
|
- POCSAG Pager [(by xMasterX & Shmuma)](https://github.com/xMasterX/flipper-pager)
|
||||||
- Text Viewer [(by kowalski7cc & kyhwana)](https://github.com/kowalski7cc/flipper-zero-text-viewer/tree/refactor-text-app)
|
- Text Viewer [(by kowalski7cc & kyhwana)](https://github.com/kowalski7cc/flipper-zero-text-viewer/tree/refactor-text-app)
|
||||||
|
|
8
applications/external/flipfrid/LICENSE.md
vendored
|
@ -1,8 +0,0 @@
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
||||||
* @G4N4P4T1 wrote this file. As long as you retain this notice you
|
|
||||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
||||||
* this stuff is worth it, you can buy me a beer in return.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
36
applications/external/flipfrid/README.md
vendored
|
@ -1,36 +0,0 @@
|
||||||
# Flipfrid
|
|
||||||
|
|
||||||
Basic LFRFID Fuzzer.
|
|
||||||
|
|
||||||
## Why
|
|
||||||
|
|
||||||
Flipfrid is a simple Rfid fuzzer using lfrfid protocols (125khz).
|
|
||||||
Objective is to provide a simple to use fuzzer to test readers by emulating various cards.
|
|
||||||
|
|
||||||
- EM4100 cards use a 1 byte customer id and 4 bytes card id.
|
|
||||||
- HIDProx cards use a 2 byte customer id and 3 byte card id.
|
|
||||||
|
|
||||||
## How
|
|
||||||
|
|
||||||
1) Select the Protocol with the left and right arrows
|
|
||||||
2) Select the Mode with the up and down arrows
|
|
||||||
3) Set TD (Time delay) between ID switch if you need, or left it as is
|
|
||||||
4) Click Start
|
|
||||||
|
|
||||||
### Info
|
|
||||||
|
|
||||||
There are 4 Protocols:
|
|
||||||
- EM4100
|
|
||||||
- HIDProx
|
|
||||||
- PAC/Stanley
|
|
||||||
- H10301
|
|
||||||
|
|
||||||
There are 4 modes:
|
|
||||||
- Default Values: Try factory/default keys and emulate one after the other.
|
|
||||||
- BF customer id: An iteration from 0X00 to 0XFF on the first byte.
|
|
||||||
- Load Dump file: Load an existing dump (.rfid) generated by Flipperzero, select an index and bruteforce from 0X00 to 0XFF;
|
|
||||||
- Uids list: Iterate over an input text file (one uid per line) and emulate one after the other.
|
|
||||||
|
|
||||||
|
|
||||||
TODO :
|
|
||||||
- Add second byte test to `BF customer id`
|
|
12
applications/external/flipfrid/application.fam
vendored
|
@ -1,12 +0,0 @@
|
||||||
App(
|
|
||||||
appid="rfid_fuzzer",
|
|
||||||
name="RFID Fuzzer",
|
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
|
||||||
entry_point="flipfrid_start",
|
|
||||||
requires=["gui", "storage", "dialogs", "input", "notification"],
|
|
||||||
stack_size=2 * 1024,
|
|
||||||
order=15,
|
|
||||||
fap_icon="rfid_10px.png",
|
|
||||||
fap_category="Tools",
|
|
||||||
fap_icon_assets="images",
|
|
||||||
)
|
|
276
applications/external/flipfrid/flipfrid.c
vendored
|
@ -1,276 +0,0 @@
|
||||||
#include "flipfrid.h"
|
|
||||||
|
|
||||||
#include "scene/flipfrid_scene_entrypoint.h"
|
|
||||||
#include "scene/flipfrid_scene_load_file.h"
|
|
||||||
#include "scene/flipfrid_scene_select_field.h"
|
|
||||||
#include "scene/flipfrid_scene_run_attack.h"
|
|
||||||
#include "scene/flipfrid_scene_load_custom_uids.h"
|
|
||||||
|
|
||||||
#define RFIDFUZZER_APP_FOLDER "/ext/rfidfuzzer"
|
|
||||||
|
|
||||||
static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) {
|
|
||||||
furi_assert(ctx);
|
|
||||||
FlipFridState* flipfrid_state = ctx;
|
|
||||||
furi_mutex_acquire(flipfrid_state->mutex, FuriWaitForever);
|
|
||||||
|
|
||||||
// Draw correct Canvas
|
|
||||||
switch(flipfrid_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
flipfrid_scene_entrypoint_on_draw(canvas, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
flipfrid_scene_load_file_on_draw(canvas, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
flipfrid_scene_select_field_on_draw(canvas, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
flipfrid_scene_load_custom_uids_on_draw(canvas, flipfrid_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_mutex_release(flipfrid_state->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
|
||||||
furi_assert(event_queue);
|
|
||||||
|
|
||||||
FlipFridEvent event = {
|
|
||||||
.evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type};
|
|
||||||
furi_message_queue_put(event_queue, &event, 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void flipfrid_timer_callback(FuriMessageQueue* event_queue) {
|
|
||||||
furi_assert(event_queue);
|
|
||||||
FlipFridEvent event = {
|
|
||||||
.evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease};
|
|
||||||
furi_message_queue_put(event_queue, &event, 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlipFridState* flipfrid_alloc() {
|
|
||||||
FlipFridState* flipfrid = malloc(sizeof(FlipFridState));
|
|
||||||
flipfrid->notification_msg = furi_string_alloc();
|
|
||||||
flipfrid->attack_name = furi_string_alloc();
|
|
||||||
flipfrid->proto_name = furi_string_alloc();
|
|
||||||
flipfrid->data_str = furi_string_alloc();
|
|
||||||
|
|
||||||
flipfrid->main_menu_items[0] = furi_string_alloc_set("Default Values");
|
|
||||||
flipfrid->main_menu_items[1] = furi_string_alloc_set("BF Customer ID");
|
|
||||||
flipfrid->main_menu_items[2] = furi_string_alloc_set("Load File");
|
|
||||||
flipfrid->main_menu_items[3] = furi_string_alloc_set("Load UIDs from file");
|
|
||||||
|
|
||||||
flipfrid->main_menu_proto_items[0] = furi_string_alloc_set("EM4100");
|
|
||||||
flipfrid->main_menu_proto_items[1] = furi_string_alloc_set("HIDProx");
|
|
||||||
flipfrid->main_menu_proto_items[2] = furi_string_alloc_set("PAC/Stanley");
|
|
||||||
flipfrid->main_menu_proto_items[3] = furi_string_alloc_set("H10301");
|
|
||||||
|
|
||||||
flipfrid->previous_scene = NoneScene;
|
|
||||||
flipfrid->current_scene = SceneEntryPoint;
|
|
||||||
flipfrid->is_running = true;
|
|
||||||
flipfrid->is_attacking = false;
|
|
||||||
flipfrid->key_index = 0;
|
|
||||||
flipfrid->menu_index = 0;
|
|
||||||
flipfrid->menu_proto_index = 0;
|
|
||||||
|
|
||||||
flipfrid->attack = FlipFridAttackDefaultValues;
|
|
||||||
flipfrid->notify = furi_record_open(RECORD_NOTIFICATION);
|
|
||||||
|
|
||||||
flipfrid->data[0] = 0x00;
|
|
||||||
flipfrid->data[1] = 0x00;
|
|
||||||
flipfrid->data[2] = 0x00;
|
|
||||||
flipfrid->data[3] = 0x00;
|
|
||||||
flipfrid->data[4] = 0x00;
|
|
||||||
flipfrid->data[5] = 0x00;
|
|
||||||
|
|
||||||
flipfrid->payload[0] = 0x00;
|
|
||||||
flipfrid->payload[1] = 0x00;
|
|
||||||
flipfrid->payload[2] = 0x00;
|
|
||||||
flipfrid->payload[3] = 0x00;
|
|
||||||
flipfrid->payload[4] = 0x00;
|
|
||||||
flipfrid->payload[5] = 0x00;
|
|
||||||
|
|
||||||
//Dialog
|
|
||||||
flipfrid->dialogs = furi_record_open(RECORD_DIALOGS);
|
|
||||||
|
|
||||||
return flipfrid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_free(FlipFridState* flipfrid) {
|
|
||||||
//Dialog
|
|
||||||
furi_record_close(RECORD_DIALOGS);
|
|
||||||
notification_message(flipfrid->notify, &sequence_blink_stop);
|
|
||||||
|
|
||||||
// Strings
|
|
||||||
furi_string_free(flipfrid->notification_msg);
|
|
||||||
furi_string_free(flipfrid->attack_name);
|
|
||||||
furi_string_free(flipfrid->proto_name);
|
|
||||||
furi_string_free(flipfrid->data_str);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
furi_string_free(flipfrid->main_menu_items[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
furi_string_free(flipfrid->main_menu_proto_items[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The rest
|
|
||||||
free(flipfrid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ENTRYPOINT
|
|
||||||
int32_t flipfrid_start(void* p) {
|
|
||||||
UNUSED(p);
|
|
||||||
// Input
|
|
||||||
FURI_LOG_I(TAG, "Initializing input");
|
|
||||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(FlipFridEvent));
|
|
||||||
FlipFridState* flipfrid_state = flipfrid_alloc();
|
|
||||||
|
|
||||||
flipfrid_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
|
||||||
if(!flipfrid_state->mutex) {
|
|
||||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
|
||||||
furi_message_queue_free(event_queue);
|
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
|
||||||
flipfrid_free(flipfrid_state);
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
if(!storage_simply_mkdir(storage, RFIDFUZZER_APP_FOLDER)) {
|
|
||||||
FURI_LOG_E(TAG, "Could not create folder %s", RFIDFUZZER_APP_FOLDER);
|
|
||||||
}
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
|
|
||||||
// Configure view port
|
|
||||||
FURI_LOG_I(TAG, "Initializing viewport");
|
|
||||||
ViewPort* view_port = view_port_alloc();
|
|
||||||
view_port_draw_callback_set(view_port, flipfrid_draw_callback, flipfrid_state);
|
|
||||||
view_port_input_callback_set(view_port, flipfrid_input_callback, event_queue);
|
|
||||||
|
|
||||||
// Configure timer
|
|
||||||
FURI_LOG_I(TAG, "Initializing timer");
|
|
||||||
FuriTimer* timer =
|
|
||||||
furi_timer_alloc(flipfrid_timer_callback, FuriTimerTypePeriodic, event_queue);
|
|
||||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second
|
|
||||||
|
|
||||||
// Register view port in GUI
|
|
||||||
FURI_LOG_I(TAG, "Initializing gui");
|
|
||||||
Gui* gui = (Gui*)furi_record_open(RECORD_GUI);
|
|
||||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
|
||||||
|
|
||||||
// Init values
|
|
||||||
FlipFridEvent event;
|
|
||||||
while(flipfrid_state->is_running) {
|
|
||||||
// Get next event
|
|
||||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25);
|
|
||||||
if(event_status == FuriStatusOk) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
//Handle event key
|
|
||||||
switch(flipfrid_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
flipfrid_scene_entrypoint_on_event(event, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
flipfrid_scene_load_file_on_event(event, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
flipfrid_scene_select_field_on_event(event, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
flipfrid_scene_run_attack_on_event(event, flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
flipfrid_scene_load_custom_uids_on_event(event, flipfrid_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(event.evt_type == EventTypeTick) {
|
|
||||||
//Handle event tick
|
|
||||||
if(flipfrid_state->current_scene != flipfrid_state->previous_scene) {
|
|
||||||
// Trigger Exit Scene
|
|
||||||
switch(flipfrid_state->previous_scene) {
|
|
||||||
case SceneEntryPoint:
|
|
||||||
flipfrid_scene_entrypoint_on_exit(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
flipfrid_scene_load_file_on_exit(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
flipfrid_scene_select_field_on_exit(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
flipfrid_scene_run_attack_on_exit(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
flipfrid_scene_load_custom_uids_on_exit(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case NoneScene:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger Entry Scene
|
|
||||||
switch(flipfrid_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
flipfrid_scene_entrypoint_on_enter(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
flipfrid_scene_load_file_on_enter(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
flipfrid_scene_select_field_on_enter(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
flipfrid_scene_run_attack_on_enter(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
flipfrid_scene_load_custom_uids_on_enter(flipfrid_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
flipfrid_state->previous_scene = flipfrid_state->current_scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger Tick Scene
|
|
||||||
switch(flipfrid_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
flipfrid_scene_entrypoint_on_tick(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
flipfrid_scene_load_file_on_tick(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
flipfrid_scene_select_field_on_tick(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
flipfrid_scene_run_attack_on_tick(flipfrid_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
flipfrid_scene_load_custom_uids_on_tick(flipfrid_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
view_port_update(view_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
furi_timer_stop(timer);
|
|
||||||
furi_timer_free(timer);
|
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "Cleaning up");
|
|
||||||
gui_remove_view_port(gui, view_port);
|
|
||||||
view_port_free(view_port);
|
|
||||||
furi_message_queue_free(event_queue);
|
|
||||||
furi_record_close(RECORD_GUI);
|
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
|
||||||
furi_mutex_free(flipfrid_state->mutex);
|
|
||||||
flipfrid_free(flipfrid_state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
94
applications/external/flipfrid/flipfrid.h
vendored
|
@ -1,94 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <input/input.h>
|
|
||||||
#include <gui/gui.h>
|
|
||||||
#include <gui/modules/submenu.h>
|
|
||||||
#include <dialogs/dialogs.h>
|
|
||||||
#include <notification/notification.h>
|
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <toolbox/stream/stream.h>
|
|
||||||
#include <flipper_format/flipper_format_i.h>
|
|
||||||
|
|
||||||
#include <toolbox/stream/stream.h>
|
|
||||||
#include <toolbox/stream/string_stream.h>
|
|
||||||
#include <toolbox/stream/file_stream.h>
|
|
||||||
#include <toolbox/stream/buffered_file_stream.h>
|
|
||||||
|
|
||||||
#include <rfid_fuzzer_icons.h>
|
|
||||||
|
|
||||||
#include <lib/lfrfid/lfrfid_worker.h>
|
|
||||||
#include <lfrfid/protocols/lfrfid_protocols.h>
|
|
||||||
|
|
||||||
#define TAG "FlipFrid"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FlipFridAttackDefaultValues,
|
|
||||||
FlipFridAttackBfCustomerId,
|
|
||||||
FlipFridAttackLoadFile,
|
|
||||||
FlipFridAttackLoadFileCustomUids,
|
|
||||||
} FlipFridAttacks;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EM4100,
|
|
||||||
HIDProx,
|
|
||||||
PAC,
|
|
||||||
H10301,
|
|
||||||
} FlipFridProtos;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
NoneScene,
|
|
||||||
SceneEntryPoint,
|
|
||||||
SceneSelectFile,
|
|
||||||
SceneSelectField,
|
|
||||||
SceneAttack,
|
|
||||||
SceneLoadCustomUids,
|
|
||||||
} FlipFridScene;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EventTypeTick,
|
|
||||||
EventTypeKey,
|
|
||||||
} EventType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
EventType evt_type;
|
|
||||||
InputKey key;
|
|
||||||
InputType input_type;
|
|
||||||
} FlipFridEvent;
|
|
||||||
|
|
||||||
// STRUCTS
|
|
||||||
typedef struct {
|
|
||||||
FuriMutex* mutex;
|
|
||||||
bool is_running;
|
|
||||||
bool is_attacking;
|
|
||||||
FlipFridScene current_scene;
|
|
||||||
FlipFridScene previous_scene;
|
|
||||||
NotificationApp* notify;
|
|
||||||
u_int8_t menu_index;
|
|
||||||
u_int8_t menu_proto_index;
|
|
||||||
|
|
||||||
FuriString* data_str;
|
|
||||||
uint8_t data[6];
|
|
||||||
uint8_t payload[6];
|
|
||||||
uint8_t attack_step;
|
|
||||||
FlipFridAttacks attack;
|
|
||||||
FlipFridProtos proto;
|
|
||||||
FuriString* attack_name;
|
|
||||||
FuriString* proto_name;
|
|
||||||
FuriString* main_menu_items[4];
|
|
||||||
FuriString* main_menu_proto_items[4];
|
|
||||||
|
|
||||||
DialogsApp* dialogs;
|
|
||||||
FuriString* notification_msg;
|
|
||||||
uint8_t key_index;
|
|
||||||
LFRFIDWorker* worker;
|
|
||||||
ProtocolDict* dict;
|
|
||||||
ProtocolId protocol;
|
|
||||||
bool workr_rund;
|
|
||||||
bool attack_stop_called;
|
|
||||||
|
|
||||||
uint8_t time_between_cards;
|
|
||||||
|
|
||||||
// Used for custom dictionnary
|
|
||||||
Stream* uids_stream;
|
|
||||||
} FlipFridState;
|
|
|
@ -1,201 +0,0 @@
|
||||||
#include "flipfrid_scene_entrypoint.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_menu_callback(
|
|
||||||
FlipFridState* context,
|
|
||||||
uint32_t index,
|
|
||||||
uint32_t proto_index) {
|
|
||||||
switch(index) {
|
|
||||||
case FlipFridAttackDefaultValues:
|
|
||||||
context->attack = FlipFridAttackDefaultValues;
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
furi_string_set(context->attack_name, "Default Values");
|
|
||||||
break;
|
|
||||||
case FlipFridAttackBfCustomerId:
|
|
||||||
context->attack = FlipFridAttackBfCustomerId;
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
furi_string_set(context->attack_name, "Bad Customer ID");
|
|
||||||
break;
|
|
||||||
case FlipFridAttackLoadFile:
|
|
||||||
context->attack = FlipFridAttackLoadFile;
|
|
||||||
context->current_scene = SceneSelectFile;
|
|
||||||
furi_string_set(context->attack_name, "Load File");
|
|
||||||
break;
|
|
||||||
case FlipFridAttackLoadFileCustomUids:
|
|
||||||
context->attack = FlipFridAttackLoadFileCustomUids;
|
|
||||||
context->current_scene = SceneLoadCustomUids;
|
|
||||||
furi_string_set(context->attack_name, "Load Custom UIDs");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(proto_index) {
|
|
||||||
case EM4100:
|
|
||||||
context->proto = EM4100;
|
|
||||||
furi_string_set(context->proto_name, "EM4100");
|
|
||||||
break;
|
|
||||||
case HIDProx:
|
|
||||||
context->proto = HIDProx;
|
|
||||||
furi_string_set(context->proto_name, "HIDProx");
|
|
||||||
break;
|
|
||||||
case PAC:
|
|
||||||
context->proto = PAC;
|
|
||||||
furi_string_set(context->proto_name, "PAC/Stanley");
|
|
||||||
break;
|
|
||||||
case H10301:
|
|
||||||
context->proto = H10301;
|
|
||||||
furi_string_set(context->proto_name, "H10301");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) {
|
|
||||||
// Clear the previous payload
|
|
||||||
context->payload[0] = 0x00;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
context->payload[3] = 0x00;
|
|
||||||
context->payload[4] = 0x00;
|
|
||||||
context->payload[5] = 0x00;
|
|
||||||
|
|
||||||
context->menu_index = 0;
|
|
||||||
/*for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
menu_items[i] = furi_string_alloc();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
context->menu_proto_index = 0;
|
|
||||||
/*for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
menu_proto_items[i] = furi_string_alloc();
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_tick(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
if(context->menu_index < FlipFridAttackLoadFileCustomUids) {
|
|
||||||
context->menu_index++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
if(context->menu_index > FlipFridAttackDefaultValues) {
|
|
||||||
context->menu_index--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(context->menu_proto_index > EM4100) {
|
|
||||||
context->menu_proto_index--;
|
|
||||||
} else if(context->menu_proto_index == EM4100) {
|
|
||||||
context->menu_proto_index = H10301;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(context->menu_proto_index < H10301) {
|
|
||||||
context->menu_proto_index++;
|
|
||||||
} else if(context->menu_proto_index == H10301) {
|
|
||||||
context->menu_proto_index = EM4100;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
flipfrid_scene_entrypoint_menu_callback(
|
|
||||||
context, context->menu_index, context->menu_proto_index);
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->is_running = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) {
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
if(context->main_menu_items != NULL) {
|
|
||||||
if(context->main_menu_items[context->menu_index] != NULL) {
|
|
||||||
if(context->menu_index > FlipFridAttackDefaultValues) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
24,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index - 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
36,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index]));
|
|
||||||
|
|
||||||
if(context->menu_index < FlipFridAttackLoadFileCustomUids) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
48,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index + 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(context->menu_proto_index > EM4100) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
-12,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(
|
|
||||||
context->main_menu_proto_items[context->menu_proto_index - 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(canvas, 27, 4, AlignCenter, AlignTop, "<");
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
4,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_proto_items[context->menu_proto_index]));
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(canvas, 101, 4, AlignCenter, AlignTop, ">");
|
|
||||||
|
|
||||||
if(context->menu_proto_index < H10301) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
-12,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(
|
|
||||||
context->main_menu_proto_items[context->menu_proto_index + 1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../flipfrid.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_entrypoint_on_enter(FlipFridState* context);
|
|
||||||
void flipfrid_scene_entrypoint_on_exit(FlipFridState* context);
|
|
||||||
void flipfrid_scene_entrypoint_on_tick(FlipFridState* context);
|
|
||||||
void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* context);
|
|
||||||
void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context);
|
|
|
@ -1,85 +0,0 @@
|
||||||
#include "flipfrid_scene_load_custom_uids.h"
|
|
||||||
#include "flipfrid_scene_run_attack.h"
|
|
||||||
#include "flipfrid_scene_entrypoint.h"
|
|
||||||
|
|
||||||
#define LFRFID_UIDS_EXTENSION ".txt"
|
|
||||||
#define RFIDFUZZER_APP_PATH_FOLDER "/ext/rfidfuzzer"
|
|
||||||
|
|
||||||
bool flipfrid_load_uids(FlipFridState* context, const char* file_path) {
|
|
||||||
bool result = false;
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
context->uids_stream = buffered_file_stream_alloc(storage);
|
|
||||||
result =
|
|
||||||
buffered_file_stream_open(context->uids_stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
||||||
// Close if loading fails
|
|
||||||
if(!result) {
|
|
||||||
buffered_file_stream_close(context->uids_stream);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flipfrid_load_custom_uids_from_file(FlipFridState* context) {
|
|
||||||
// Input events and views are managed by file_select
|
|
||||||
FuriString* uid_path;
|
|
||||||
uid_path = furi_string_alloc();
|
|
||||||
furi_string_set(uid_path, RFIDFUZZER_APP_PATH_FOLDER);
|
|
||||||
|
|
||||||
DialogsFileBrowserOptions browser_options;
|
|
||||||
dialog_file_browser_set_basic_options(&browser_options, LFRFID_UIDS_EXTENSION, &I_125_10px);
|
|
||||||
browser_options.base_path = RFIDFUZZER_APP_PATH_FOLDER;
|
|
||||||
browser_options.hide_ext = false;
|
|
||||||
|
|
||||||
bool res = dialog_file_browser_show(context->dialogs, uid_path, uid_path, &browser_options);
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
res = flipfrid_load_uids(context, furi_string_get_cstr(uid_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_free(uid_path);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context) {
|
|
||||||
if(flipfrid_load_custom_uids_from_file(context)) {
|
|
||||||
// Force context loading
|
|
||||||
flipfrid_scene_run_attack_on_enter(context);
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
} else {
|
|
||||||
flipfrid_scene_entrypoint_on_enter(context);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
case InputKeyUp:
|
|
||||||
case InputKeyLeft:
|
|
||||||
case InputKeyRight:
|
|
||||||
case InputKeyOk:
|
|
||||||
case InputKeyBack:
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
UNUSED(canvas);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../flipfrid.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context);
|
|
||||||
bool flipfrid_load_custom_uids_from_file(FlipFridState* context);
|
|
|
@ -1,193 +0,0 @@
|
||||||
#include "flipfrid_scene_load_file.h"
|
|
||||||
#include "flipfrid_scene_entrypoint.h"
|
|
||||||
|
|
||||||
#define LFRFID_APP_EXTENSION ".rfid"
|
|
||||||
#define LFRFID_APP_PATH_FOLDER "/ext/lfrfid"
|
|
||||||
|
|
||||||
bool flipfrid_load(FlipFridState* context, const char* file_path) {
|
|
||||||
bool result = false;
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
||||||
FuriString* temp_str;
|
|
||||||
temp_str = furi_string_alloc();
|
|
||||||
do {
|
|
||||||
if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
|
|
||||||
FURI_LOG_E(TAG, "Error open file %s", file_path);
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Error open file");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileType
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Filetype", temp_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Filetype");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Filetypes");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Filetype: %s", furi_string_get_cstr(temp_str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key type
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Key type", temp_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Key type");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key type: %s", furi_string_get_cstr(temp_str));
|
|
||||||
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "EM4100") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "PAC/Stanley") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "H10301") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "HIDProx") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Data");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Key");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str));
|
|
||||||
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
if(furi_string_size(context->data_str) != 14) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
if(furi_string_size(context->data_str) != 11) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
if(furi_string_size(context->data_str) != 8) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(furi_string_size(context->data_str) != 17) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String to uint8_t
|
|
||||||
for(uint8_t i = 0; i < 6; i++) {
|
|
||||||
char temp_str2[3];
|
|
||||||
temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3];
|
|
||||||
temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1];
|
|
||||||
temp_str2[2] = '\0';
|
|
||||||
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
} while(0);
|
|
||||||
furi_string_free(temp_str);
|
|
||||||
flipper_format_free(fff_data_file);
|
|
||||||
if(result) {
|
|
||||||
FURI_LOG_I(TAG, "Loaded successfully");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Source loaded.");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_enter(FlipFridState* context) {
|
|
||||||
if(flipfrid_load_protocol_from_file(context)) {
|
|
||||||
context->current_scene = SceneSelectField;
|
|
||||||
} else {
|
|
||||||
flipfrid_scene_entrypoint_on_enter(context);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_exit(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_tick(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_event(FlipFridEvent event, FlipFridState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
case InputKeyUp:
|
|
||||||
case InputKeyLeft:
|
|
||||||
case InputKeyRight:
|
|
||||||
case InputKeyOk:
|
|
||||||
case InputKeyBack:
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_draw(Canvas* canvas, FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
UNUSED(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flipfrid_load_protocol_from_file(FlipFridState* context) {
|
|
||||||
FuriString* user_file_path;
|
|
||||||
user_file_path = furi_string_alloc();
|
|
||||||
furi_string_set(user_file_path, LFRFID_APP_PATH_FOLDER);
|
|
||||||
|
|
||||||
DialogsFileBrowserOptions browser_options;
|
|
||||||
dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px);
|
|
||||||
browser_options.base_path = LFRFID_APP_PATH_FOLDER;
|
|
||||||
|
|
||||||
// Input events and views are managed by file_select
|
|
||||||
bool res = dialog_file_browser_show(
|
|
||||||
context->dialogs, user_file_path, user_file_path, &browser_options);
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
res = flipfrid_load(context, furi_string_get_cstr(user_file_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_free(user_file_path);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../flipfrid.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_load_file_on_enter(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_file_on_exit(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_file_on_tick(FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_file_on_event(FlipFridEvent event, FlipFridState* context);
|
|
||||||
void flipfrid_scene_load_file_on_draw(Canvas* canvas, FlipFridState* context);
|
|
||||||
bool flipfrid_load_protocol_from_file(FlipFridState* context);
|
|
|
@ -1,666 +0,0 @@
|
||||||
#include "flipfrid_scene_run_attack.h"
|
|
||||||
#include <gui/elements.h>
|
|
||||||
|
|
||||||
uint8_t counter = 0;
|
|
||||||
|
|
||||||
uint8_t id_list[17][5] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t id_list_hid[14][6] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t id_list_pac[17][4] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t id_list_h[14][3] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_enter(FlipFridState* context) {
|
|
||||||
context->time_between_cards = 10;
|
|
||||||
context->attack_step = 0;
|
|
||||||
context->attack_stop_called = false;
|
|
||||||
context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
|
|
||||||
context->worker = lfrfid_worker_alloc(context->dict);
|
|
||||||
if(context->proto == HIDProx) {
|
|
||||||
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "HIDProx");
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "PAC/Stanley");
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "H10301");
|
|
||||||
} else {
|
|
||||||
context->protocol = protocol_dict_get_protocol_by_name(context->dict, "EM4100");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_exit(FlipFridState* context) {
|
|
||||||
if(context->workr_rund) {
|
|
||||||
lfrfid_worker_stop(context->worker);
|
|
||||||
lfrfid_worker_stop_thread(context->worker);
|
|
||||||
context->workr_rund = false;
|
|
||||||
}
|
|
||||||
lfrfid_worker_free(context->worker);
|
|
||||||
protocol_dict_free(context->dict);
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
|
|
||||||
if(context->is_attacking) {
|
|
||||||
if(1 == counter) {
|
|
||||||
protocol_dict_set_data(context->dict, context->protocol, context->payload, 6);
|
|
||||||
lfrfid_worker_free(context->worker);
|
|
||||||
context->worker = lfrfid_worker_alloc(context->dict);
|
|
||||||
lfrfid_worker_start_thread(context->worker);
|
|
||||||
lfrfid_worker_emulate_start(context->worker, context->protocol);
|
|
||||||
context->workr_rund = true;
|
|
||||||
} else if(0 == counter) {
|
|
||||||
if(context->workr_rund) {
|
|
||||||
lfrfid_worker_stop(context->worker);
|
|
||||||
lfrfid_worker_stop_thread(context->worker);
|
|
||||||
context->workr_rund = false;
|
|
||||||
furi_delay_ms(200);
|
|
||||||
}
|
|
||||||
switch(context->attack) {
|
|
||||||
case FlipFridAttackDefaultValues:
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
context->payload[0] = id_list[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list[context->attack_step][2];
|
|
||||||
context->payload[3] = id_list[context->attack_step][3];
|
|
||||||
context->payload[4] = id_list[context->attack_step][4];
|
|
||||||
|
|
||||||
if(context->attack_step == 16) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
context->payload[0] = id_list_pac[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_pac[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list_pac[context->attack_step][2];
|
|
||||||
context->payload[3] = id_list_pac[context->attack_step][3];
|
|
||||||
|
|
||||||
if(context->attack_step == 16) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
context->payload[0] = id_list_h[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_h[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list_h[context->attack_step][2];
|
|
||||||
|
|
||||||
if(context->attack_step == 13) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->payload[0] = id_list_hid[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_hid[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list_hid[context->attack_step][2];
|
|
||||||
context->payload[3] = id_list_hid[context->attack_step][3];
|
|
||||||
context->payload[4] = id_list_hid[context->attack_step][4];
|
|
||||||
context->payload[5] = id_list_hid[context->attack_step][5];
|
|
||||||
|
|
||||||
if(context->attack_step == 13) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FlipFridAttackBfCustomerId:
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
context->payload[0] = context->attack_step;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
context->payload[3] = 0x00;
|
|
||||||
context->payload[4] = 0x00;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
context->payload[0] = context->attack_step;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
context->payload[3] = 0x00;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
context->payload[0] = context->attack_step;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->payload[0] = context->attack_step;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
context->payload[3] = 0x00;
|
|
||||||
context->payload[4] = 0x00;
|
|
||||||
context->payload[5] = 0x00;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FlipFridAttackLoadFile:
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
context->payload[3] = context->data[3];
|
|
||||||
context->payload[4] = context->data[4];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
context->payload[3] = context->data[3];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
context->payload[3] = context->data[3];
|
|
||||||
context->payload[4] = context->data[4];
|
|
||||||
context->payload[5] = context->data[5];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FlipFridAttackLoadFileCustomUids:
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 11) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(end_of_list) break;
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(furi_string_size(context->data_str) != 11) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 5; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 9) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(end_of_list) break;
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(furi_string_size(context->data_str) != 9) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 4; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 7) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(end_of_list) break;
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(furi_string_size(context->data_str) != 7) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 3; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 13) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(end_of_list) break;
|
|
||||||
if(furi_string_size(context->data_str) != 13) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 6; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(counter > context->time_between_cards) {
|
|
||||||
counter = 0;
|
|
||||||
} else {
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards > 5) {
|
|
||||||
context->time_between_cards--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards < 70) {
|
|
||||||
context->time_between_cards++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
counter = 0;
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
notification_message(context->notify, &sequence_blink_start_blue);
|
|
||||||
context->is_attacking = true;
|
|
||||||
} else {
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->is_attacking = false;
|
|
||||||
counter = 0;
|
|
||||||
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
if(context->attack_stop_called) {
|
|
||||||
context->attack_stop_called = false;
|
|
||||||
context->attack_step = 0;
|
|
||||||
if(context->attack == FlipFridAttackLoadFileCustomUids) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
buffered_file_stream_close(context->uids_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
context->attack_stop_called = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(event.input_type == InputTypeLong) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards > 0) {
|
|
||||||
if((context->time_between_cards - 10) > 5) {
|
|
||||||
context->time_between_cards -= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards < 70) {
|
|
||||||
context->time_between_cards += 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context) {
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
// Frame
|
|
||||||
//canvas_draw_frame(canvas, 0, 0, 128, 64);
|
|
||||||
|
|
||||||
// Title
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(context->attack_name));
|
|
||||||
|
|
||||||
char uid[18];
|
|
||||||
char speed[16];
|
|
||||||
if(context->proto == HIDProx) {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2],
|
|
||||||
context->payload[3],
|
|
||||||
context->payload[4],
|
|
||||||
context->payload[5]);
|
|
||||||
} else if(context->proto == PAC) {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2],
|
|
||||||
context->payload[3]);
|
|
||||||
} else if(context->proto == H10301) {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2]);
|
|
||||||
} else {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2],
|
|
||||||
context->payload[3],
|
|
||||||
context->payload[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, uid);
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 26, AlignCenter, AlignTop, furi_string_get_cstr(context->proto_name));
|
|
||||||
|
|
||||||
snprintf(speed, sizeof(speed), "Time delay: %d", context->time_between_cards);
|
|
||||||
|
|
||||||
//canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Speed:");
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 14, AlignCenter, AlignTop, speed);
|
|
||||||
//char start_stop_msg[20];
|
|
||||||
if(context->is_attacking) {
|
|
||||||
elements_button_center(canvas, "Stop");
|
|
||||||
//snprintf(start_stop_msg, sizeof(start_stop_msg), " Press OK to stop ");
|
|
||||||
} else {
|
|
||||||
elements_button_center(canvas, "Start");
|
|
||||||
elements_button_left(canvas, "TD -");
|
|
||||||
elements_button_right(canvas, "+ TD");
|
|
||||||
}
|
|
||||||
//canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, start_stop_msg);
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../flipfrid.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_run_attack_on_enter(FlipFridState* context);
|
|
||||||
void flipfrid_scene_run_attack_on_exit(FlipFridState* context);
|
|
||||||
void flipfrid_scene_run_attack_on_tick(FlipFridState* context);
|
|
||||||
void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* context);
|
|
||||||
void flipfrid_scene_run_attack_on_draw(Canvas* canvas, FlipFridState* context);
|
|
|
@ -1,160 +0,0 @@
|
||||||
#include "flipfrid_scene_select_field.h"
|
|
||||||
|
|
||||||
void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) {
|
|
||||||
char key_cstr[18];
|
|
||||||
uint8_t key_len = 18;
|
|
||||||
uint8_t str_index = (index * 3);
|
|
||||||
int data_len = sizeof(context->data) / sizeof(context->data[0]);
|
|
||||||
int key_index = 0;
|
|
||||||
|
|
||||||
if(context->proto == EM4100) {
|
|
||||||
key_len = 16;
|
|
||||||
}
|
|
||||||
if(context->proto == PAC) {
|
|
||||||
key_len = 13;
|
|
||||||
}
|
|
||||||
if(context->proto == H10301) {
|
|
||||||
key_len = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->data[i] < 9) {
|
|
||||||
key_index +=
|
|
||||||
snprintf(&key_cstr[key_index], key_len - key_index, "0%X ", context->data[i]);
|
|
||||||
} else {
|
|
||||||
key_index +=
|
|
||||||
snprintf(&key_cstr[key_index], key_len - key_index, "%X ", context->data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char display_menu[17] = {
|
|
||||||
'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
|
|
||||||
|
|
||||||
if(index > 1) {
|
|
||||||
display_menu[0] = key_cstr[str_index - 6];
|
|
||||||
display_menu[1] = key_cstr[str_index - 5];
|
|
||||||
} else {
|
|
||||||
display_menu[0] = ' ';
|
|
||||||
display_menu[1] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(index > 0) {
|
|
||||||
display_menu[3] = key_cstr[str_index - 3];
|
|
||||||
display_menu[4] = key_cstr[str_index - 2];
|
|
||||||
} else {
|
|
||||||
display_menu[3] = ' ';
|
|
||||||
display_menu[4] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
display_menu[7] = key_cstr[str_index];
|
|
||||||
display_menu[8] = key_cstr[str_index + 1];
|
|
||||||
|
|
||||||
if((str_index + 4) <= (uint8_t)strlen(key_cstr)) {
|
|
||||||
display_menu[11] = key_cstr[str_index + 3];
|
|
||||||
display_menu[12] = key_cstr[str_index + 4];
|
|
||||||
} else {
|
|
||||||
display_menu[11] = ' ';
|
|
||||||
display_menu[12] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if((str_index + 8) <= (uint8_t)strlen(key_cstr)) {
|
|
||||||
display_menu[14] = key_cstr[str_index + 6];
|
|
||||||
display_menu[15] = key_cstr[str_index + 7];
|
|
||||||
} else {
|
|
||||||
display_menu[14] = ' ';
|
|
||||||
display_menu[15] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, display_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_enter(FlipFridState* context) {
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_exit(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_tick(FlipFridState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
const char* key_cstr = furi_string_get_cstr(context->data_str);
|
|
||||||
int data_len = sizeof(context->data) / sizeof(context->data[0]);
|
|
||||||
|
|
||||||
// don't look, it's ugly but I'm a python dev so...
|
|
||||||
uint8_t nb_bytes = 0;
|
|
||||||
for(uint8_t i = 0; i < strlen(key_cstr); i++) {
|
|
||||||
if(' ' == key_cstr[i]) {
|
|
||||||
nb_bytes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->key_index == i) {
|
|
||||||
context->data[i] = (context->data[i] - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->key_index == i) {
|
|
||||||
context->data[i] = (context->data[i] + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(context->key_index > 0) {
|
|
||||||
context->key_index = context->key_index - 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(context->key_index < nb_bytes) {
|
|
||||||
context->key_index = context->key_index + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->key_index = 0;
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneSelectFile;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FURI_LOG_D(TAG, "Position: %d/%d", context->key_index, nb_bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_draw(Canvas* canvas, FlipFridState* context) {
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
// Frame
|
|
||||||
//canvas_draw_frame(canvas, 0, 0, 128, 64);
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(canvas, 12, 5, AlignLeft, AlignTop, "Left and right: select byte");
|
|
||||||
canvas_draw_str_aligned(canvas, 12, 15, AlignLeft, AlignTop, "Up and down: adjust byte");
|
|
||||||
|
|
||||||
char msg_index[18];
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
snprintf(msg_index, sizeof(msg_index), "Field index : %d", context->key_index);
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignTop, msg_index);
|
|
||||||
|
|
||||||
flipfrid_center_displayed_key(context, context->key_index);
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 45, AlignCenter, AlignTop, furi_string_get_cstr(context->notification_msg));
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../flipfrid.h"
|
|
||||||
|
|
||||||
void flipfrid_scene_select_field_on_enter(FlipFridState* context);
|
|
||||||
void flipfrid_scene_select_field_on_exit(FlipFridState* context);
|
|
||||||
void flipfrid_scene_select_field_on_tick(FlipFridState* context);
|
|
||||||
void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* context);
|
|
||||||
void flipfrid_scene_select_field_on_draw(Canvas* canvas, FlipFridState* context);
|
|
||||||
void center_displayed_key(FlipFridState* context, uint8_t index);
|
|
8
applications/external/ibtn_fuzzer/LICENSE.md
vendored
|
@ -1,8 +0,0 @@
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
||||||
* @xMasterX and @G4N4P4T1(made original version) wrote this file. As long as you retain this notice you
|
|
||||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
||||||
* this stuff is worth it, you can buy me a beer in return.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
|
@ -1,12 +0,0 @@
|
||||||
App(
|
|
||||||
appid="ibtn_fuzzer",
|
|
||||||
name="iButton Fuzzer",
|
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
|
||||||
entry_point="ibtnfuzzer_start",
|
|
||||||
requires=["gui", "storage", "dialogs", "input", "notification"],
|
|
||||||
stack_size=1 * 1024,
|
|
||||||
order=15,
|
|
||||||
fap_icon="ibutt_10px.png",
|
|
||||||
fap_category="Tools",
|
|
||||||
fap_icon_assets="images",
|
|
||||||
)
|
|
280
applications/external/ibtn_fuzzer/ibtnfuzzer.c
vendored
|
@ -1,280 +0,0 @@
|
||||||
#include "ibtnfuzzer.h"
|
|
||||||
|
|
||||||
#include "scene/ibtnfuzzer_scene_entrypoint.h"
|
|
||||||
#include "scene/ibtnfuzzer_scene_load_file.h"
|
|
||||||
#include "scene/ibtnfuzzer_scene_select_field.h"
|
|
||||||
#include "scene/ibtnfuzzer_scene_run_attack.h"
|
|
||||||
#include "scene/ibtnfuzzer_scene_load_custom_uids.h"
|
|
||||||
|
|
||||||
#define IBTNFUZZER_APP_FOLDER "/ext/ibtnfuzzer"
|
|
||||||
|
|
||||||
static void ibtnfuzzer_draw_callback(Canvas* const canvas, void* ctx) {
|
|
||||||
furi_assert(ctx);
|
|
||||||
iBtnFuzzerState* ibtnfuzzer_state = ctx;
|
|
||||||
furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever);
|
|
||||||
|
|
||||||
// Draw correct Canvas
|
|
||||||
switch(ibtnfuzzer_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_draw(canvas, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
ibtnfuzzer_scene_load_file_on_draw(canvas, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
ibtnfuzzer_scene_select_field_on_draw(canvas, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
ibtnfuzzer_scene_run_attack_on_draw(canvas, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
ibtnfuzzer_scene_load_custom_uids_on_draw(canvas, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_mutex_release(ibtnfuzzer_state->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
|
||||||
furi_assert(event_queue);
|
|
||||||
|
|
||||||
iBtnFuzzerEvent event = {
|
|
||||||
.evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type};
|
|
||||||
furi_message_queue_put(event_queue, &event, 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ibtnfuzzer_timer_callback(FuriMessageQueue* event_queue) {
|
|
||||||
furi_assert(event_queue);
|
|
||||||
iBtnFuzzerEvent event = {
|
|
||||||
.evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease};
|
|
||||||
furi_message_queue_put(event_queue, &event, 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
iBtnFuzzerState* ibtnfuzzer_alloc() {
|
|
||||||
iBtnFuzzerState* ibtnfuzzer = malloc(sizeof(iBtnFuzzerState));
|
|
||||||
ibtnfuzzer->notification_msg = furi_string_alloc();
|
|
||||||
ibtnfuzzer->attack_name = furi_string_alloc();
|
|
||||||
ibtnfuzzer->proto_name = furi_string_alloc();
|
|
||||||
ibtnfuzzer->data_str = furi_string_alloc();
|
|
||||||
|
|
||||||
ibtnfuzzer->main_menu_items[0] = furi_string_alloc_set("Default Values");
|
|
||||||
ibtnfuzzer->main_menu_items[1] = furi_string_alloc_set("Load File");
|
|
||||||
ibtnfuzzer->main_menu_items[2] = furi_string_alloc_set("Load UIDs from file");
|
|
||||||
|
|
||||||
ibtnfuzzer->main_menu_proto_items[0] = furi_string_alloc_set("DS1990");
|
|
||||||
ibtnfuzzer->main_menu_proto_items[1] = furi_string_alloc_set("Metakom");
|
|
||||||
ibtnfuzzer->main_menu_proto_items[2] = furi_string_alloc_set("Cyfral");
|
|
||||||
|
|
||||||
ibtnfuzzer->previous_scene = NoneScene;
|
|
||||||
ibtnfuzzer->current_scene = SceneEntryPoint;
|
|
||||||
ibtnfuzzer->is_running = true;
|
|
||||||
ibtnfuzzer->is_attacking = false;
|
|
||||||
ibtnfuzzer->key_index = 0;
|
|
||||||
ibtnfuzzer->menu_index = 0;
|
|
||||||
ibtnfuzzer->menu_proto_index = 0;
|
|
||||||
|
|
||||||
ibtnfuzzer->attack = iBtnFuzzerAttackDefaultValues;
|
|
||||||
ibtnfuzzer->notify = furi_record_open(RECORD_NOTIFICATION);
|
|
||||||
|
|
||||||
ibtnfuzzer->data[0] = 0x00;
|
|
||||||
ibtnfuzzer->data[1] = 0x00;
|
|
||||||
ibtnfuzzer->data[2] = 0x00;
|
|
||||||
ibtnfuzzer->data[3] = 0x00;
|
|
||||||
ibtnfuzzer->data[4] = 0x00;
|
|
||||||
ibtnfuzzer->data[5] = 0x00;
|
|
||||||
ibtnfuzzer->data[6] = 0x00;
|
|
||||||
ibtnfuzzer->data[7] = 0x00;
|
|
||||||
|
|
||||||
ibtnfuzzer->payload[0] = 0x00;
|
|
||||||
ibtnfuzzer->payload[1] = 0x00;
|
|
||||||
ibtnfuzzer->payload[2] = 0x00;
|
|
||||||
ibtnfuzzer->payload[3] = 0x00;
|
|
||||||
ibtnfuzzer->payload[4] = 0x00;
|
|
||||||
ibtnfuzzer->payload[5] = 0x00;
|
|
||||||
ibtnfuzzer->payload[6] = 0x00;
|
|
||||||
ibtnfuzzer->payload[7] = 0x00;
|
|
||||||
|
|
||||||
//Dialog
|
|
||||||
ibtnfuzzer->dialogs = furi_record_open(RECORD_DIALOGS);
|
|
||||||
|
|
||||||
return ibtnfuzzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_free(iBtnFuzzerState* ibtnfuzzer) {
|
|
||||||
//Dialog
|
|
||||||
furi_record_close(RECORD_DIALOGS);
|
|
||||||
notification_message(ibtnfuzzer->notify, &sequence_blink_stop);
|
|
||||||
|
|
||||||
// Strings
|
|
||||||
furi_string_free(ibtnfuzzer->notification_msg);
|
|
||||||
furi_string_free(ibtnfuzzer->attack_name);
|
|
||||||
furi_string_free(ibtnfuzzer->proto_name);
|
|
||||||
furi_string_free(ibtnfuzzer->data_str);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < 3; i++) {
|
|
||||||
furi_string_free(ibtnfuzzer->main_menu_items[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < 3; i++) {
|
|
||||||
furi_string_free(ibtnfuzzer->main_menu_proto_items[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The rest
|
|
||||||
free(ibtnfuzzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ENTRYPOINT
|
|
||||||
int32_t ibtnfuzzer_start(void* p) {
|
|
||||||
UNUSED(p);
|
|
||||||
// Input
|
|
||||||
FURI_LOG_I(TAG, "Initializing input");
|
|
||||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(iBtnFuzzerEvent));
|
|
||||||
iBtnFuzzerState* ibtnfuzzer_state = ibtnfuzzer_alloc();
|
|
||||||
|
|
||||||
ibtnfuzzer_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
|
||||||
if(!ibtnfuzzer_state->mutex) {
|
|
||||||
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
|
||||||
furi_message_queue_free(event_queue);
|
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
|
||||||
ibtnfuzzer_free(ibtnfuzzer_state);
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
if(!storage_simply_mkdir(storage, IBTNFUZZER_APP_FOLDER)) {
|
|
||||||
FURI_LOG_E(TAG, "Could not create folder %s", IBTNFUZZER_APP_FOLDER);
|
|
||||||
}
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
|
|
||||||
// Configure view port
|
|
||||||
FURI_LOG_I(TAG, "Initializing viewport");
|
|
||||||
ViewPort* view_port = view_port_alloc();
|
|
||||||
view_port_draw_callback_set(view_port, ibtnfuzzer_draw_callback, ibtnfuzzer_state);
|
|
||||||
view_port_input_callback_set(view_port, ibtnfuzzer_input_callback, event_queue);
|
|
||||||
|
|
||||||
// Configure timer
|
|
||||||
FURI_LOG_I(TAG, "Initializing timer");
|
|
||||||
FuriTimer* timer =
|
|
||||||
furi_timer_alloc(ibtnfuzzer_timer_callback, FuriTimerTypePeriodic, event_queue);
|
|
||||||
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second
|
|
||||||
|
|
||||||
// Register view port in GUI
|
|
||||||
FURI_LOG_I(TAG, "Initializing gui");
|
|
||||||
Gui* gui = (Gui*)furi_record_open(RECORD_GUI);
|
|
||||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
|
||||||
|
|
||||||
// Init values
|
|
||||||
iBtnFuzzerEvent event;
|
|
||||||
while(ibtnfuzzer_state->is_running) {
|
|
||||||
// Get next event
|
|
||||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25);
|
|
||||||
//furi_mutex_acquire(ibtnfuzzer_state->mutex, FuriWaitForever);
|
|
||||||
if(event_status == FuriStatusOk) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
//Handle event key
|
|
||||||
switch(ibtnfuzzer_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_event(event, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
ibtnfuzzer_scene_load_file_on_event(event, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
ibtnfuzzer_scene_select_field_on_event(event, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
ibtnfuzzer_scene_run_attack_on_event(event, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
ibtnfuzzer_scene_load_custom_uids_on_event(event, ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(event.evt_type == EventTypeTick) {
|
|
||||||
//Handle event tick
|
|
||||||
if(ibtnfuzzer_state->current_scene != ibtnfuzzer_state->previous_scene) {
|
|
||||||
// Trigger Exit Scene
|
|
||||||
switch(ibtnfuzzer_state->previous_scene) {
|
|
||||||
case SceneEntryPoint:
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_exit(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
ibtnfuzzer_scene_load_file_on_exit(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
ibtnfuzzer_scene_select_field_on_exit(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
ibtnfuzzer_scene_run_attack_on_exit(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
ibtnfuzzer_scene_load_custom_uids_on_exit(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case NoneScene:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger Entry Scene
|
|
||||||
switch(ibtnfuzzer_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_enter(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
ibtnfuzzer_scene_load_file_on_enter(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
ibtnfuzzer_scene_select_field_on_enter(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
ibtnfuzzer_scene_run_attack_on_enter(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
ibtnfuzzer_scene_load_custom_uids_on_enter(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ibtnfuzzer_state->previous_scene = ibtnfuzzer_state->current_scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger Tick Scene
|
|
||||||
switch(ibtnfuzzer_state->current_scene) {
|
|
||||||
case NoneScene:
|
|
||||||
case SceneEntryPoint:
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_tick(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectFile:
|
|
||||||
ibtnfuzzer_scene_load_file_on_tick(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneSelectField:
|
|
||||||
ibtnfuzzer_scene_select_field_on_tick(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneAttack:
|
|
||||||
ibtnfuzzer_scene_run_attack_on_tick(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
case SceneLoadCustomUids:
|
|
||||||
ibtnfuzzer_scene_load_custom_uids_on_tick(ibtnfuzzer_state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
view_port_update(view_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//furi_mutex_release(ibtnfuzzer_state->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
furi_timer_stop(timer);
|
|
||||||
furi_timer_free(timer);
|
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "Cleaning up");
|
|
||||||
gui_remove_view_port(gui, view_port);
|
|
||||||
view_port_free(view_port);
|
|
||||||
furi_message_queue_free(event_queue);
|
|
||||||
furi_record_close(RECORD_GUI);
|
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
|
||||||
furi_mutex_free(ibtnfuzzer_state->mutex);
|
|
||||||
ibtnfuzzer_free(ibtnfuzzer_state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
94
applications/external/ibtn_fuzzer/ibtnfuzzer.h
vendored
|
@ -1,94 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <input/input.h>
|
|
||||||
#include <gui/gui.h>
|
|
||||||
#include <gui/modules/submenu.h>
|
|
||||||
#include <dialogs/dialogs.h>
|
|
||||||
#include <notification/notification.h>
|
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <toolbox/stream/stream.h>
|
|
||||||
#include <flipper_format/flipper_format_i.h>
|
|
||||||
|
|
||||||
#include <toolbox/stream/stream.h>
|
|
||||||
#include <toolbox/stream/string_stream.h>
|
|
||||||
#include <toolbox/stream/file_stream.h>
|
|
||||||
#include <toolbox/stream/buffered_file_stream.h>
|
|
||||||
|
|
||||||
#include <ibtn_fuzzer_icons.h>
|
|
||||||
|
|
||||||
#include <lib/ibutton/ibutton_worker.h>
|
|
||||||
#include <lib/ibutton/ibutton_key.h>
|
|
||||||
|
|
||||||
#define TAG "iBtnFuzzer"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
iBtnFuzzerAttackDefaultValues,
|
|
||||||
iBtnFuzzerAttackLoadFile,
|
|
||||||
iBtnFuzzerAttackLoadFileCustomUids,
|
|
||||||
} iBtnFuzzerAttacks;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
DS1990,
|
|
||||||
Metakom,
|
|
||||||
Cyfral,
|
|
||||||
} iBtnFuzzerProtos;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
NoneScene,
|
|
||||||
SceneEntryPoint,
|
|
||||||
SceneSelectFile,
|
|
||||||
SceneSelectField,
|
|
||||||
SceneAttack,
|
|
||||||
SceneLoadCustomUids,
|
|
||||||
} iBtnFuzzerScene;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EventTypeTick,
|
|
||||||
EventTypeKey,
|
|
||||||
} EventType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
EventType evt_type;
|
|
||||||
InputKey key;
|
|
||||||
InputType input_type;
|
|
||||||
} iBtnFuzzerEvent;
|
|
||||||
|
|
||||||
// STRUCTS
|
|
||||||
typedef struct {
|
|
||||||
FuriMutex* mutex;
|
|
||||||
bool is_running;
|
|
||||||
bool is_attacking;
|
|
||||||
iBtnFuzzerScene current_scene;
|
|
||||||
iBtnFuzzerScene previous_scene;
|
|
||||||
NotificationApp* notify;
|
|
||||||
u_int8_t menu_index;
|
|
||||||
u_int8_t menu_proto_index;
|
|
||||||
|
|
||||||
FuriString* data_str;
|
|
||||||
uint8_t data[8];
|
|
||||||
uint8_t payload[8];
|
|
||||||
uint8_t attack_step;
|
|
||||||
iBtnFuzzerAttacks attack;
|
|
||||||
iBtnFuzzerProtos proto;
|
|
||||||
FuriString* attack_name;
|
|
||||||
FuriString* proto_name;
|
|
||||||
FuriString* main_menu_items[3];
|
|
||||||
FuriString* main_menu_proto_items[3];
|
|
||||||
|
|
||||||
DialogsApp* dialogs;
|
|
||||||
FuriString* notification_msg;
|
|
||||||
uint8_t key_index;
|
|
||||||
iButtonWorker* worker;
|
|
||||||
iButtonKey* key;
|
|
||||||
iButtonProtocolId keytype;
|
|
||||||
iButtonProtocols* protocols;
|
|
||||||
bool workr_rund;
|
|
||||||
bool enter_rerun;
|
|
||||||
bool attack_stop_called;
|
|
||||||
|
|
||||||
uint8_t time_between_cards;
|
|
||||||
|
|
||||||
// Used for custom dictionnary
|
|
||||||
Stream* uids_stream;
|
|
||||||
} iBtnFuzzerState;
|
|
Before Width: | Height: | Size: 304 B |
|
@ -1,201 +0,0 @@
|
||||||
#include "ibtnfuzzer_scene_entrypoint.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_menu_callback(
|
|
||||||
iBtnFuzzerState* context,
|
|
||||||
uint32_t index,
|
|
||||||
uint32_t proto_index) {
|
|
||||||
switch(index) {
|
|
||||||
case iBtnFuzzerAttackDefaultValues:
|
|
||||||
context->attack = iBtnFuzzerAttackDefaultValues;
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
furi_string_set(context->attack_name, "Default Values");
|
|
||||||
break;
|
|
||||||
case iBtnFuzzerAttackLoadFile:
|
|
||||||
context->attack = iBtnFuzzerAttackLoadFile;
|
|
||||||
context->current_scene = SceneSelectFile;
|
|
||||||
furi_string_set(context->attack_name, "Load File");
|
|
||||||
break;
|
|
||||||
case iBtnFuzzerAttackLoadFileCustomUids:
|
|
||||||
context->attack = iBtnFuzzerAttackLoadFileCustomUids;
|
|
||||||
context->current_scene = SceneLoadCustomUids;
|
|
||||||
furi_string_set(context->attack_name, "Load Custom UIDs");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(proto_index) {
|
|
||||||
case DS1990:
|
|
||||||
context->proto = DS1990;
|
|
||||||
furi_string_set(context->proto_name, "DS1990");
|
|
||||||
break;
|
|
||||||
case Metakom:
|
|
||||||
context->proto = Metakom;
|
|
||||||
furi_string_set(context->proto_name, "Metakom");
|
|
||||||
break;
|
|
||||||
case Cyfral:
|
|
||||||
context->proto = Cyfral;
|
|
||||||
furi_string_set(context->proto_name, "Cyfral");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_enter(iBtnFuzzerState* context) {
|
|
||||||
// Clear the previous payload
|
|
||||||
context->payload[0] = 0x00;
|
|
||||||
context->payload[1] = 0x00;
|
|
||||||
context->payload[2] = 0x00;
|
|
||||||
context->payload[3] = 0x00;
|
|
||||||
context->payload[4] = 0x00;
|
|
||||||
context->payload[5] = 0x00;
|
|
||||||
context->payload[6] = 0x00;
|
|
||||||
context->payload[7] = 0x00;
|
|
||||||
|
|
||||||
context->menu_index = 0;
|
|
||||||
/*for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
menu_items[i] = furi_string_alloc();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
context->menu_proto_index = 0;
|
|
||||||
/*for(uint32_t i = 0; i < 4; i++) {
|
|
||||||
menu_proto_items[i] = furi_string_alloc();
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_exit(iBtnFuzzerState* context) {
|
|
||||||
context->enter_rerun = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_tick(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
if(context->menu_index < iBtnFuzzerAttackLoadFileCustomUids) {
|
|
||||||
context->menu_index++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
if(context->menu_index > iBtnFuzzerAttackDefaultValues) {
|
|
||||||
context->menu_index--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(context->menu_proto_index > DS1990) {
|
|
||||||
context->menu_proto_index--;
|
|
||||||
} else if(context->menu_proto_index == DS1990) {
|
|
||||||
context->menu_proto_index = Cyfral;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(context->menu_proto_index < Cyfral) {
|
|
||||||
context->menu_proto_index++;
|
|
||||||
} else if(context->menu_proto_index == Cyfral) {
|
|
||||||
context->menu_proto_index = DS1990;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
ibtnfuzzer_scene_entrypoint_menu_callback(
|
|
||||||
context, context->menu_index, context->menu_proto_index);
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->is_running = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_draw(Canvas* canvas, iBtnFuzzerState* context) {
|
|
||||||
if(!context->enter_rerun) {
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_enter(context);
|
|
||||||
context->enter_rerun = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
if(context->main_menu_items != NULL) {
|
|
||||||
if(context->main_menu_items[context->menu_index] != NULL) {
|
|
||||||
if(context->menu_index > iBtnFuzzerAttackDefaultValues) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
24,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index - 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
36,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index]));
|
|
||||||
|
|
||||||
if(context->menu_index < iBtnFuzzerAttackLoadFileCustomUids) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
48,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(context->main_menu_items[context->menu_index + 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(context->menu_proto_index > DS1990) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
-12,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(
|
|
||||||
context->main_menu_proto_items[context->menu_proto_index - 1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(canvas, 27, 4, AlignCenter, AlignTop, "<");
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
if(context->main_menu_proto_items[context->menu_proto_index] != NULL) {
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
4,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(
|
|
||||||
context->main_menu_proto_items[context->menu_proto_index]));
|
|
||||||
}
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(canvas, 101, 4, AlignCenter, AlignTop, ">");
|
|
||||||
|
|
||||||
if(context->menu_proto_index < Cyfral) {
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas,
|
|
||||||
64,
|
|
||||||
-12,
|
|
||||||
AlignCenter,
|
|
||||||
AlignTop,
|
|
||||||
furi_string_get_cstr(
|
|
||||||
context->main_menu_proto_items[context->menu_proto_index + 1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../ibtnfuzzer.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_enter(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_exit(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_tick(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_entrypoint_on_draw(Canvas* canvas, iBtnFuzzerState* context);
|
|
|
@ -1,86 +0,0 @@
|
||||||
#include "ibtnfuzzer_scene_load_custom_uids.h"
|
|
||||||
#include "ibtnfuzzer_scene_run_attack.h"
|
|
||||||
#include "ibtnfuzzer_scene_entrypoint.h"
|
|
||||||
|
|
||||||
#define IBTNFUZZER_UIDS_EXTENSION ".txt"
|
|
||||||
#define IBTNFUZZER_APP_PATH_FOLDER "/ext/ibtnfuzzer"
|
|
||||||
|
|
||||||
bool ibtnfuzzer_load_uids(iBtnFuzzerState* context, const char* file_path) {
|
|
||||||
bool result = false;
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
context->uids_stream = buffered_file_stream_alloc(storage);
|
|
||||||
result =
|
|
||||||
buffered_file_stream_open(context->uids_stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
||||||
// Close if loading fails
|
|
||||||
if(!result) {
|
|
||||||
buffered_file_stream_close(context->uids_stream);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ibtnfuzzer_load_custom_uids_from_file(iBtnFuzzerState* context) {
|
|
||||||
// Input events and views are managed by file_select
|
|
||||||
FuriString* uid_path;
|
|
||||||
uid_path = furi_string_alloc();
|
|
||||||
furi_string_set(uid_path, IBTNFUZZER_APP_PATH_FOLDER);
|
|
||||||
|
|
||||||
DialogsFileBrowserOptions browser_options;
|
|
||||||
dialog_file_browser_set_basic_options(
|
|
||||||
&browser_options, IBTNFUZZER_UIDS_EXTENSION, &I_ibutt_10px);
|
|
||||||
browser_options.base_path = IBTNFUZZER_APP_PATH_FOLDER;
|
|
||||||
browser_options.hide_ext = false;
|
|
||||||
|
|
||||||
bool res = dialog_file_browser_show(context->dialogs, uid_path, uid_path, &browser_options);
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
res = ibtnfuzzer_load_uids(context, furi_string_get_cstr(uid_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_free(uid_path);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_enter(iBtnFuzzerState* context) {
|
|
||||||
if(ibtnfuzzer_load_custom_uids_from_file(context)) {
|
|
||||||
// Force context loading
|
|
||||||
ibtnfuzzer_scene_run_attack_on_enter(context);
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
} else {
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_enter(context);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_exit(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_tick(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
case InputKeyUp:
|
|
||||||
case InputKeyLeft:
|
|
||||||
case InputKeyRight:
|
|
||||||
case InputKeyOk:
|
|
||||||
case InputKeyBack:
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_draw(Canvas* canvas, iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
UNUSED(canvas);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../ibtnfuzzer.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_enter(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_exit(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_tick(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_custom_uids_on_draw(Canvas* canvas, iBtnFuzzerState* context);
|
|
||||||
bool ibtnfuzzer_load_custom_uids_from_file(iBtnFuzzerState* context);
|
|
|
@ -1,293 +0,0 @@
|
||||||
#include "ibtnfuzzer_scene_load_file.h"
|
|
||||||
#include "ibtnfuzzer_scene_entrypoint.h"
|
|
||||||
|
|
||||||
#define IBUTTON_FUZZER_APP_EXTENSION ".ibtn"
|
|
||||||
#define IBUTTON_FUZZER_APP_PATH_FOLDER "/ext/ibutton"
|
|
||||||
|
|
||||||
bool ibtnfuzzer_load(iBtnFuzzerState* context, const char* file_path) {
|
|
||||||
bool result = false;
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
||||||
FuriString* temp_str;
|
|
||||||
temp_str = furi_string_alloc();
|
|
||||||
bool key_v2 = false;
|
|
||||||
do {
|
|
||||||
if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
|
|
||||||
FURI_LOG_E(TAG, "Error open file %s", file_path);
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Error open file");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileType
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Filetype", temp_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Filetype");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Filetypes");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Filetype: %s", furi_string_get_cstr(temp_str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key type
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Key type", temp_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Key type, checking for typ2..");
|
|
||||||
|
|
||||||
if(!flipper_format_rewind(fff_data_file)) {
|
|
||||||
FURI_LOG_E(TAG, "Failed to rewind file");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) {
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(
|
|
||||||
context->notification_msg, "Missing or incorrect Protocol or Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FURI_LOG_I(TAG, "Key type V2: %s", furi_string_get_cstr(temp_str));
|
|
||||||
key_v2 = true;
|
|
||||||
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "DS1990") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "Cyfral") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "Metakom") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key type: %s", furi_string_get_cstr(temp_str));
|
|
||||||
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "Dallas") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "Cyfral") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(strcmp(furi_string_get_cstr(temp_str), "Metakom") != 0) {
|
|
||||||
FURI_LOG_E(TAG, "Unsupported Key type");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Unsupported Key type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!key_v2) {
|
|
||||||
// Data
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Data");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Key");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str));
|
|
||||||
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
if(furi_string_size(context->data_str) != 23) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
if(furi_string_size(context->data_str) != 5) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(furi_string_size(context->data_str) != 11) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String to uint8_t
|
|
||||||
for(uint8_t i = 0; i < 8; i++) {
|
|
||||||
char temp_str2[3];
|
|
||||||
temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3];
|
|
||||||
temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1];
|
|
||||||
temp_str2[2] = '\0';
|
|
||||||
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Data
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Rom Data", context->data_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Rom Data");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Rom Data");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str));
|
|
||||||
|
|
||||||
if(furi_string_size(context->data_str) != 23) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// String to uint8_t
|
|
||||||
for(uint8_t i = 0; i < 8; i++) {
|
|
||||||
char temp_str2[3];
|
|
||||||
temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3];
|
|
||||||
temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1];
|
|
||||||
temp_str2[2] = '\0';
|
|
||||||
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Data");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Data");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str));
|
|
||||||
|
|
||||||
if(furi_string_size(context->data_str) != 5) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// String to uint8_t
|
|
||||||
for(uint8_t i = 0; i < 8; i++) {
|
|
||||||
char temp_str2[3];
|
|
||||||
temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3];
|
|
||||||
temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1];
|
|
||||||
temp_str2[2] = '\0';
|
|
||||||
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(!flipper_format_read_string(fff_data_file, "Data", context->data_str)) {
|
|
||||||
FURI_LOG_E(TAG, "Missing or incorrect Data");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Missing or incorrect Data");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
FURI_LOG_I(TAG, "Key: %s", furi_string_get_cstr(context->data_str));
|
|
||||||
|
|
||||||
if(furi_string_size(context->data_str) != 11) {
|
|
||||||
FURI_LOG_E(TAG, "Incorrect Key length");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Incorrect Key length");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// String to uint8_t
|
|
||||||
for(uint8_t i = 0; i < 8; i++) {
|
|
||||||
char temp_str2[3];
|
|
||||||
temp_str2[0] = furi_string_get_cstr(context->data_str)[i * 3];
|
|
||||||
temp_str2[1] = furi_string_get_cstr(context->data_str)[i * 3 + 1];
|
|
||||||
temp_str2[2] = '\0';
|
|
||||||
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
} while(0);
|
|
||||||
furi_string_free(temp_str);
|
|
||||||
flipper_format_free(fff_data_file);
|
|
||||||
if(result) {
|
|
||||||
FURI_LOG_I(TAG, "Loaded successfully");
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, "Source loaded.");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_enter(iBtnFuzzerState* context) {
|
|
||||||
if(ibtnfuzzer_load_protocol_from_file(context)) {
|
|
||||||
context->current_scene = SceneSelectField;
|
|
||||||
} else {
|
|
||||||
ibtnfuzzer_scene_entrypoint_on_enter(context);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_exit(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_tick(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
case InputKeyUp:
|
|
||||||
case InputKeyLeft:
|
|
||||||
case InputKeyRight:
|
|
||||||
case InputKeyOk:
|
|
||||||
case InputKeyBack:
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_draw(Canvas* canvas, iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
UNUSED(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ibtnfuzzer_load_protocol_from_file(iBtnFuzzerState* context) {
|
|
||||||
FuriString* user_file_path;
|
|
||||||
user_file_path = furi_string_alloc();
|
|
||||||
furi_string_set(user_file_path, IBUTTON_FUZZER_APP_PATH_FOLDER);
|
|
||||||
|
|
||||||
DialogsFileBrowserOptions browser_options;
|
|
||||||
dialog_file_browser_set_basic_options(
|
|
||||||
&browser_options, IBUTTON_FUZZER_APP_EXTENSION, &I_ibutt_10px);
|
|
||||||
browser_options.base_path = IBUTTON_FUZZER_APP_PATH_FOLDER;
|
|
||||||
|
|
||||||
// Input events and views are managed by file_select
|
|
||||||
bool res = dialog_file_browser_show(
|
|
||||||
context->dialogs, user_file_path, user_file_path, &browser_options);
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
res = ibtnfuzzer_load(context, furi_string_get_cstr(user_file_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_free(user_file_path);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../ibtnfuzzer.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_load_file_on_enter(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_file_on_exit(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_file_on_tick(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_file_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_load_file_on_draw(Canvas* canvas, iBtnFuzzerState* context);
|
|
||||||
bool ibtnfuzzer_load_protocol_from_file(iBtnFuzzerState* context);
|
|
|
@ -1,501 +0,0 @@
|
||||||
#include "ibtnfuzzer_scene_run_attack.h"
|
|
||||||
#include <gui/elements.h>
|
|
||||||
|
|
||||||
uint8_t counter = 0;
|
|
||||||
|
|
||||||
uint8_t id_list_ds1990[18][8] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t id_list_metakom[17][4] = {
|
|
||||||
{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}, // ??
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t id_list_cyfral[16][2] = {
|
|
||||||
{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
|
|
||||||
};
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_enter(iBtnFuzzerState* context) {
|
|
||||||
context->time_between_cards = 8;
|
|
||||||
context->attack_step = 0;
|
|
||||||
context->attack_stop_called = false;
|
|
||||||
context->protocols = ibutton_protocols_alloc();
|
|
||||||
context->key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(context->protocols));
|
|
||||||
context->worker = ibutton_worker_alloc(context->protocols);
|
|
||||||
if(context->proto == Metakom) {
|
|
||||||
context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "Metakom");
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "Cyfral");
|
|
||||||
} else {
|
|
||||||
context->keytype = ibutton_protocols_get_id_by_name(context->protocols, "DS1990");
|
|
||||||
}
|
|
||||||
context->workr_rund = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_exit(iBtnFuzzerState* context) {
|
|
||||||
if(context->workr_rund) {
|
|
||||||
ibutton_worker_stop(context->worker);
|
|
||||||
ibutton_worker_stop_thread(context->worker);
|
|
||||||
context->workr_rund = false;
|
|
||||||
}
|
|
||||||
ibutton_key_free(context->key);
|
|
||||||
ibutton_worker_free(context->worker);
|
|
||||||
ibutton_protocols_free(context->protocols);
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_tick(iBtnFuzzerState* context) {
|
|
||||||
if(context->is_attacking) {
|
|
||||||
if(1 == counter) {
|
|
||||||
ibutton_worker_start_thread(context->worker);
|
|
||||||
ibutton_key_set_protocol_id(context->key, context->keytype);
|
|
||||||
iButtonEditableData data;
|
|
||||||
ibutton_protocols_get_editable_data(context->protocols, context->key, &data);
|
|
||||||
data.size = sizeof(context->payload);
|
|
||||||
for(size_t i = 0; i < data.size; i++) {
|
|
||||||
data.ptr[i] = context->payload[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ibutton_worker_emulate_start(context->worker, context->key);
|
|
||||||
context->workr_rund = true;
|
|
||||||
} else if(0 == counter) {
|
|
||||||
if(context->workr_rund) {
|
|
||||||
ibutton_worker_stop(context->worker);
|
|
||||||
ibutton_worker_stop_thread(context->worker);
|
|
||||||
context->workr_rund = false;
|
|
||||||
furi_delay_ms(500);
|
|
||||||
}
|
|
||||||
switch(context->attack) {
|
|
||||||
case iBtnFuzzerAttackDefaultValues:
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
context->payload[0] = id_list_ds1990[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_ds1990[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list_ds1990[context->attack_step][2];
|
|
||||||
context->payload[3] = id_list_ds1990[context->attack_step][3];
|
|
||||||
context->payload[4] = id_list_ds1990[context->attack_step][4];
|
|
||||||
context->payload[5] = id_list_ds1990[context->attack_step][5];
|
|
||||||
context->payload[6] = id_list_ds1990[context->attack_step][6];
|
|
||||||
context->payload[7] = id_list_ds1990[context->attack_step][7];
|
|
||||||
|
|
||||||
if(context->attack_step == 17) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == Metakom) {
|
|
||||||
context->payload[0] = id_list_metakom[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_metakom[context->attack_step][1];
|
|
||||||
context->payload[2] = id_list_metakom[context->attack_step][2];
|
|
||||||
context->payload[3] = id_list_metakom[context->attack_step][3];
|
|
||||||
|
|
||||||
if(context->attack_step == 16) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->payload[0] = id_list_cyfral[context->attack_step][0];
|
|
||||||
context->payload[1] = id_list_cyfral[context->attack_step][1];
|
|
||||||
|
|
||||||
if(context->attack_step == 15) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case iBtnFuzzerAttackLoadFile:
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
context->payload[3] = context->data[3];
|
|
||||||
context->payload[4] = context->data[4];
|
|
||||||
context->payload[5] = context->data[5];
|
|
||||||
context->payload[6] = context->data[6];
|
|
||||||
context->payload[7] = context->data[7];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->payload[0] = context->data[0];
|
|
||||||
context->payload[1] = context->data[1];
|
|
||||||
context->payload[2] = context->data[2];
|
|
||||||
context->payload[3] = context->data[3];
|
|
||||||
|
|
||||||
context->payload[context->key_index] = context->attack_step;
|
|
||||||
|
|
||||||
if(context->attack_step == 255) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
context->attack_step++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case iBtnFuzzerAttackLoadFileCustomUids:
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 17) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(end_of_list) break;
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(furi_string_size(context->data_str) != 17) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 8; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 5) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(end_of_list) break;
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(furi_string_size(context->data_str) != 5) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 2; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
bool end_of_list = false;
|
|
||||||
while(true) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
if(!stream_read_line(context->uids_stream, context->data_str)) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
end_of_list = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if(furi_string_get_char(context->data_str, 0) == '#') continue;
|
|
||||||
if(furi_string_size(context->data_str) != 9) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FURI_LOG_D(TAG, furi_string_get_cstr(context->data_str));
|
|
||||||
if(end_of_list) break;
|
|
||||||
if(furi_string_size(context->data_str) != 9) {
|
|
||||||
context->attack_step = 0;
|
|
||||||
counter = 0;
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_error);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
// string is valid, parse it in context->payload
|
|
||||||
for(uint8_t i = 0; i < 4; i++) {
|
|
||||||
char temp_str[3];
|
|
||||||
temp_str[0] = furi_string_get_cstr(context->data_str)[i * 2];
|
|
||||||
temp_str[1] = furi_string_get_cstr(context->data_str)[i * 2 + 1];
|
|
||||||
temp_str[2] = '\0';
|
|
||||||
context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(counter > context->time_between_cards) {
|
|
||||||
counter = 0;
|
|
||||||
} else {
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards > 4) {
|
|
||||||
context->time_between_cards--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards < 80) {
|
|
||||||
context->time_between_cards++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
counter = 0;
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
notification_message(context->notify, &sequence_blink_start_blue);
|
|
||||||
context->is_attacking = true;
|
|
||||||
} else {
|
|
||||||
context->is_attacking = false;
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
notification_message(context->notify, &sequence_single_vibro);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->is_attacking = false;
|
|
||||||
counter = 0;
|
|
||||||
|
|
||||||
notification_message(context->notify, &sequence_blink_stop);
|
|
||||||
if(context->attack_stop_called) {
|
|
||||||
context->attack_stop_called = false;
|
|
||||||
context->attack_step = 0;
|
|
||||||
if(context->attack == iBtnFuzzerAttackLoadFileCustomUids) {
|
|
||||||
furi_string_reset(context->data_str);
|
|
||||||
stream_rewind(context->uids_stream);
|
|
||||||
buffered_file_stream_close(context->uids_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneEntryPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
context->attack_stop_called = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(event.input_type == InputTypeLong) {
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards > 4) {
|
|
||||||
if((context->time_between_cards - 10) > 4) {
|
|
||||||
context->time_between_cards -= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(!context->is_attacking) {
|
|
||||||
if(context->time_between_cards < 80) {
|
|
||||||
context->time_between_cards += 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_draw(Canvas* canvas, iBtnFuzzerState* context) {
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
// Frame
|
|
||||||
//canvas_draw_frame(canvas, 0, 0, 128, 64);
|
|
||||||
|
|
||||||
// Title
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(context->attack_name));
|
|
||||||
|
|
||||||
char uid[25];
|
|
||||||
char speed[16];
|
|
||||||
if(context->proto == Metakom) {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2],
|
|
||||||
context->payload[3]);
|
|
||||||
} else if(context->proto == Cyfral) {
|
|
||||||
snprintf(uid, sizeof(uid), "%02X:%02X", context->payload[0], context->payload[1]);
|
|
||||||
} else {
|
|
||||||
snprintf(
|
|
||||||
uid,
|
|
||||||
sizeof(uid),
|
|
||||||
"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
|
|
||||||
context->payload[0],
|
|
||||||
context->payload[1],
|
|
||||||
context->payload[2],
|
|
||||||
context->payload[3],
|
|
||||||
context->payload[4],
|
|
||||||
context->payload[5],
|
|
||||||
context->payload[6],
|
|
||||||
context->payload[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignTop, uid);
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 26, AlignCenter, AlignTop, furi_string_get_cstr(context->proto_name));
|
|
||||||
|
|
||||||
snprintf(speed, sizeof(speed), "Time delay: %d", context->time_between_cards);
|
|
||||||
|
|
||||||
//canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Speed:");
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 14, AlignCenter, AlignTop, speed);
|
|
||||||
//char start_stop_msg[20];
|
|
||||||
if(context->is_attacking) {
|
|
||||||
elements_button_center(canvas, "Stop");
|
|
||||||
//snprintf(start_stop_msg, sizeof(start_stop_msg), " Press OK to stop ");
|
|
||||||
} else {
|
|
||||||
elements_button_center(canvas, "Start");
|
|
||||||
elements_button_left(canvas, "TD -");
|
|
||||||
elements_button_right(canvas, "+ TD");
|
|
||||||
}
|
|
||||||
//canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, start_stop_msg);
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../ibtnfuzzer.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_enter(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_exit(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_tick(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_run_attack_on_draw(Canvas* canvas, iBtnFuzzerState* context);
|
|
|
@ -1,160 +0,0 @@
|
||||||
#include "ibtnfuzzer_scene_select_field.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_center_displayed_key(iBtnFuzzerState* context, uint8_t index) {
|
|
||||||
char key_cstr[25];
|
|
||||||
uint8_t key_len = 25;
|
|
||||||
uint8_t str_index = (index * 3);
|
|
||||||
int data_len = sizeof(context->data) / sizeof(context->data[0]);
|
|
||||||
int key_index = 0;
|
|
||||||
|
|
||||||
if(context->proto == DS1990) {
|
|
||||||
key_len = 25;
|
|
||||||
}
|
|
||||||
if(context->proto == Metakom) {
|
|
||||||
key_len = 13;
|
|
||||||
}
|
|
||||||
if(context->proto == Cyfral) {
|
|
||||||
key_len = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->data[i] < 9) {
|
|
||||||
key_index +=
|
|
||||||
snprintf(&key_cstr[key_index], key_len - key_index, "0%X ", context->data[i]);
|
|
||||||
} else {
|
|
||||||
key_index +=
|
|
||||||
snprintf(&key_cstr[key_index], key_len - key_index, "%X ", context->data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char display_menu[17] = {
|
|
||||||
'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
|
|
||||||
|
|
||||||
if(index > 1) {
|
|
||||||
display_menu[0] = key_cstr[str_index - 6];
|
|
||||||
display_menu[1] = key_cstr[str_index - 5];
|
|
||||||
} else {
|
|
||||||
display_menu[0] = ' ';
|
|
||||||
display_menu[1] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(index > 0) {
|
|
||||||
display_menu[3] = key_cstr[str_index - 3];
|
|
||||||
display_menu[4] = key_cstr[str_index - 2];
|
|
||||||
} else {
|
|
||||||
display_menu[3] = ' ';
|
|
||||||
display_menu[4] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
display_menu[7] = key_cstr[str_index];
|
|
||||||
display_menu[8] = key_cstr[str_index + 1];
|
|
||||||
|
|
||||||
if((str_index + 4) <= (uint8_t)strlen(key_cstr)) {
|
|
||||||
display_menu[11] = key_cstr[str_index + 3];
|
|
||||||
display_menu[12] = key_cstr[str_index + 4];
|
|
||||||
} else {
|
|
||||||
display_menu[11] = ' ';
|
|
||||||
display_menu[12] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if((str_index + 8) <= (uint8_t)strlen(key_cstr)) {
|
|
||||||
display_menu[14] = key_cstr[str_index + 6];
|
|
||||||
display_menu[15] = key_cstr[str_index + 7];
|
|
||||||
} else {
|
|
||||||
display_menu[14] = ' ';
|
|
||||||
display_menu[15] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
furi_string_set(context->notification_msg, display_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_enter(iBtnFuzzerState* context) {
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_exit(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_tick(iBtnFuzzerState* context) {
|
|
||||||
UNUSED(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context) {
|
|
||||||
if(event.evt_type == EventTypeKey) {
|
|
||||||
if(event.input_type == InputTypeShort) {
|
|
||||||
const char* key_cstr = furi_string_get_cstr(context->data_str);
|
|
||||||
int data_len = sizeof(context->data) / sizeof(context->data[0]);
|
|
||||||
|
|
||||||
// don't look, it's ugly but I'm a python dev so...
|
|
||||||
uint8_t nb_bytes = 0;
|
|
||||||
for(uint8_t i = 0; i < strlen(key_cstr); i++) {
|
|
||||||
if(' ' == key_cstr[i]) {
|
|
||||||
nb_bytes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(event.key) {
|
|
||||||
case InputKeyDown:
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->key_index == i) {
|
|
||||||
context->data[i] = (context->data[i] - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyUp:
|
|
||||||
for(uint8_t i = 0; i < data_len; i++) {
|
|
||||||
if(context->key_index == i) {
|
|
||||||
context->data[i] = (context->data[i] + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyLeft:
|
|
||||||
if(context->key_index > 0) {
|
|
||||||
context->key_index = context->key_index - 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyRight:
|
|
||||||
if(context->key_index < nb_bytes) {
|
|
||||||
context->key_index = context->key_index + 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InputKeyOk:
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneAttack;
|
|
||||||
break;
|
|
||||||
case InputKeyBack:
|
|
||||||
context->key_index = 0;
|
|
||||||
furi_string_reset(context->notification_msg);
|
|
||||||
context->current_scene = SceneSelectFile;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FURI_LOG_D(TAG, "Position: %d/%d", context->key_index, nb_bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_draw(Canvas* canvas, iBtnFuzzerState* context) {
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
|
|
||||||
// Frame
|
|
||||||
//canvas_draw_frame(canvas, 0, 0, 128, 64);
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(canvas, 12, 5, AlignLeft, AlignTop, "Left and right: select byte");
|
|
||||||
canvas_draw_str_aligned(canvas, 12, 15, AlignLeft, AlignTop, "Up and down: adjust byte");
|
|
||||||
|
|
||||||
char msg_index[18];
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
|
||||||
snprintf(msg_index, sizeof(msg_index), "Field index : %d", context->key_index);
|
|
||||||
canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignTop, msg_index);
|
|
||||||
|
|
||||||
ibtnfuzzer_center_displayed_key(context, context->key_index);
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
|
||||||
canvas_draw_str_aligned(
|
|
||||||
canvas, 64, 45, AlignCenter, AlignTop, furi_string_get_cstr(context->notification_msg));
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "../ibtnfuzzer.h"
|
|
||||||
|
|
||||||
void ibtnfuzzer_scene_select_field_on_enter(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_select_field_on_exit(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_select_field_on_tick(iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_select_field_on_event(iBtnFuzzerEvent event, iBtnFuzzerState* context);
|
|
||||||
void ibtnfuzzer_scene_select_field_on_draw(Canvas* canvas, iBtnFuzzerState* context);
|
|
||||||
void center_displayed_key(iBtnFuzzerState* context, uint8_t index);
|
|
|
@ -1,6 +1,6 @@
|
||||||
App(
|
App(
|
||||||
appid="pacs_fuzzer_ibtn",
|
appid="fuzzer_ibtn",
|
||||||
name="iButton Fuzzer [B]",
|
name="iButton Fuzzer",
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
apptype=FlipperAppType.EXTERNAL,
|
||||||
entry_point="fuzzer_start_ibtn",
|
entry_point="fuzzer_start_ibtn",
|
||||||
requires=[
|
requires=[
|
||||||
|
@ -11,8 +11,8 @@ App(
|
||||||
"notification",
|
"notification",
|
||||||
],
|
],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
fap_icon="icons/rfid_10px.png",
|
fap_icon="icons/ibutt_10px.png",
|
||||||
fap_category="Debug",
|
fap_category="Tools",
|
||||||
fap_private_libs=[
|
fap_private_libs=[
|
||||||
Lib(
|
Lib(
|
||||||
name="worker",
|
name="worker",
|
||||||
|
@ -24,8 +24,8 @@ App(
|
||||||
)
|
)
|
||||||
|
|
||||||
App(
|
App(
|
||||||
appid="pacs_fuzzer_rfid",
|
appid="fuzzer_rfid",
|
||||||
name="RFID Fuzzer [B]",
|
name="RFID Fuzzer",
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
apptype=FlipperAppType.EXTERNAL,
|
||||||
entry_point="fuzzer_start_rfid",
|
entry_point="fuzzer_start_rfid",
|
||||||
requires=[
|
requires=[
|
||||||
|
@ -36,8 +36,8 @@ App(
|
||||||
"notification",
|
"notification",
|
||||||
],
|
],
|
||||||
stack_size=2 * 1024,
|
stack_size=2 * 1024,
|
||||||
fap_icon="icons/125_10px.png",
|
fap_icon="icons/rfid_10px.png",
|
||||||
fap_category="Debug",
|
fap_category="Tools",
|
||||||
fap_private_libs=[
|
fap_private_libs=[
|
||||||
Lib(
|
Lib(
|
||||||
name="worker",
|
name="worker",
|
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
applications/external/pacs_fuzzer/icons/125_10px.png
vendored
Before Width: | Height: | Size: 308 B |
Before Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 2.3 KiB |