Skip to content

Commit 9313050

Browse files
committed
upd mfkey
fixes by Willy-JL
1 parent 86596b3 commit 9313050

File tree

3 files changed

+47
-57
lines changed

3 files changed

+47
-57
lines changed

base_pack/mfkey/application.fam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ App(
1515
fap_icon_assets="images",
1616
fap_weburl="https://github.com/noproto/FlipperMfkey",
1717
fap_description="MIFARE Classic key recovery tool",
18-
fap_version="2.1",
18+
fap_version="2.2",
1919
)
2020

2121
App(

base_pack/mfkey/mfkey.c

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,17 @@ int old_recover(
257257

258258
static inline int sync_state(ProgramState* program_state) {
259259
int ts = furi_hal_rtc_get_timestamp();
260-
program_state->eta_round = program_state->eta_round - (ts - program_state->eta_timestamp);
261-
program_state->eta_total = program_state->eta_total - (ts - program_state->eta_timestamp);
260+
int elapsed_time = ts - program_state->eta_timestamp;
261+
if(elapsed_time < program_state->eta_round) {
262+
program_state->eta_round -= elapsed_time;
263+
} else {
264+
program_state->eta_round = 0;
265+
}
266+
if(elapsed_time < program_state->eta_total) {
267+
program_state->eta_total -= elapsed_time;
268+
} else {
269+
program_state->eta_total = 0;
270+
}
262271
program_state->eta_timestamp = ts;
263272
if(program_state->close_thread_please) {
264273
return 1;
@@ -669,13 +678,10 @@ static void render_callback(Canvas* const canvas, void* ctx) {
669678
canvas_clear(canvas);
670679
canvas_draw_frame(canvas, 0, 0, 128, 64);
671680
canvas_draw_frame(canvas, 0, 15, 128, 64);
672-
canvas_set_font(canvas, FontPrimary);
673-
canvas_draw_str_aligned(canvas, 5, 4, AlignLeft, AlignTop, "MFKey");
674681
snprintf(draw_str, sizeof(draw_str), "RAM: %zub", memmgr_get_free_heap());
675-
canvas_set_font(canvas, FontSecondary);
676682
canvas_draw_str_aligned(canvas, 48, 5, AlignLeft, AlignTop, draw_str);
677683
canvas_draw_icon(canvas, 114, 4, &I_mfkey);
678-
if(program_state->is_thread_running && program_state->mfkey_state == MFKeyAttack) {
684+
if(program_state->mfkey_state == MFKeyAttack) {
679685
float eta_round = (float)1 - ((float)program_state->eta_round / (float)eta_round_time);
680686
float eta_total = (float)1 - ((float)program_state->eta_total / (float)eta_total_time);
681687
float progress = (float)program_state->num_completed / (float)program_state->total;
@@ -689,7 +695,6 @@ static void render_callback(Canvas* const canvas, void* ctx) {
689695
eta_total = 1;
690696
program_state->eta_total = 0;
691697
}
692-
canvas_set_font(canvas, FontSecondary);
693698
snprintf(
694699
draw_str,
695700
sizeof(draw_str),
@@ -707,39 +712,33 @@ static void render_callback(Canvas* const canvas, void* ctx) {
707712
elements_progress_bar_with_text(canvas, 5, 31, 118, eta_round, draw_str);
708713
snprintf(draw_str, sizeof(draw_str), "Total ETA %03d Sec", program_state->eta_total);
709714
elements_progress_bar_with_text(canvas, 5, 44, 118, eta_total, draw_str);
710-
} else if(program_state->is_thread_running && program_state->mfkey_state == DictionaryAttack) {
711-
canvas_set_font(canvas, FontSecondary);
715+
} else if(program_state->mfkey_state == DictionaryAttack) {
712716
snprintf(
713717
draw_str, sizeof(draw_str), "Dict solves: %d (in progress)", program_state->cracked);
714718
canvas_draw_str_aligned(canvas, 10, 18, AlignLeft, AlignTop, draw_str);
715719
snprintf(draw_str, sizeof(draw_str), "Keys in dict: %d", program_state->dict_count);
716720
canvas_draw_str_aligned(canvas, 26, 28, AlignLeft, AlignTop, draw_str);
717721
} else if(program_state->mfkey_state == Complete) {
718722
// TODO: Scrollable list view to see cracked keys if user presses down
719-
elements_progress_bar_with_text(canvas, 5, 18, 118, 1, draw_str);
720-
canvas_set_font(canvas, FontSecondary);
721-
snprintf(draw_str, sizeof(draw_str), "Complete");
722-
canvas_draw_str_aligned(canvas, 40, 31, AlignLeft, AlignTop, draw_str);
723+
elements_progress_bar(canvas, 5, 18, 118, 1);
724+
canvas_draw_str_aligned(canvas, 40, 31, AlignLeft, AlignTop, "Complete");
723725
snprintf(
724726
draw_str,
725727
sizeof(draw_str),
726728
"Keys added to user dict: %d",
727729
program_state->unique_cracked);
728730
canvas_draw_str_aligned(canvas, 10, 41, AlignLeft, AlignTop, draw_str);
729731
} else if(program_state->mfkey_state == Ready) {
730-
canvas_set_font(canvas, FontSecondary);
731732
canvas_draw_str_aligned(canvas, 50, 30, AlignLeft, AlignTop, "Ready");
732733
elements_button_center(canvas, "Start");
733734
elements_button_right(canvas, "Help");
734735
} else if(program_state->mfkey_state == Help) {
735-
canvas_set_font(canvas, FontSecondary);
736736
canvas_draw_str_aligned(canvas, 7, 20, AlignLeft, AlignTop, "Collect nonces using Detect");
737737
canvas_draw_str_aligned(canvas, 7, 30, AlignLeft, AlignTop, "Reader or FlipperNested.");
738738
canvas_draw_str_aligned(canvas, 7, 40, AlignLeft, AlignTop, "Devs: noproto, AG, ALiberty");
739739
canvas_draw_str_aligned(canvas, 7, 50, AlignLeft, AlignTop, "Thanks: bettse, Foxushka");
740740
} else if(program_state->mfkey_state == Error) {
741741
canvas_draw_str_aligned(canvas, 50, 25, AlignLeft, AlignTop, "Error");
742-
canvas_set_font(canvas, FontSecondary);
743742
if(program_state->err == MissingNonces) {
744743
canvas_draw_str_aligned(canvas, 25, 36, AlignLeft, AlignTop, "No nonces found");
745744
} else if(program_state->err == ZeroNonces) {
@@ -752,6 +751,8 @@ static void render_callback(Canvas* const canvas, void* ctx) {
752751
} else {
753752
// Unhandled program state
754753
}
754+
canvas_set_font(canvas, FontPrimary);
755+
canvas_draw_str_aligned(canvas, 5, 4, AlignLeft, AlignTop, "MFKey");
755756
furi_mutex_release(program_state->mutex);
756757
}
757758

@@ -763,7 +764,6 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
763764
}
764765

765766
static void mfkey_state_init(ProgramState* program_state) {
766-
program_state->is_thread_running = false;
767767
program_state->mfkey_state = Ready;
768768
program_state->cracked = 0;
769769
program_state->unique_cracked = 0;
@@ -775,20 +775,12 @@ static void mfkey_state_init(ProgramState* program_state) {
775775
// Entrypoint for worker thread
776776
static int32_t mfkey_worker_thread(void* ctx) {
777777
ProgramState* program_state = ctx;
778-
program_state->is_thread_running = true;
779778
program_state->mfkey_state = Initializing;
780779
//FURI_LOG_I(TAG, "Hello from the mfkey worker thread"); // DEBUG
781780
mfkey(program_state);
782-
program_state->is_thread_running = false;
783781
return 0;
784782
}
785783

786-
void start_mfkey_thread(ProgramState* program_state) {
787-
if(!program_state->is_thread_running) {
788-
furi_thread_start(program_state->mfkeythread);
789-
}
790-
}
791-
792784
int32_t mfkey_main() {
793785
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
794786

@@ -812,11 +804,8 @@ int32_t mfkey_main() {
812804
Gui* gui = furi_record_open(RECORD_GUI);
813805
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
814806

815-
program_state->mfkeythread = furi_thread_alloc();
816-
furi_thread_set_name(program_state->mfkeythread, "MFKey Worker");
817-
furi_thread_set_stack_size(program_state->mfkeythread, 2048);
818-
furi_thread_set_context(program_state->mfkeythread, program_state);
819-
furi_thread_set_callback(program_state->mfkeythread, mfkey_worker_thread);
807+
program_state->mfkeythread =
808+
furi_thread_alloc_ex("MFKey Worker", 2048, mfkey_worker_thread, program_state);
820809

821810
PluginEvent event;
822811
for(bool main_loop = true; main_loop;) {
@@ -834,33 +823,27 @@ int32_t mfkey_main() {
834823
case InputKeyDown:
835824
break;
836825
case InputKeyRight:
837-
if(!program_state->is_thread_running &&
838-
program_state->mfkey_state == Ready) {
826+
if(program_state->mfkey_state == Ready) {
839827
program_state->mfkey_state = Help;
840828
view_port_update(view_port);
841829
}
842830
break;
843831
case InputKeyLeft:
844832
break;
845833
case InputKeyOk:
846-
if(!program_state->is_thread_running &&
847-
program_state->mfkey_state == Ready) {
848-
start_mfkey_thread(program_state);
834+
if(program_state->mfkey_state == Ready) {
835+
furi_thread_start(program_state->mfkeythread);
849836
view_port_update(view_port);
850837
}
851838
break;
852839
case InputKeyBack:
853-
if(!program_state->is_thread_running &&
854-
program_state->mfkey_state == Help) {
840+
if(program_state->mfkey_state == Help) {
855841
program_state->mfkey_state = Ready;
856842
view_port_update(view_port);
857843
} else {
858844
program_state->close_thread_please = true;
859-
if(program_state->is_thread_running && program_state->mfkeythread) {
860-
// Wait until thread is finished
861-
furi_thread_join(program_state->mfkeythread);
862-
}
863-
program_state->close_thread_please = false;
845+
// Wait until thread is finished
846+
furi_thread_join(program_state->mfkeythread);
864847
main_loop = false;
865848
}
866849
break;
@@ -875,6 +858,7 @@ int32_t mfkey_main() {
875858
furi_mutex_release(program_state->mutex);
876859
}
877860

861+
// Thread joined in back event handler
878862
furi_thread_free(program_state->mfkeythread);
879863
view_port_enabled_set(view_port, false);
880864
gui_remove_view_port(gui, view_port);

base_pack/mfkey/mfkey.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,26 @@ typedef struct {
7474
uint32_t nt1; // tag challenge second
7575
uint32_t uid_xor_nt0; // uid ^ nt0
7676
uint32_t uid_xor_nt1; // uid ^ nt1
77-
// Mfkey32
78-
uint32_t p64; // 64th successor of nt0
79-
uint32_t p64b; // 64th successor of nt1
80-
uint32_t nr0_enc; // first encrypted reader challenge
81-
uint32_t ar0_enc; // first encrypted reader response
82-
uint32_t nr1_enc; // second encrypted reader challenge
83-
uint32_t ar1_enc; // second encrypted reader response
84-
// Nested
85-
uint32_t ks1_1_enc; // first encrypted keystream
86-
uint32_t ks1_2_enc; // second encrypted keystream
87-
char par_1_str[5]; // first parity bits (string representation)
88-
char par_2_str[5]; // second parity bits (string representation)
89-
uint8_t par_1; // first parity bits
90-
uint8_t par_2; // second parity bits
77+
union {
78+
// Mfkey32
79+
struct {
80+
uint32_t p64; // 64th successor of nt0
81+
uint32_t p64b; // 64th successor of nt1
82+
uint32_t nr0_enc; // first encrypted reader challenge
83+
uint32_t ar0_enc; // first encrypted reader response
84+
uint32_t nr1_enc; // second encrypted reader challenge
85+
uint32_t ar1_enc; // second encrypted reader response
86+
};
87+
// Nested
88+
struct {
89+
uint32_t ks1_1_enc; // first encrypted keystream
90+
uint32_t ks1_2_enc; // second encrypted keystream
91+
char par_1_str[5]; // first parity bits (string representation)
92+
char par_2_str[5]; // second parity bits (string representation)
93+
uint8_t par_1; // first parity bits
94+
uint8_t par_2; // second parity bits
95+
};
96+
};
9197
} MfClassicNonce;
9298

9399
typedef struct {

0 commit comments

Comments
 (0)