| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- #include "dict_attack.h"
- #include <gui/elements.h>
- typedef enum {
- DictAttackStateStart,
- DictAttackStateRead,
- DictAttackStateCardRemoved,
- } DictAttackState;
- struct DictAttack {
- View* view;
- DictAttackCallback callback;
- void* context;
- };
- typedef struct {
- DictAttackState state;
- FuriString* header;
- uint8_t sectors_total;
- uint8_t sectors_read;
- uint8_t sector_current;
- uint8_t keys_total;
- uint8_t keys_found;
- uint16_t dict_keys_total;
- uint16_t dict_keys_current;
- bool is_key_attack;
- uint8_t key_attack_current_sector;
- } DictAttackViewModel;
- static void dict_attack_draw_callback(Canvas* canvas, void* model) {
- DictAttackViewModel* m = model;
- if(m->state == DictAttackStateStart) {
- canvas_draw_icon(canvas, 0, 8, &I_RFIDDolphinReceive_97x61);
- canvas_set_font(canvas, FontPrimary);
- elements_multiline_text_aligned(
- canvas, 128, 40, AlignRight, AlignCenter, "Apply card to\nthe back");
- } else if(m->state == DictAttackStateCardRemoved) {
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost the tag!");
- canvas_set_font(canvas, FontSecondary);
- elements_multiline_text_aligned(
- canvas, 64, 23, AlignCenter, AlignTop, "Make sure the tag is\npositioned correctly.");
- } else if(m->state == DictAttackStateRead) {
- char draw_str[32] = {};
- canvas_set_font(canvas, FontSecondary);
- canvas_draw_str_aligned(
- canvas, 64, 0, AlignCenter, AlignTop, furi_string_get_cstr(m->header));
- if(m->is_key_attack) {
- snprintf(
- draw_str,
- sizeof(draw_str),
- "Reuse key check for sector: %d",
- m->key_attack_current_sector);
- } else {
- snprintf(
- draw_str, sizeof(draw_str), "Unlocking Application Area %d", m->sector_current + 1);
- }
- canvas_draw_str_aligned(canvas, 0, 10, AlignLeft, AlignTop, draw_str);
- float dict_progress = m->dict_keys_total == 0 ?
- 0 :
- (float)(m->dict_keys_current) / (float)(m->dict_keys_total);
- float progress = m->sectors_total == 0 ? 0 :
- ((float)(m->sector_current) + dict_progress) /
- (float)(m->sectors_total);
- if(progress > 1.0) {
- progress = 1.0;
- }
- if(m->dict_keys_current == 0) {
- // Cause when people see 0 they think it's broken
- snprintf(draw_str, sizeof(draw_str), "%d/%d", 1, m->dict_keys_total);
- } else {
- snprintf(
- draw_str, sizeof(draw_str), "%d/%d", m->dict_keys_current, m->dict_keys_total);
- }
- elements_progress_bar_with_text(canvas, 0, 20, 128, dict_progress, draw_str);
- canvas_set_font(canvas, FontSecondary);
- snprintf(draw_str, sizeof(draw_str), "Keys found: %d/%d", m->keys_found, m->keys_total);
- canvas_draw_str_aligned(canvas, 0, 33, AlignLeft, AlignTop, draw_str);
- snprintf(
- draw_str,
- sizeof(draw_str),
- "Application Area Read: %d/%d",
- m->sectors_read,
- m->sectors_total);
- canvas_draw_str_aligned(canvas, 0, 43, AlignLeft, AlignTop, draw_str);
- elements_button_center(canvas, "Skip");
- }
- }
- static bool dict_attack_input_callback(InputEvent* event, void* context) {
- DictAttack* dict_attack = context;
- bool consumed = false;
- if(event->type == InputTypeShort && event->key == InputKeyOk) {
- if(dict_attack->callback) {
- dict_attack->callback(dict_attack->context);
- }
- consumed = true;
- }
- return consumed;
- }
- DictAttack* dict_attack_alloc() {
- DictAttack* dict_attack = malloc(sizeof(DictAttack));
- dict_attack->view = view_alloc();
- view_allocate_model(dict_attack->view, ViewModelTypeLocking, sizeof(DictAttackViewModel));
- view_set_draw_callback(dict_attack->view, dict_attack_draw_callback);
- view_set_input_callback(dict_attack->view, dict_attack_input_callback);
- view_set_context(dict_attack->view, dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- { model->header = furi_string_alloc(); },
- false);
- return dict_attack;
- }
- void dict_attack_free(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- { furi_string_free(model->header); },
- false);
- view_free(dict_attack->view);
- free(dict_attack);
- }
- void dict_attack_reset(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- model->state = DictAttackStateStart;
- model->sectors_total = 1;
- model->sectors_read = 0;
- model->sector_current = 0;
- model->keys_total = 0;
- model->keys_found = 0;
- model->dict_keys_total = 0;
- model->dict_keys_current = 0;
- model->is_key_attack = false;
- furi_string_reset(model->header);
- },
- false);
- }
- View* dict_attack_get_view(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- return dict_attack->view;
- }
- void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context) {
- furi_assert(dict_attack);
- furi_assert(callback);
- dict_attack->callback = callback;
- dict_attack->context = context;
- }
- void dict_attack_set_header(DictAttack* dict_attack, const char* header) {
- furi_assert(dict_attack);
- furi_assert(header);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- { furi_string_set(model->header, header); },
- true);
- }
- void dict_attack_set_card_detected(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- model->state = DictAttackStateRead;
- model->sectors_total = 1;
- model->keys_total = model->sectors_total;
- },
- true);
- }
- void dict_attack_set_card_removed(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- // Only mark card as removed it if had been Read
- if(model->state == DictAttackStateRead) {
- model->state = DictAttackStateCardRemoved;
- }
- },
- true);
- }
- void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view, DictAttackViewModel * model, { model->sectors_read = sec_read; }, true);
- }
- void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view, DictAttackViewModel * model, { model->keys_found = keys_found; }, true);
- }
- void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- model->sector_current = curr_sec;
- model->dict_keys_current = 0;
- },
- true);
- }
- void dict_attack_inc_current_sector(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- if(model->sector_current < model->sectors_total) {
- model->sector_current++;
- model->dict_keys_current = 0;
- }
- },
- true);
- }
- void dict_attack_inc_keys_found(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- if(model->keys_found < model->keys_total) {
- model->keys_found++;
- }
- },
- true);
- }
- void dict_attack_set_total_dict_keys(DictAttack* dict_attack, uint16_t dict_keys_total) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- { model->dict_keys_total = dict_keys_total; },
- true);
- }
- void dict_attack_set_current_dict_key(DictAttack* dict_attack, uint16_t current_key) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- { model->dict_keys_current = current_key; },
- true);
- }
- void dict_attack_inc_current_dict_key(DictAttack* dict_attack, uint16_t keys_tried) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- if(model->dict_keys_current + keys_tried < model->dict_keys_total) {
- model->dict_keys_current += keys_tried;
- }
- },
- true);
- }
- void dict_attack_set_key_attack(DictAttack* dict_attack, bool is_key_attack, uint8_t sector) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- model->is_key_attack = is_key_attack;
- model->key_attack_current_sector = sector;
- },
- true);
- }
- void dict_attack_inc_key_attack_current_sector(DictAttack* dict_attack) {
- furi_assert(dict_attack);
- with_view_model(
- dict_attack->view,
- DictAttackViewModel * model,
- {
- if(model->key_attack_current_sector < model->sectors_total) {
- model->key_attack_current_sector++;
- }
- },
- true);
- }
|