From 8936c024874e04d07269b09b86a8d8eb7f97d3e8 Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 8 Aug 2023 14:16:35 +0300 Subject: [PATCH] NFC App: Add manual MF Classic custom UID --- .../main/nfc/helpers/nfc_custom_event.h | 7 ++ .../main/nfc/scenes/nfc_scene_save_name.c | 3 + .../main/nfc/scenes/nfc_scene_set_type.c | 80 +++++++++++++++++++ .../main/nfc/scenes/nfc_scene_set_uid.c | 50 +++++++++++- firmware/targets/f7/api_symbols.csv | 1 + lib/nfc/helpers/nfc_generators.c | 21 ++++- lib/nfc/helpers/nfc_generators.h | 15 ++++ 7 files changed, 170 insertions(+), 7 deletions(-) diff --git a/applications/main/nfc/helpers/nfc_custom_event.h b/applications/main/nfc/helpers/nfc_custom_event.h index aa932a3d8..b2ad3170c 100644 --- a/applications/main/nfc/helpers/nfc_custom_event.h +++ b/applications/main/nfc/helpers/nfc_custom_event.h @@ -15,3 +15,10 @@ enum NfcCustomEvent { NfcCustomEventUpdateLog, NfcCustomEventSaveShadow, }; + +enum NfcSceneSetUidState { + NfcSceneSetUidStateNotSet, + NfcSceneSetUidStateMFClassic1k, + NfcSceneSetUidStateMFClassic4k, + NfcSceneSetUidStateMFClassicMini, +}; diff --git a/applications/main/nfc/scenes/nfc_scene_save_name.c b/applications/main/nfc/scenes/nfc_scene_save_name.c index a7b97aac0..327a31292 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_name.c +++ b/applications/main/nfc/scenes/nfc_scene_save_name.c @@ -67,6 +67,9 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(!scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { // Nothing, do not count editing as saving } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) { + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateNotSet); + dolphin_deed(DolphinDeedNfcAddSave); } else { dolphin_deed(DolphinDeedNfcSave); diff --git a/applications/main/nfc/scenes/nfc_scene_set_type.c b/applications/main/nfc/scenes/nfc_scene_set_type.c index cadf2eb69..d17b7616f 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_type.c +++ b/applications/main/nfc/scenes/nfc_scene_set_type.c @@ -4,9 +4,19 @@ enum SubmenuIndex { SubmenuIndexNFCA4, SubmenuIndexNFCA7, + SubmenuIndexMFC1k4Uid, + SubmenuIndexMFC4k4Uid, + SubmenuIndexMFC1k7Uid, + SubmenuIndexMFC4k7Uid, + SubmenuIndexMFCMini, SubmenuIndexGeneratorsStart, }; +static const NfcGenerator ganeator_gag = { + .name = "Mifare Classic Custom UID", + .generator_func = NULL, +}; + void nfc_scene_set_type_submenu_callback(void* context, uint32_t index) { Nfc* nfc = context; @@ -23,6 +33,36 @@ void nfc_scene_set_type_on_enter(void* context) { submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu_add_item( submenu, "NFC-A 4-bytes UID", SubmenuIndexNFCA4, nfc_scene_set_type_submenu_callback, nfc); + submenu_add_item( + submenu, + "MFClassic1k4b Custom uid", + SubmenuIndexMFC1k4Uid, + nfc_scene_set_type_submenu_callback, + nfc); + submenu_add_item( + submenu, + "MFClassic4k4b Custom uid", + SubmenuIndexMFC4k4Uid, + nfc_scene_set_type_submenu_callback, + nfc); + submenu_add_item( + submenu, + "MFClassic1k7b Custom uid", + SubmenuIndexMFC1k7Uid, + nfc_scene_set_type_submenu_callback, + nfc); + submenu_add_item( + submenu, + "MFClassic4k7b Custom uid ", + SubmenuIndexMFC4k7Uid, + nfc_scene_set_type_submenu_callback, + nfc); + submenu_add_item( + submenu, + "MFClassic Mini Custom uid ", + SubmenuIndexMFCMini, + nfc_scene_set_type_submenu_callback, + nfc); // Generators int i = SubmenuIndexGeneratorsStart; @@ -49,6 +89,46 @@ bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) { nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); consumed = true; + } else if(event.event == SubmenuIndexMFC1k4Uid) { + nfc->dev->dev_data.nfc_data.uid_len = 4; + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->generator = &ganeator_gag; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateMFClassic1k); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + consumed = true; + } else if(event.event == SubmenuIndexMFC1k7Uid) { + nfc->dev->dev_data.nfc_data.uid_len = 7; + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->generator = &ganeator_gag; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateMFClassic1k); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + consumed = true; + } else if(event.event == SubmenuIndexMFC4k4Uid) { + nfc->dev->dev_data.nfc_data.uid_len = 4; + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->generator = &ganeator_gag; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateMFClassic4k); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + consumed = true; + } else if(event.event == SubmenuIndexMFC4k7Uid) { + nfc->dev->dev_data.nfc_data.uid_len = 7; + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->generator = &ganeator_gag; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateMFClassic4k); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + consumed = true; + } else if(event.event == SubmenuIndexMFCMini) { + nfc->dev->dev_data.nfc_data.uid_len = 4; + nfc->dev->format = NfcDeviceSaveFormatMifareClassic; + nfc->generator = &ganeator_gag; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateMFClassicMini); + scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + consumed = true; } else { nfc_device_clear(nfc->dev); nfc->generator = nfc_generators[event.event - SubmenuIndexGeneratorsStart]; diff --git a/applications/main/nfc/scenes/nfc_scene_set_uid.c b/applications/main/nfc/scenes/nfc_scene_set_uid.c index 54606b68e..d1df352f1 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_set_uid.c @@ -27,7 +27,10 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = (Nfc*)context; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { + if(event.type == SceneManagerEventTypeBack) { + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneSetUid, NfcSceneSetUidStateNotSet); + } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventByteInputDone) { if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { nfc->dev->dev_data.nfc_data = nfc->dev_edit_data; @@ -36,8 +39,49 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) { consumed = true; } } else { - scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - consumed = true; + switch(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSetUid)) { + case NfcSceneSetUidStateMFClassic1k: + nfc_generate_mf_classic_ext( + &nfc->dev->dev_data, + nfc->dev_edit_data.uid_len, + MfClassicType1k, + false, + nfc->dev_edit_data.uid); + scene_manager_next_scene(nfc->scene_manager, NfcSceneGenerateInfo); + consumed = true; + break; + + case NfcSceneSetUidStateMFClassic4k: + nfc_generate_mf_classic_ext( + &nfc->dev->dev_data, + nfc->dev_edit_data.uid_len, + MfClassicType4k, + false, + nfc->dev_edit_data.uid); + scene_manager_next_scene(nfc->scene_manager, NfcSceneGenerateInfo); + consumed = true; + break; + + case NfcSceneSetUidStateMFClassicMini: + nfc_generate_mf_classic_ext( + &nfc->dev->dev_data, + nfc->dev_edit_data.uid_len, + MfClassicTypeMini, + false, + nfc->dev_edit_data.uid); + scene_manager_next_scene(nfc->scene_manager, NfcSceneGenerateInfo); + consumed = true; + break; + + case NfcSceneSetUidStateNotSet: + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); + consumed = true; + break; + + default: + furi_crash("Nfc unknown type"); + break; + } } } } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a6807e131..86296975d 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2138,6 +2138,7 @@ Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, Function,+,nfc_device_set_name,void,"NfcDevice*, const char*" Function,+,nfc_file_select,_Bool,NfcDevice* Function,-,nfc_generate_mf_classic,void,"NfcDeviceData*, uint8_t, MfClassicType" +Function,+,nfc_generate_mf_classic_ext,void,"NfcDeviceData*, uint8_t, MfClassicType, _Bool, uint8_t*" Function,+,nfc_get_dev_type,const char*,FuriHalNfcType Function,-,nfc_guess_protocol,const char*,NfcProtocol Function,+,nfc_mf_classic_type,const char*,MfClassicType diff --git a/lib/nfc/helpers/nfc_generators.c b/lib/nfc/helpers/nfc_generators.c index 50c89aba8..c65ffcedb 100644 --- a/lib/nfc/helpers/nfc_generators.c +++ b/lib/nfc/helpers/nfc_generators.c @@ -333,14 +333,22 @@ static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) { mful->version.storage_size = 0x15; } -void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { +void nfc_generate_mf_classic_ext( + NfcDeviceData* data, + uint8_t uid_len, + MfClassicType type, + bool random_uid, + uint8_t* uid) { nfc_generate_common_start(data); - nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len); + if(random_uid) { + nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len); + } else { + memcpy(data->mf_classic_data.block[0].value, uid, uid_len); + } nfc_generate_mf_classic_common(data, uid_len, type); // Set the UID - data->nfc_data.uid[0] = NXP_MANUFACTURER_ID; - for(int i = 1; i < uid_len; i++) { + for(int i = 0; i < uid_len; i++) { data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i]; } @@ -395,6 +403,11 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType mfc->type = type; } +void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { + uint8_t uid = 0; + nfc_generate_mf_classic_ext(data, uid_len, type, true, &uid); +} + static void nfc_generate_mf_mini(NfcDeviceData* data) { nfc_generate_mf_classic(data, 4, MfClassicTypeMini); } diff --git a/lib/nfc/helpers/nfc_generators.h b/lib/nfc/helpers/nfc_generators.h index 8cee67067..5102d0bc3 100644 --- a/lib/nfc/helpers/nfc_generators.h +++ b/lib/nfc/helpers/nfc_generators.h @@ -2,6 +2,10 @@ #include "../nfc_device.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef void (*NfcGeneratorFunc)(NfcDeviceData* data); typedef struct { @@ -12,3 +16,14 @@ typedef struct { extern const NfcGenerator* const nfc_generators[]; void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type); + +void nfc_generate_mf_classic_ext( + NfcDeviceData* data, + uint8_t uid_len, + MfClassicType type, + bool random_uid, + uint8_t* uid); + +#ifdef __cplusplus +} +#endif \ No newline at end of file