From 1b6295b2bf38c0218ebe3c1168db18db63d90f70 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Mon, 23 Oct 2023 12:49:16 +0300 Subject: [PATCH 01/28] [FL-3632] FastFAP: human readable error log (#3156) --- lib/flipper_application/elf/elf_file.c | 55 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index 9b8b4c8f5..b2c9445ff 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -613,10 +613,31 @@ static Elf32_Addr elf_address_of_by_hash(ELFFile* elf, uint32_t hash) { return ELF_INVALID_ADDRESS; } +static bool elf_file_find_string_by_hash(ELFFile* elf, uint32_t hash, FuriString* out) { + bool result = false; + + FuriString* symbol_name = furi_string_alloc(); + Elf32_Sym sym; + for(size_t i = 0; i < elf->symbol_count; i++) { + furi_string_reset(symbol_name); + if(elf_read_symbol(elf, i, &sym, symbol_name)) { + if(elf_symbolname_hash(furi_string_get_cstr(symbol_name)) == hash) { + furi_string_set(out, symbol_name); + result = true; + break; + } + } + } + furi_string_free(symbol_name); + + return result; +} + static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { UNUSED(elf); const uint8_t* start = s->fast_rel->data; const uint8_t version = *start; + bool no_errors = true; if(version != FAST_RELOCATION_VERSION) { FURI_LOG_E(TAG, "Unsupported fast relocation version %d", version); @@ -664,16 +685,30 @@ static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { } if(address == ELF_INVALID_ADDRESS) { - FURI_LOG_E(TAG, "Failed to resolve address for hash %lX", hash_or_section_index); - return false; - } + FuriString* symbol_name = furi_string_alloc(); + if(elf_file_find_string_by_hash(elf, hash_or_section_index, symbol_name)) { + FURI_LOG_E( + TAG, + "Failed to resolve address for symbol %s (hash %lX)", + furi_string_get_cstr(symbol_name), + hash_or_section_index); + } else { + FURI_LOG_E( + TAG, + "Failed to resolve address for hash %lX (string not found)", + hash_or_section_index); + } + furi_string_free(symbol_name); - for(uint32_t j = 0; j < offsets_count; j++) { - uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF; - start += 3; - // FURI_LOG_I(TAG, " Fast relocation offset %ld: %ld", j, offset); - Elf32_Addr relAddr = ((Elf32_Addr)s->data) + offset; - elf_relocate_symbol(elf, relAddr, type, address); + no_errors = false; + start += 3 * offsets_count; + } else { + for(uint32_t j = 0; j < offsets_count; j++) { + uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF; + start += 3; + Elf32_Addr relAddr = ((Elf32_Addr)s->data) + offset; + elf_relocate_symbol(elf, relAddr, type, address); + } } } @@ -681,7 +716,7 @@ static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) { free(s->fast_rel); s->fast_rel = NULL; - return true; + return no_errors; } static bool elf_relocate_section(ELFFile* elf, ELFSection* section) { From 35c903494c511f41a518dd045be5ab8991fa3991 Mon Sep 17 00:00:00 2001 From: hedger Date: Mon, 23 Oct 2023 13:55:36 +0400 Subject: [PATCH 02/28] [FL-3627, FL-3628, FL-3631] fbt: glob & git improvements (#3151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fbt: optional shallow submodule checkout * fbt: more git threads by default * fbt: git condition fix * fbt: renamed FBT_SHALLOW to FBT_GIT_SUBMODULE_SHALLOW * github: enabled FBT_GIT_SUBMODULE_SHALLOW in flows * fbt: always compile icons' .c, even if user does not specify a proper source glob; changed glob to require files at user-specified paths to exist * fbt: fail build for missing imports in .faps * fbt: moved STRICT_FAP_IMPORT_CHECK to commandline options; enabled by default * ufbt: enabled STRICT_FAP_IMPORT_CHECK Co-authored-by: ใ‚ใ --- .github/workflows/build.yml | 1 + .github/workflows/build_compact.yml | 1 + .github/workflows/pvs_studio.yml | 1 + .github/workflows/unit_tests.yml | 1 + .github/workflows/updater_test.yml | 1 + fbt | 11 +++++++++-- fbt.cmd | 12 ++++++++++-- scripts/fbt/appmanifest.py | 4 ++++ scripts/fbt_tools/fbt_extapps.py | 15 +++++++++++++-- scripts/fbt_tools/sconsrecursiveglob.py | 7 +++---- scripts/ufbt/commandline.scons | 5 +++++ site_scons/commandline.scons | 5 +++++ 12 files changed, 54 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7a7188837..4c5535066 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,7 @@ on: env: DEFAULT_TARGET: f7 FBT_TOOLCHAIN_PATH: /runner/_work + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: main: diff --git a/.github/workflows/build_compact.yml b/.github/workflows/build_compact.yml index 7556c15ac..c63be24a4 100644 --- a/.github/workflows/build_compact.yml +++ b/.github/workflows/build_compact.yml @@ -5,6 +5,7 @@ on: env: FBT_TOOLCHAIN_PATH: /runner/_work + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: compact: diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 24964a309..4f650f1b7 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -10,6 +10,7 @@ env: TARGETS: f7 DEFAULT_TARGET: f7 FBT_TOOLCHAIN_PATH: /runner/_work + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: analyse_c_cpp: diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 794dce37f..35085ba57 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -7,6 +7,7 @@ env: TARGETS: f7 DEFAULT_TARGET: f7 FBT_TOOLCHAIN_PATH: /opt + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: run_units_on_bench: diff --git a/.github/workflows/updater_test.yml b/.github/workflows/updater_test.yml index f4064e1cc..9987fdd32 100644 --- a/.github/workflows/updater_test.yml +++ b/.github/workflows/updater_test.yml @@ -7,6 +7,7 @@ env: TARGETS: f7 DEFAULT_TARGET: f7 FBT_TOOLCHAIN_PATH: /opt + FBT_GIT_SUBMODULE_SHALLOW: 1 jobs: test_updater_on_bench: diff --git a/fbt b/fbt index 26f325d45..e6133d07b 100755 --- a/fbt +++ b/fbt @@ -5,7 +5,8 @@ set -eu; # private variables -N_GIT_THREADS="$(getconf _NPROCESSORS_ONLN)"; +N_CORES="$(getconf _NPROCESSORS_ONLN)"; +N_GIT_THREADS="$(($N_CORES * 2))"; SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)"; SCONS_DEFAULT_FLAGS="--warn=target-not-built"; SCONS_EP="python3 -m SCons"; @@ -15,6 +16,7 @@ FBT_NOENV="${FBT_NOENV:-""}"; FBT_NO_SYNC="${FBT_NO_SYNC:-""}"; FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}"; FBT_VERBOSE="${FBT_VERBOSE:-""}"; +FBT_GIT_SUBMODULE_SHALLOW="${FBT_GIT_SUBMODULE_SHALLOW:-""}"; if [ -z "$FBT_NOENV" ]; then FBT_VERBOSE="$FBT_VERBOSE" . "$SCRIPT_PATH/scripts/toolchain/fbtenv.sh"; @@ -29,7 +31,12 @@ if [ -z "$FBT_NO_SYNC" ]; then echo "\".git\" directory not found, please clone repo via \"git clone\""; exit 1; fi - git submodule update --init --jobs "$N_GIT_THREADS"; + _FBT_CLONE_FLAGS="--jobs $N_GIT_THREADS"; + if [ ! -z "$FBT_GIT_SUBMODULE_SHALLOW" ]; then + _FBT_CLONE_FLAGS="$_FBT_CLONE_FLAGS --depth 1"; + fi + + git submodule update --init --recursive $_FBT_CLONE_FLAGS; fi $SCONS_EP $SCONS_DEFAULT_FLAGS "$@" diff --git a/fbt.cmd b/fbt.cmd index 03e4ec3d0..20432be1c 100644 --- a/fbt.cmd +++ b/fbt.cmd @@ -4,10 +4,18 @@ call "%~dp0scripts\toolchain\fbtenv.cmd" env set SCONS_EP=python -m SCons if [%FBT_NO_SYNC%] == [] ( + set _FBT_CLONE_FLAGS=--jobs %NUMBER_OF_PROCESSORS% + if not [%FBT_GIT_SUBMODULE_SHALLOW%] == [] ( + set _FBT_CLONE_FLAGS=%_FBT_CLONE_FLAGS% --depth 1 + ) if exist ".git" ( - git submodule update --init --depth 1 --jobs %NUMBER_OF_PROCESSORS% + git submodule update --init --recursive %_FBT_CLONE_FLAGS% + if %ERRORLEVEL% neq 0 ( + echo Failed to update submodules, set FBT_NO_SYNC to skip + exit /b 1 + ) ) else ( - echo Not in a git repo, please clone with "git clone" + echo .git not found, please clone repo with "git clone" exit /b 1 ) ) diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index ff49707b1..1a6cae9b1 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -100,6 +100,10 @@ class FlipperApplication: def is_default_deployable(self): return self.apptype != FlipperAppType.DEBUG and self.fap_category != "Examples" + @property + def do_strict_import_checks(self): + return self.apptype != FlipperAppType.PLUGIN + def __post_init__(self): if self.apptype == FlipperAppType.PLUGIN: self.stack_size = 0 diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index bc8f9d5df..963429f24 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -42,6 +42,7 @@ class AppBuilder: self.ext_apps_work_dir = env["EXT_APPS_WORK_DIR"] self.app_work_dir = self.get_app_work_dir(env, app) self.app_alias = f"fap_{self.app.appid}" + self.icons_src = None self.externally_built_files = [] self.private_libs = [] @@ -93,6 +94,7 @@ class AppBuilder: ) self.app_env.Alias("_fap_icons", fap_icons) self.fw_env.Append(_APP_ICONS=[fap_icons]) + self.icons_src = next(filter(lambda n: n.path.endswith(".c"), fap_icons)) def _build_private_libs(self): for lib_def in self.app.fap_private_libs: @@ -160,6 +162,10 @@ class AppBuilder: if not app_sources: raise UserError(f"No source files found for {self.app.appid}") + # Ensure that icons are included in the build, regardless of user-configured sources + if self.icons_src and not self.icons_src in app_sources: + app_sources.append(self.icons_src) + ## Uncomment for debug # print(f"App sources for {self.app.appid}: {list(f.path for f in app_sources)}") @@ -180,7 +186,9 @@ class AppBuilder: self.app._assets_dirs.append(self.app_work_dir.Dir("assets")) app_artifacts.validator = self.app_env.ValidateAppImports( - app_artifacts.compact + app_artifacts.compact, + _CHECK_APP=self.app.do_strict_import_checks + and self.app_env.get("STRICT_FAP_IMPORT_CHECK"), )[0] if self.app.apptype == FlipperAppType.PLUGIN: @@ -300,7 +308,10 @@ def validate_app_imports(target, source, env): + fg.brightmagenta(f"{disabled_api_syms}") + fg.brightyellow(")") ) - SCons.Warnings.warn(SCons.Warnings.LinkWarning, warning_msg), + if env.get("_CHECK_APP"): + raise UserError(warning_msg) + else: + SCons.Warnings.warn(SCons.Warnings.LinkWarning, warning_msg), def GetExtAppByIdOrPath(env, app_dir): diff --git a/scripts/fbt_tools/sconsrecursiveglob.py b/scripts/fbt_tools/sconsrecursiveglob.py index 38aa9a839..e7eb8fb72 100644 --- a/scripts/fbt_tools/sconsrecursiveglob.py +++ b/scripts/fbt_tools/sconsrecursiveglob.py @@ -20,10 +20,9 @@ def GlobRecursive(env, pattern, node=".", exclude=[]): source=True, exclude=exclude, ) - # Otherwise, just check if that's an existing file path - # NB: still creates "virtual" nodes as part of existence check - elif (file_node := node.File(pattern)).exists() or file_node.rexists(): - results.append(file_node) + # Otherwise, just assume that file at path exists + else: + results.append(node.File(pattern)) # print(f"Glob result for {pattern} from {node}: {results}") return results diff --git a/scripts/ufbt/commandline.scons b/scripts/ufbt/commandline.scons index 99c34c35d..a3ba7e08d 100644 --- a/scripts/ufbt/commandline.scons +++ b/scripts/ufbt/commandline.scons @@ -88,6 +88,11 @@ vars.AddVariables( "CDC Port of Flipper to use, if multiple are connected", "auto", ), + BoolVariable( + "STRICT_FAP_IMPORT_CHECK", + help="Enable strict import check for .faps", + default=True, + ), ) Return("vars") diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index f75d5e0e4..2d2abd5c6 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -269,6 +269,11 @@ vars.AddVariables( "clangd", ], ), + BoolVariable( + "STRICT_FAP_IMPORT_CHECK", + help="Enable strict import check for .faps", + default=True, + ), ) Return("vars") From ac5abdbb1db0ded15b2610a3ffd70199c45c6859 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 24 Oct 2023 00:56:15 +0300 Subject: [PATCH 03/28] add new env var --- .drone.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.drone.yml b/.drone.yml index 39a79b2cf..341f49e4e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -22,6 +22,7 @@ steps: - export DIST_SUFFIX=${DRONE_TAG}c - export WORKFLOW_BRANCH_OR_TAG=release-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -rf assets/resources/apps/ - rm -rf build/ - rm -rf dist/ @@ -42,6 +43,7 @@ steps: - export DIST_SUFFIX=${DRONE_TAG} - export WORKFLOW_BRANCH_OR_TAG=release-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz - tar zxvf all-the-apps-base.tgz - cp -R base_pack_build/artifacts-base/* assets/resources/apps/ @@ -69,6 +71,7 @@ steps: - export DIST_SUFFIX=${DRONE_TAG}e - export WORKFLOW_BRANCH_OR_TAG=release-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-extra-apps @@ -87,6 +90,7 @@ steps: - export DIST_SUFFIX=${DRONE_TAG}r - export WORKFLOW_BRANCH_OR_TAG=release-cfw-rgb - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-rgb-patch @@ -109,6 +113,7 @@ steps: - export DIST_SUFFIX=${DRONE_TAG}n - export WORKFLOW_BRANCH_OR_TAG=no-custom-anims - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz @@ -391,6 +396,7 @@ steps: - export DIST_SUFFIX=${DRONE_BUILD_NUMBER}c - export WORKFLOW_BRANCH_OR_TAG=dev-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -rf assets/resources/apps/ - rm -rf build/ - rm -rf dist/ @@ -412,6 +418,7 @@ steps: - export DIST_SUFFIX=${DRONE_BUILD_NUMBER} - export WORKFLOW_BRANCH_OR_TAG=dev-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz - tar zxvf all-the-apps-base.tgz - cp -R base_pack_build/artifacts-base/* assets/resources/apps/ @@ -439,6 +446,7 @@ steps: - export DIST_SUFFIX=${DRONE_BUILD_NUMBER}e - export WORKFLOW_BRANCH_OR_TAG=dev-cfw - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-extra-apps @@ -457,6 +465,7 @@ steps: - export DIST_SUFFIX=${DRONE_BUILD_NUMBER}r - export WORKFLOW_BRANCH_OR_TAG=dev-cfw-rgb - export FORCE_NO_DIRTY=yes + - export FBT_GIT_SUBMODULE_SHALLOW=1 - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-rgb-patch From 73baec523053d76694edb1ddff74ccca9c24ee13 Mon Sep 17 00:00:00 2001 From: Leeroy Date: Tue, 24 Oct 2023 09:59:02 +1100 Subject: [PATCH 04/28] About on Power Off Menu. --- .../scenes/power_settings_scene_power_off.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c index 573c4c4f8..8cacbffff 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c @@ -20,7 +20,7 @@ void power_settings_scene_power_off_on_enter(void* context) { dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop); } dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52); - dialog_ex_set_left_button_text(dialog, "Back"); + dialog_ex_set_left_button_text(dialog, "About"); dialog_ex_set_right_button_text(dialog, "OFF"); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); dialog_ex_set_context(dialog, app); @@ -35,8 +35,7 @@ bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); + scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneBatteryInfo); } } else if(event.event == DialogExResultRight) { power_off(app->power); From 1562e031c37ddb0d57cd54217ea1f5caceb7cf5f Mon Sep 17 00:00:00 2001 From: Leeroy Date: Tue, 24 Oct 2023 10:08:08 +1100 Subject: [PATCH 05/28] Change back button exit to short press (or stop transmission if one active. Brings behaviour into lie with other apps. --- .../system/subghz_remote/views/remote.c | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/applications/system/subghz_remote/views/remote.c b/applications/system/subghz_remote/views/remote.c index fc7608624..bdf4b89c3 100644 --- a/applications/system/subghz_remote/views/remote.c +++ b/applications/system/subghz_remote/views/remote.c @@ -201,21 +201,30 @@ bool subrem_view_remote_input(InputEvent* event, void* context) { furi_assert(context); SubRemViewRemote* subrem_view_remote = context; - if(event->key == InputKeyBack && event->type == InputTypeLong) { - subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack && event->type == InputTypeShort) { + if(event->key == InputKeyBack && event->type == InputTypePress) { + bool is_stopping = false; with_view_model( subrem_view_remote->view, SubRemViewRemoteModel * model, - { model->pressed_btn = 0; }, + { + if(model->state == SubRemViewRemoteStateSending) { + is_stopping = true; + model->pressed_btn = 0; + } + }, true); - subrem_view_remote->callback( - SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack) { + + //Cant send exit the app inside that with_model,locks the model and the app will hang and not unload! + if(is_stopping) + subrem_view_remote->callback( + SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); + else + subrem_view_remote->callback( + SubRemCustomEventViewRemoteBack, subrem_view_remote->context); + return true; } + // BACK button processing end if(event->key == InputKeyUp && event->type == InputTypePress) { From 4bbdbcf2c7a9c07d734eee34fffb6d7dd3a1ebcf Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 23 Oct 2023 23:24:41 +0100 Subject: [PATCH 06/28] BLE Spam fix default 0 values and checks --nobuild --- applications/external/ble_spam/protocols/continuity.c | 2 +- applications/external/ble_spam/protocols/easysetup.c | 2 +- applications/external/ble_spam/protocols/easysetup.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index 4b29683ab..5027414e3 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -91,7 +91,7 @@ static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const Prot const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL; ContinuityType type; - if(cfg) { + if(cfg && cfg->type != 0x00) { type = cfg->type; } else { const ContinuityType types[] = { diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index 98a9541de..b95cab031 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -81,7 +81,7 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc const EasysetupCfg* cfg = _cfg ? &_cfg->easysetup : NULL; EasysetupType type; - if(cfg) { + if(cfg && cfg->type != 0x00) { type = cfg->type; } else { type = rand() % EasysetupTypeCOUNT; diff --git a/applications/external/ble_spam/protocols/easysetup.h b/applications/external/ble_spam/protocols/easysetup.h index 4c9458538..010dc7ec2 100644 --- a/applications/external/ble_spam/protocols/easysetup.h +++ b/applications/external/ble_spam/protocols/easysetup.h @@ -5,7 +5,7 @@ // Research by @Spooks4576 typedef enum { - EasysetupTypeBuds, + EasysetupTypeBuds = 0x01, // Skip 0 as it means unset EasysetupTypeWatch, EasysetupTypeCOUNT, } EasysetupType; From 9c96c75dcbc881e1689992e529ef49f272a2c61e Mon Sep 17 00:00:00 2001 From: Leeroy Date: Tue, 24 Oct 2023 11:07:31 +1100 Subject: [PATCH 07/28] Remote Mouse Acceleration. Navigation Impoved on Screens! --- applications/system/hid_app/views/hid_mouse.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/applications/system/hid_app/views/hid_mouse.c b/applications/system/hid_app/views/hid_mouse.c index 956ad6b24..1f662d4aa 100644 --- a/applications/system/hid_app/views/hid_mouse.c +++ b/applications/system/hid_app/views/hid_mouse.c @@ -22,8 +22,10 @@ typedef struct { bool left_mouse_held; bool right_mouse_pressed; bool connected; + uint32_t button_press_repeat_count; HidTransport transport; } HidMouseModel; +static uint32_t button_press_repeat_count; static void hid_mouse_draw_callback(Canvas* canvas, void* context) { furi_assert(context); @@ -119,6 +121,12 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { hid_mouse->view, HidMouseModel * model, { + button_press_repeat_count = + (event->type == InputTypePress) ? 2 : + (event->type == InputTypeRelease) ? 0 : + (button_press_repeat_count > 10) ? 10 : + ++button_press_repeat_count; + if(event->key == InputKeyBack) { if(event->type == InputTypeShort) { hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT); @@ -150,7 +158,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->right_pressed = true; hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); + for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->right_pressed = false; } @@ -159,7 +168,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->left_pressed = true; hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); + for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->left_pressed = false; } @@ -168,7 +178,9 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->down_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); + for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); + } else if(event->type == InputTypeRelease) { model->down_pressed = false; } @@ -177,7 +189,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->up_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); + for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); } else if(event->type == InputTypeRelease) { model->up_pressed = false; } From b8db2a9f7321a019b9af7c6b6332b4ce2fe90c9f Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 01:10:47 +0100 Subject: [PATCH 08/28] Battery info check inputs for battery+about mode --- .../settings/power_settings_app/views/battery_info.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index dd539bd6c..ec94f65ad 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -151,7 +151,10 @@ static bool battery_info_input_callback(InputEvent* event, void* context) { BatteryInfo* battery_info = context; - if(event->type == InputTypeShort) { + bool about_battery; + with_view_model( + battery_info->view, BatteryInfoModel * model, { about_battery = model->alt; }, false); + if(about_battery && event->type == InputTypeShort) { if(event->key == InputKeyLeft) { event->key = InputKeyBack; } else if(event->key == InputKeyRight) { From d3e83a9182f8bea430620a5d588a3e4e952f132b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 01:12:15 +0100 Subject: [PATCH 09/28] Battery on off back out to off menu + change text --- .../scenes/power_settings_scene_power_off.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c index 8cacbffff..65f10762f 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c @@ -20,7 +20,7 @@ void power_settings_scene_power_off_on_enter(void* context) { dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop); } dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52); - dialog_ex_set_left_button_text(dialog, "About"); + dialog_ex_set_left_button_text(dialog, "Battery"); dialog_ex_set_right_button_text(dialog, "OFF"); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); dialog_ex_set_context(dialog, app); @@ -34,9 +34,7 @@ bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent ev if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneBatteryInfo); - } + scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneBatteryInfo); } else if(event.event == DialogExResultRight) { power_off(app->power); } From 5d368f2add7edce341b7f6e3818cf89d23ed6f52 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 01:41:09 +0100 Subject: [PATCH 10/28] Fix up mouse acceleration --- applications/system/hid_app/views/hid_mouse.c | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/applications/system/hid_app/views/hid_mouse.c b/applications/system/hid_app/views/hid_mouse.c index 1f662d4aa..5e2dab476 100644 --- a/applications/system/hid_app/views/hid_mouse.c +++ b/applications/system/hid_app/views/hid_mouse.c @@ -22,10 +22,9 @@ typedef struct { bool left_mouse_held; bool right_mouse_pressed; bool connected; - uint32_t button_press_repeat_count; + uint8_t acceleration; HidTransport transport; } HidMouseModel; -static uint32_t button_press_repeat_count; static void hid_mouse_draw_callback(Canvas* canvas, void* context) { furi_assert(context); @@ -121,11 +120,10 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { hid_mouse->view, HidMouseModel * model, { - button_press_repeat_count = - (event->type == InputTypePress) ? 2 : - (event->type == InputTypeRelease) ? 0 : - (button_press_repeat_count > 10) ? 10 : - ++button_press_repeat_count; + model->acceleration = (event->type == InputTypePress) ? 1 : + (event->type == InputTypeRelease) ? 0 : + (model->acceleration >= 20) ? 20 : + model->acceleration + 1; if(event->key == InputKeyBack) { if(event->type == InputTypeShort) { @@ -158,7 +156,7 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->right_pressed = true; hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + for(uint8_t i = model->acceleration; i > 1; i -= 2) hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->right_pressed = false; @@ -168,7 +166,7 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->left_pressed = true; hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0); } else if(event->type == InputTypeRepeat) { - for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + for(uint8_t i = model->acceleration; i > 1; i -= 2) hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); } else if(event->type == InputTypeRelease) { model->left_pressed = false; @@ -178,7 +176,7 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->down_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + for(uint8_t i = model->acceleration; i > 1; i -= 2) hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); } else if(event->type == InputTypeRelease) { @@ -189,7 +187,7 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { model->up_pressed = true; hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT); } else if(event->type == InputTypeRepeat) { - for(int32_t i = model->button_press_repeat_count; i > 1; i = i - 2) + for(uint8_t i = model->acceleration; i > 1; i -= 2) hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); } else if(event->type == InputTypeRelease) { model->up_pressed = false; From 16e3294a565ca9ec7488d7711a854b668ef1fd78 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 02:33:17 +0100 Subject: [PATCH 11/28] Fix workflows --nobuild --- .github/workflow_data/devbuild.py | 6 ++++++ .github/workflow_data/webhook.py | 2 +- .github/workflow_data/webupdater.py | 7 +++++++ .github/workflows/build.yml | 1 + .github/workflows/hotfix.yml | 1 + .github/workflows/release.yml | 1 + 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflow_data/devbuild.py b/.github/workflow_data/devbuild.py index fd409bce2..3a2d8facc 100644 --- a/.github/workflow_data/devbuild.py +++ b/.github/workflow_data/devbuild.py @@ -12,6 +12,12 @@ if __name__ == "__main__": event = json.load(f) client = nextcloud_client.Client(os.environ["NC_HOST"]) + _session = requests.session + def session(*args, **kwargs): + s = _session(*args, **kwargs) + s.headers["User-Agent"] = os.environ["NC_USERAGENT"] + return s + requests.session = session client.login(os.environ["NC_USER"], os.environ["NC_PASS"]) for file in ( diff --git a/.github/workflow_data/webhook.py b/.github/workflow_data/webhook.py index d1f9c08bb..de0617276 100644 --- a/.github/workflow_data/webhook.py +++ b/.github/workflow_data/webhook.py @@ -36,7 +36,7 @@ if __name__ == "__main__": for i, commit in enumerate(event["commits"]): msg = commit['message'].splitlines()[0].replace("`", "") msg = msg[:50] + ("..." if len(msg) > 50 else "") - desc += f"\n[`{commit['id'][:7]}`]({commit['url']}): {msg} - [__{commit['author']['username']}__](https://github.com/{commit['author']['username']})" + desc += f"\n[`{commit['id'][:7]}`]({commit['url']}): {msg} - [__{commit['author'].get('username')}__](https://github.com/{commit['author'].get('username')})" if len(desc) > 2020: desc = desc.rsplit("\n", 1)[0] + f"\n+ {count - i} more commits" break diff --git a/.github/workflow_data/webupdater.py b/.github/workflow_data/webupdater.py index ccf131567..e9a861aaa 100644 --- a/.github/workflow_data/webupdater.py +++ b/.github/workflow_data/webupdater.py @@ -1,9 +1,16 @@ import nextcloud_client +import requests import json import os if __name__ == "__main__": client = nextcloud_client.Client(os.environ["NC_HOST"]) + _session = requests.session + def session(*args, **kwargs): + s = _session(*args, **kwargs) + s.headers["User-Agent"] = os.environ["NC_USERAGENT"] + return s + requests.session = session client.login(os.environ["NC_USER"], os.environ["NC_PASS"]) file = os.environ["ARTIFACT_TGZ"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f118e279d..f9ac76eeb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -57,6 +57,7 @@ jobs: if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }} diff --git a/.github/workflows/hotfix.yml b/.github/workflows/hotfix.yml index 38076ae18..7b7f15132 100644 --- a/.github/workflows/hotfix.yml +++ b/.github/workflows/hotfix.yml @@ -59,6 +59,7 @@ jobs: - name: "Upload to webupdater" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1352871e0..00a5c8dab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,6 +55,7 @@ jobs: - name: "Upload to webupdater" env: NC_HOST: "https://cloud.cynthialabs.net/" + NC_USERAGENT: "${{ secrets.NC_USERAGENT }}" NC_USER: "${{ secrets.NC_USER }}" NC_PASS: "${{ secrets.NC_PASS }}" run: | From 15ea63b1ee6cd895c48cd36aa39f1a11bffc9573 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:50:04 +0100 Subject: [PATCH 12/28] Fix malloc(0) in BLE Spam --- applications/external/ble_spam/protocols/easysetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index b95cab031..4dad1e67b 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -84,7 +84,11 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc if(cfg && cfg->type != 0x00) { type = cfg->type; } else { - type = rand() % EasysetupTypeCOUNT; + const EasysetupType types[] = { + EasysetupTypeBuds, + EasysetupTypeWatch, + }; + type = types[rand() % COUNT_OF(types)]; } uint8_t size = packet_sizes[type]; From 7ace42debc1a88436622f223cb73c6bfb5197f74 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:10:58 +0100 Subject: [PATCH 13/28] Android spam set up device by @Mr-Proxy-source --- applications/external/ble_spam/protocols/fastpair.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index 1e7c2920c..1cf3a3551 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -8,6 +8,9 @@ const struct { uint32_t value; const char* name; } models[] = { + // Genuine actions + {0x00000C, "Set Up Device"}, + // Genuine devices {0xCD8256, "Bose NC 700"}, {0xF52494, "JBL Buds Pro"}, From 1f9d8f4dd459f9429e2a3f041a34ddfc354a9b23 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:06:15 +0100 Subject: [PATCH 14/28] How are these models legit??? xD by @xAstroBoy --- applications/external/ble_spam/protocols/fastpair.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index 1cf3a3551..a8e11996b 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -12,11 +12,15 @@ const struct { {0x00000C, "Set Up Device"}, // Genuine devices + {0x00000a, "Anti-Spoofing Test (lmao)"}, + {0x0001F0, "Bisto CSR8670 Dev Board"}, + {0x000047, "Arduino 101"}, {0xCD8256, "Bose NC 700"}, {0xF52494, "JBL Buds Pro"}, {0x718FA4, "JBL Live 300TWS"}, {0x821F66, "JBL Flip 6"}, {0x92BBBD, "Pixel Buds"}, + {0x000006, "Google Pixel buds"}, {0xD446A7, "Sony XM5"}, {0x2D7A23, "Sony WF-1000XM4"}, {0x0E30C3, "Razer Hammerhead TWS"}, From fd58f40fbd5c5a2ce744b5f109e0660e000e20f1 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:27:42 +0100 Subject: [PATCH 15/28] Formatting --nobuild --- .../external/ble_spam/protocols/continuity.c | 16 ++++++++-------- .../external/ble_spam/protocols/easysetup.c | 16 ++++++++-------- .../external/ble_spam/protocols/fastpair.c | 18 +++++++++--------- .../external/ble_spam/protocols/swiftpair.c | 16 ++++++++-------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index 5027414e3..88c6b5762 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -71,7 +71,7 @@ static const char* type_names[ContinuityTypeCOUNT] = { [ContinuityTypeNearbyInfo] = "Nearby Info", [ContinuityTypeCustomCrash] = "Continuity Custom", }; -static const char* continuity_get_name(const ProtocolCfg* _cfg) { +static const char* get_name(const ProtocolCfg* _cfg) { const ContinuityCfg* cfg = &_cfg->continuity; return type_names[cfg->type]; } @@ -87,7 +87,7 @@ static uint8_t packet_sizes[ContinuityTypeCOUNT] = { [ContinuityTypeNearbyInfo] = HEADER_LEN + 5, [ContinuityTypeCustomCrash] = HEADER_LEN + 11, }; -static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { +static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL; ContinuityType type; @@ -376,7 +376,7 @@ static void na_action_changed(VariableItem* item) { variable_item_set_current_value_text(item, "Random"); } } -static void continuity_extra_config(Ctx* ctx) { +static void extra_config(Ctx* ctx) { ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; VariableItemList* list = ctx->variable_item_list; VariableItem* item; @@ -502,17 +502,17 @@ static uint8_t config_counts[ContinuityTypeCOUNT] = { [ContinuityTypeNearbyInfo] = 0, [ContinuityTypeCustomCrash] = ConfigCcCOUNT - ConfigExtraStart - 1, }; -static uint8_t continuity_config_count(const ProtocolCfg* _cfg) { +static uint8_t config_count(const ProtocolCfg* _cfg) { const ContinuityCfg* cfg = &_cfg->continuity; return config_counts[cfg->type]; } const Protocol protocol_continuity = { .icon = &I_apple, - .get_name = continuity_get_name, - .make_packet = continuity_make_packet, - .extra_config = continuity_extra_config, - .config_count = continuity_config_count, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, }; static void pp_model_callback(void* _ctx, uint32_t index) { diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index 4dad1e67b..e4df74786 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -68,7 +68,7 @@ static const char* type_names[EasysetupTypeCOUNT] = { [EasysetupTypeBuds] = "EasySetup Buds", [EasysetupTypeWatch] = "EasySetup Watch", }; -static const char* easysetup_get_name(const ProtocolCfg* _cfg) { +static const char* get_name(const ProtocolCfg* _cfg) { const EasysetupCfg* cfg = &_cfg->easysetup; return type_names[cfg->type]; } @@ -77,7 +77,7 @@ static uint8_t packet_sizes[EasysetupTypeCOUNT] = { [EasysetupTypeBuds] = 31, [EasysetupTypeWatch] = 15, }; -void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cfg) { +void make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cfg) { const EasysetupCfg* cfg = _cfg ? &_cfg->easysetup : NULL; EasysetupType type; @@ -241,7 +241,7 @@ static void watch_model_changed(VariableItem* item) { variable_item_set_current_value_text(item, "Random"); } } -static void easysetup_extra_config(Ctx* ctx) { +static void extra_config(Ctx* ctx) { EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; VariableItemList* list = ctx->variable_item_list; VariableItem* item; @@ -313,17 +313,17 @@ static uint8_t config_counts[EasysetupTypeCOUNT] = { [EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1, [EasysetupTypeWatch] = ConfigWatchCOUNT - ConfigExtraStart - 1, }; -static uint8_t easysetup_config_count(const ProtocolCfg* _cfg) { +static uint8_t config_count(const ProtocolCfg* _cfg) { const EasysetupCfg* cfg = &_cfg->easysetup; return config_counts[cfg->type]; } const Protocol protocol_easysetup = { .icon = &I_android, - .get_name = easysetup_get_name, - .make_packet = easysetup_make_packet, - .extra_config = easysetup_extra_config, - .config_count = easysetup_config_count, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, }; static void buds_model_callback(void* _ctx, uint32_t index) { diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index a8e11996b..42d521105 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -12,7 +12,7 @@ const struct { {0x00000C, "Set Up Device"}, // Genuine devices - {0x00000a, "Anti-Spoofing Test (lmao)"}, + {0x00000A, "Anti-Spoofing Test (lmao)"}, {0x0001F0, "Bisto CSR8670 Dev Board"}, {0x000047, "Arduino 101"}, {0xCD8256, "Bose NC 700"}, @@ -46,12 +46,12 @@ const struct { }; const uint8_t models_count = COUNT_OF(models); -static const char* fastpair_get_name(const ProtocolCfg* _cfg) { +static const char* get_name(const ProtocolCfg* _cfg) { UNUSED(_cfg); return "FastPair"; } -static void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { +static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL; uint32_t model; @@ -118,7 +118,7 @@ static void model_changed(VariableItem* item) { variable_item_set_current_value_text(item, "Random"); } } -static void fastpair_extra_config(Ctx* ctx) { +static void extra_config(Ctx* ctx) { FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; VariableItemList* list = ctx->variable_item_list; VariableItem* item; @@ -152,17 +152,17 @@ static void fastpair_extra_config(Ctx* ctx) { variable_item_list_set_enter_callback(list, config_callback, ctx); } -static uint8_t fastpair_config_count(const ProtocolCfg* _cfg) { +static uint8_t config_count(const ProtocolCfg* _cfg) { UNUSED(_cfg); return ConfigCOUNT - ConfigExtraStart - 1; } const Protocol protocol_fastpair = { .icon = &I_android, - .get_name = fastpair_get_name, - .make_packet = fastpair_make_packet, - .extra_config = fastpair_extra_config, - .config_count = fastpair_config_count, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, }; static void model_callback(void* _ctx, uint32_t index) { diff --git a/applications/external/ble_spam/protocols/swiftpair.c b/applications/external/ble_spam/protocols/swiftpair.c index b204f8eef..3a4788312 100644 --- a/applications/external/ble_spam/protocols/swiftpair.c +++ b/applications/external/ble_spam/protocols/swiftpair.c @@ -4,12 +4,12 @@ // Hacked together by @Willy-JL and @Spooks4576 // Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair -static const char* swiftpair_get_name(const ProtocolCfg* _cfg) { +static const char* get_name(const ProtocolCfg* _cfg) { UNUSED(_cfg); return "SwiftPair"; } -static void swiftpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { +static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL; const char* name; @@ -66,7 +66,7 @@ static void config_callback(void* _ctx, uint32_t index) { break; } } -static void swiftpair_extra_config(Ctx* ctx) { +static void extra_config(Ctx* ctx) { SwiftpairCfg* cfg = &ctx->attack->payload.cfg.swiftpair; VariableItemList* list = ctx->variable_item_list; VariableItem* item; @@ -79,17 +79,17 @@ static void swiftpair_extra_config(Ctx* ctx) { variable_item_list_set_enter_callback(list, config_callback, ctx); } -static uint8_t swiftpair_config_count(const ProtocolCfg* _cfg) { +static uint8_t config_count(const ProtocolCfg* _cfg) { UNUSED(_cfg); return ConfigCOUNT - ConfigExtraStart - 1; } const Protocol protocol_swiftpair = { .icon = &I_windows, - .get_name = swiftpair_get_name, - .make_packet = swiftpair_make_packet, - .extra_config = swiftpair_extra_config, - .config_count = swiftpair_config_count, + .get_name = get_name, + .make_packet = make_packet, + .extra_config = extra_config, + .config_count = config_count, }; static void name_callback(void* _ctx) { From f4cb2a087bcecfd0a13ef520ea9927ec668c791b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 21:58:43 +0100 Subject: [PATCH 16/28] BLE Spam redraw while advertising --- applications/external/ble_spam/ble_spam.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index b3edf165f..89e005aaa 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -488,9 +488,17 @@ static void lock_timer_callback(void* _ctx) { state->lock_count = 0; } +static void tick_event_callback(void* _ctx) { + State* state = _ctx; + bool advertising; + with_view_model( + state->main_view, State * *model, { advertising = (*model)->advertising; }, advertising); + scene_manager_handle_tick_event(state->ctx.scene_manager); +} + static bool back_event_callback(void* _ctx) { - Ctx* ctx = _ctx; - return scene_manager_handle_back_event(ctx->scene_manager); + State* state = _ctx; + return scene_manager_handle_back_event(state->ctx.scene_manager); } int32_t ble_spam(void* p) { @@ -507,7 +515,8 @@ int32_t ble_spam(void* p) { Gui* gui = furi_record_open(RECORD_GUI); state->ctx.view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(state->ctx.view_dispatcher); - view_dispatcher_set_event_callback_context(state->ctx.view_dispatcher, &state->ctx); + view_dispatcher_set_event_callback_context(state->ctx.view_dispatcher, state); + view_dispatcher_set_tick_event_callback(state->ctx.view_dispatcher, tick_event_callback, 100); view_dispatcher_set_navigation_event_callback(state->ctx.view_dispatcher, back_event_callback); state->ctx.scene_manager = scene_manager_alloc(&scene_handlers, &state->ctx); From 60ec667178b09279f7c8035a9072eb15521e1094 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:20:06 +0100 Subject: [PATCH 17/28] BLE Spam save new custom data only on ok not back --- .../external/ble_spam/protocols/continuity.c | 18 +++++++++--------- .../external/ble_spam/protocols/easysetup.c | 14 +++++++------- .../external/ble_spam/protocols/fastpair.c | 8 ++++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index 88c6b5762..efbf87560 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -573,6 +573,8 @@ void scene_continuity_pp_model_on_exit(void* _ctx) { static void pp_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -597,9 +599,7 @@ bool scene_continuity_pp_model_custom_on_event(void* _ctx, SceneManagerEvent eve return false; } void scene_continuity_pp_model_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; - cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00); + UNUSED(_ctx); } static void pp_prefix_callback(void* _ctx, uint32_t index) { @@ -660,6 +660,8 @@ void scene_continuity_pp_prefix_on_exit(void* _ctx) { static void pp_prefix_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -683,9 +685,7 @@ bool scene_continuity_pp_prefix_custom_on_event(void* _ctx, SceneManagerEvent ev return false; } void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; - cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00); + UNUSED(_ctx); } static void na_action_callback(void* _ctx, uint32_t index) { @@ -746,6 +746,8 @@ void scene_continuity_na_action_on_exit(void* _ctx) { static void na_action_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -769,9 +771,7 @@ bool scene_continuity_na_action_custom_on_event(void* _ctx, SceneManagerEvent ev return false; } void scene_continuity_na_action_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; - cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00); + UNUSED(_ctx); } static void na_flags_callback(void* _ctx) { diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index e4df74786..e1b6e0584 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -384,6 +384,9 @@ void scene_easysetup_buds_model_on_exit(void* _ctx) { static void buds_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + cfg->data.buds.model = + (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -409,10 +412,7 @@ bool scene_easysetup_buds_model_custom_on_event(void* _ctx, SceneManagerEvent ev return false; } void scene_easysetup_buds_model_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; - cfg->data.buds.model = - (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); + UNUSED(_ctx); } static void watch_model_callback(void* _ctx, uint32_t index) { @@ -473,6 +473,8 @@ void scene_easysetup_watch_model_on_exit(void* _ctx) { static void watch_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + cfg->data.watch.model = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -496,7 +498,5 @@ bool scene_easysetup_watch_model_custom_on_event(void* _ctx, SceneManagerEvent e return false; } void scene_easysetup_watch_model_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; - cfg->data.watch.model = (ctx->byte_store[0] << 0x00); + UNUSED(_ctx); } diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index 42d521105..db3d37b35 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -223,6 +223,9 @@ void scene_fastpair_model_on_exit(void* _ctx) { static void model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; + FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + cfg->model = + (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } @@ -248,8 +251,5 @@ bool scene_fastpair_model_custom_on_event(void* _ctx, SceneManagerEvent event) { return false; } void scene_fastpair_model_custom_on_exit(void* _ctx) { - Ctx* ctx = _ctx; - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; - cfg->model = - (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); + UNUSED(_ctx); } From 0f3fbd1cd729f5a6c498b4e04febd78d94de87a3 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 00:02:36 +0100 Subject: [PATCH 18/28] BLE Spam refactor random/set/custom mode handling --- applications/external/ble_spam/ble_spam.c | 55 ++----- .../external/ble_spam/protocols/_base.h | 4 +- .../external/ble_spam/protocols/_protocols.h | 18 ++- .../external/ble_spam/protocols/continuity.c | 151 +++++++++++------- .../external/ble_spam/protocols/easysetup.c | 122 +++++++++----- .../external/ble_spam/protocols/fastpair.c | 60 ++++--- .../external/ble_spam/protocols/swiftpair.c | 52 +++--- 7 files changed, 277 insertions(+), 185 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 89e005aaa..54171cec6 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -30,13 +30,10 @@ static Attack attacks[] = { .payload = { .random_mac = false, - .cfg = + .cfg.specific.continuity = { - .continuity = - { - .type = ContinuityTypeCustomCrash, - .data = {}, - }, + .type = ContinuityTypeCustomCrash, + .data = {}, }, }, }, @@ -47,13 +44,10 @@ static Attack attacks[] = { .payload = { .random_mac = false, - .cfg = + .cfg.specific.continuity = { - .continuity = - { - .type = ContinuityTypeNearbyAction, - .data = {}, - }, + .type = ContinuityTypeNearbyAction, + .data = {}, }, }, }, @@ -64,13 +58,10 @@ static Attack attacks[] = { .payload = { .random_mac = false, - .cfg = + .cfg.specific.continuity = { - .continuity = - { - .type = ContinuityTypeProximityPair, - .data = {}, - }, + .type = ContinuityTypeProximityPair, + .data = {}, }, }, }, @@ -81,10 +72,7 @@ static Attack attacks[] = { .payload = { .random_mac = true, - .cfg = - { - .fastpair = {}, - }, + .cfg.specific.fastpair = {}, }, }, { @@ -94,13 +82,10 @@ static Attack attacks[] = { .payload = { .random_mac = true, - .cfg = + .cfg.specific.easysetup = { - .easysetup = - { - .type = EasysetupTypeBuds, - .data = {}, - }, + .type = EasysetupTypeBuds, + .data = {}, }, }, }, @@ -111,13 +96,10 @@ static Attack attacks[] = { .payload = { .random_mac = true, - .cfg = + .cfg.specific.easysetup = { - .easysetup = - { - .type = EasysetupTypeWatch, - .data = {}, - }, + .type = EasysetupTypeWatch, + .data = {}, }, }, }, @@ -128,10 +110,7 @@ static Attack attacks[] = { .payload = { .random_mac = true, - .cfg = - { - .swiftpair = {}, - }, + .cfg.specific.swiftpair = {}, }, }, }; diff --git a/applications/external/ble_spam/protocols/_base.h b/applications/external/ble_spam/protocols/_base.h index 6f32b9990..1456b1c4a 100644 --- a/applications/external/ble_spam/protocols/_base.h +++ b/applications/external/ble_spam/protocols/_base.h @@ -10,12 +10,12 @@ #include #include "../ble_spam.h" -typedef union ProtocolCfg ProtocolCfg; +typedef struct ProtocolCfg ProtocolCfg; typedef struct { const Icon* icon; const char* (*get_name)(const ProtocolCfg* _cfg); - void (*make_packet)(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg); + void (*make_packet)(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg); void (*extra_config)(Ctx* ctx); uint8_t (*config_count)(const ProtocolCfg* _cfg); } Protocol; diff --git a/applications/external/ble_spam/protocols/_protocols.h b/applications/external/ble_spam/protocols/_protocols.h index 4e646eefb..c1395dab8 100644 --- a/applications/external/ble_spam/protocols/_protocols.h +++ b/applications/external/ble_spam/protocols/_protocols.h @@ -5,11 +5,19 @@ #include "easysetup.h" #include "swiftpair.h" -union ProtocolCfg { - ContinuityCfg continuity; - FastpairCfg fastpair; - EasysetupCfg easysetup; - SwiftpairCfg swiftpair; +typedef enum { + ProtocolModeRandom, + ProtocolModeValue, +} ProtocolMode; + +struct ProtocolCfg { + ProtocolMode mode; + union { + ContinuityCfg continuity; + FastpairCfg fastpair; + EasysetupCfg easysetup; + SwiftpairCfg swiftpair; + } specific; }; extern const Protocol* protocols[]; diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index efbf87560..6a7e130e5 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -72,7 +72,7 @@ static const char* type_names[ContinuityTypeCOUNT] = { [ContinuityTypeCustomCrash] = "Continuity Custom", }; static const char* get_name(const ProtocolCfg* _cfg) { - const ContinuityCfg* cfg = &_cfg->continuity; + const ContinuityCfg* cfg = &_cfg->specific.continuity; return type_names[cfg->type]; } @@ -87,8 +87,8 @@ static uint8_t packet_sizes[ContinuityTypeCOUNT] = { [ContinuityTypeNearbyInfo] = HEADER_LEN + 5, [ContinuityTypeCustomCrash] = HEADER_LEN + 11, }; -static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { - const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { + ContinuityCfg* cfg = _cfg ? &_cfg->specific.continuity : NULL; ContinuityType type; if(cfg && cfg->type != 0x00) { @@ -139,14 +139,18 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _c case ContinuityTypeProximityPair: { uint16_t model; - if(cfg && cfg->data.proximity_pair.model != 0x0000) { - model = cfg->data.proximity_pair.model; - } else { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: model = pp_models[rand() % pp_models_count].value; + break; + case ProtocolModeValue: + model = cfg->data.proximity_pair.model; + break; } uint8_t prefix; - if(cfg && cfg->data.proximity_pair.prefix == 0x00) { + if(cfg && cfg->data.proximity_pair.prefix != 0x00) { prefix = cfg->data.proximity_pair.prefix; } else { if(model == 0x0055 || model == 0x0030) @@ -209,10 +213,14 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _c case ContinuityTypeNearbyAction: { uint8_t action; - if(cfg && cfg->data.nearby_action.action != 0x00) { - action = cfg->data.nearby_action.action; - } else { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: action = na_actions[rand() % na_actions_count].value; + break; + case ProtocolModeValue: + action = cfg->data.nearby_action.action; + break; } uint8_t flags; @@ -293,7 +301,8 @@ enum { }; static void config_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); switch(cfg->type) { case ContinuityTypeProximityPair: { @@ -341,19 +350,22 @@ static void config_callback(void* _ctx, uint32_t index) { } } static void pp_model_changed(VariableItem* item) { - ContinuityCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + ContinuityCfg* cfg = &_cfg->specific.continuity; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; + _cfg->mode = ProtocolModeValue; cfg->data.proximity_pair.model = pp_models[index].value; variable_item_set_current_value_text(item, pp_models[index].name); } else { - cfg->data.proximity_pair.model = 0x0000; + _cfg->mode = ProtocolModeRandom; variable_item_set_current_value_text(item, "Random"); } } static void pp_prefix_changed(VariableItem* item) { - ContinuityCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + ContinuityCfg* cfg = &_cfg->specific.continuity; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; @@ -365,33 +377,39 @@ static void pp_prefix_changed(VariableItem* item) { } } static void na_action_changed(VariableItem* item) { - ContinuityCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + ContinuityCfg* cfg = &_cfg->specific.continuity; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; + _cfg->mode = ProtocolModeValue; cfg->data.nearby_action.action = na_actions[index].value; variable_item_set_current_value_text(item, na_actions[index].name); } else { - cfg->data.nearby_action.action = 0x00; + _cfg->mode = ProtocolModeRandom; variable_item_set_current_value_text(item, "Random"); } } static void extra_config(Ctx* ctx) { - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; VariableItemList* list = ctx->variable_item_list; VariableItem* item; size_t value_index; switch(cfg->type) { case ContinuityTypeProximityPair: { - item = - variable_item_list_add(list, "Model Code", pp_models_count + 1, pp_model_changed, cfg); + item = variable_item_list_add( + list, "Model Code", pp_models_count + 1, pp_model_changed, _cfg); const char* model_name = NULL; char model_name_buf[5]; - if(cfg->data.proximity_pair.model == 0x0000) { + switch(_cfg->mode) { + case ProtocolModeRandom: + default: model_name = "Random"; value_index = 0; - } else { + break; + case ProtocolModeValue: for(uint8_t i = 0; i < pp_models_count; i++) { if(cfg->data.proximity_pair.model == pp_models[i].value) { model_name = pp_models[i].name; @@ -405,12 +423,13 @@ static void extra_config(Ctx* ctx) { model_name = model_name_buf; value_index = pp_models_count + 1; } + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); item = - variable_item_list_add(list, "Prefix", pp_prefixes_count + 1, pp_prefix_changed, cfg); + variable_item_list_add(list, "Prefix", pp_prefixes_count + 1, pp_prefix_changed, _cfg); const char* prefix_name = NULL; char prefix_name_buf[3]; if(cfg->data.proximity_pair.prefix == 0x00) { @@ -440,13 +459,16 @@ static void extra_config(Ctx* ctx) { } case ContinuityTypeNearbyAction: { item = variable_item_list_add( - list, "Action Type", na_actions_count + 1, na_action_changed, cfg); + list, "Action Type", na_actions_count + 1, na_action_changed, _cfg); const char* action_name = NULL; char action_name_buf[3]; - if(cfg->data.nearby_action.action == 0x00) { + switch(_cfg->mode) { + case ProtocolModeRandom: + default: action_name = "Random"; value_index = 0; - } else { + break; + case ProtocolModeValue: for(uint8_t i = 0; i < na_actions_count; i++) { if(cfg->data.nearby_action.action == na_actions[i].value) { action_name = na_actions[i].name; @@ -463,6 +485,7 @@ static void extra_config(Ctx* ctx) { action_name = action_name_buf; value_index = na_actions_count + 1; } + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, action_name); @@ -503,7 +526,7 @@ static uint8_t config_counts[ContinuityTypeCOUNT] = { [ContinuityTypeCustomCrash] = ConfigCcCOUNT - ConfigExtraStart - 1, }; static uint8_t config_count(const ProtocolCfg* _cfg) { - const ContinuityCfg* cfg = &_cfg->continuity; + const ContinuityCfg* cfg = &_cfg->specific.continuity; return config_counts[cfg->type]; } @@ -517,16 +540,18 @@ const Protocol protocol_continuity = { static void pp_model_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; switch(index) { case 0: - cfg->data.proximity_pair.model = 0x0000; + _cfg->mode = ProtocolModeRandom; scene_manager_previous_scene(ctx->scene_manager); break; case pp_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModelCustom); break; default: + _cfg->mode = ProtocolModeValue; cfg->data.proximity_pair.model = pp_models[index - 1].value; scene_manager_previous_scene(ctx->scene_manager); break; @@ -534,27 +559,28 @@ static void pp_model_callback(void* _ctx, uint32_t index) { } void scene_continuity_pp_model_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; Submenu* submenu = ctx->submenu; uint32_t selected = 0; - bool found = false; submenu_reset(submenu); submenu_add_item(submenu, "Random", 0, pp_model_callback, ctx); - if(cfg->data.proximity_pair.model == 0x0000) { - found = true; + if(_cfg->mode == ProtocolModeRandom) { selected = 0; } + + bool found = false; for(uint8_t i = 0; i < pp_models_count; i++) { submenu_add_item(submenu, pp_models[i].name, i + 1, pp_model_callback, ctx); - if(!found && cfg->data.proximity_pair.model == pp_models[i].value) { + if(!found && _cfg->mode == ProtocolModeValue && + cfg->data.proximity_pair.model == pp_models[i].value) { found = true; selected = i + 1; } } submenu_add_item(submenu, "Custom", pp_models_count + 1, pp_model_callback, ctx); - if(!found) { - found = true; + if(!found && _cfg->mode == ProtocolModeValue) { selected = pp_models_count + 1; } @@ -573,14 +599,17 @@ void scene_continuity_pp_model_on_exit(void* _ctx) { static void pp_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; + _cfg->mode = ProtocolModeValue; cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } void scene_continuity_pp_model_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Model Code"); @@ -604,7 +633,8 @@ void scene_continuity_pp_model_custom_on_exit(void* _ctx) { static void pp_prefix_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; switch(index) { case 0: cfg->data.proximity_pair.prefix = 0x00; @@ -621,7 +651,8 @@ static void pp_prefix_callback(void* _ctx, uint32_t index) { } void scene_continuity_pp_prefix_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; Submenu* submenu = ctx->submenu; uint32_t selected = 0; bool found = false; @@ -632,6 +663,7 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) { found = true; selected = 0; } + for(uint8_t i = 0; i < pp_prefixes_count; i++) { submenu_add_item(submenu, pp_prefixes[i].name, i + 1, pp_prefix_callback, ctx); if(!found && cfg->data.proximity_pair.prefix == pp_prefixes[i].value) { @@ -641,7 +673,6 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) { } submenu_add_item(submenu, "Custom", pp_prefixes_count + 1, pp_prefix_callback, ctx); if(!found) { - found = true; selected = pp_prefixes_count + 1; } @@ -660,14 +691,16 @@ void scene_continuity_pp_prefix_on_exit(void* _ctx) { static void pp_prefix_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } void scene_continuity_pp_prefix_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Prefix"); @@ -690,16 +723,18 @@ void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) { static void na_action_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; switch(index) { case 0: - cfg->data.nearby_action.action = 0x00; + _cfg->mode = ProtocolModeRandom; scene_manager_previous_scene(ctx->scene_manager); break; case na_actions_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaActionCustom); break; default: + _cfg->mode = ProtocolModeValue; cfg->data.nearby_action.action = na_actions[index - 1].value; scene_manager_previous_scene(ctx->scene_manager); break; @@ -707,27 +742,28 @@ static void na_action_callback(void* _ctx, uint32_t index) { } void scene_continuity_na_action_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; Submenu* submenu = ctx->submenu; uint32_t selected = 0; - bool found = false; submenu_reset(submenu); submenu_add_item(submenu, "Random", 0, na_action_callback, ctx); - if(cfg->data.nearby_action.action == 0x00) { - found = true; + if(_cfg->mode == ProtocolModeRandom) { selected = 0; } + + bool found = false; for(uint8_t i = 0; i < na_actions_count; i++) { submenu_add_item(submenu, na_actions[i].name, i + 1, na_action_callback, ctx); - if(!found && cfg->data.nearby_action.action == na_actions[i].value) { + if(!found && _cfg->mode == ProtocolModeValue && + cfg->data.nearby_action.action == na_actions[i].value) { found = true; selected = i + 1; } } submenu_add_item(submenu, "Custom", na_actions_count + 1, na_action_callback, ctx); - if(!found) { - found = true; + if(!found && _cfg->mode == ProtocolModeValue) { selected = na_actions_count + 1; } @@ -746,14 +782,17 @@ void scene_continuity_na_action_on_exit(void* _ctx) { static void na_action_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; + _cfg->mode = ProtocolModeValue; cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } void scene_continuity_na_action_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Action Type"); @@ -780,7 +819,8 @@ static void na_flags_callback(void* _ctx) { } void scene_continuity_na_flags_on_enter(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Press back for automatic"); @@ -801,6 +841,7 @@ bool scene_continuity_na_flags_on_event(void* _ctx, SceneManagerEvent event) { } void scene_continuity_na_flags_on_exit(void* _ctx) { Ctx* ctx = _ctx; - ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + ContinuityCfg* cfg = &_cfg->specific.continuity; cfg->data.nearby_action.flags = (ctx->byte_store[0] << 0x00); } diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index e1b6e0584..d13083b7d 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -69,7 +69,7 @@ static const char* type_names[EasysetupTypeCOUNT] = { [EasysetupTypeWatch] = "EasySetup Watch", }; static const char* get_name(const ProtocolCfg* _cfg) { - const EasysetupCfg* cfg = &_cfg->easysetup; + const EasysetupCfg* cfg = &_cfg->specific.easysetup; return type_names[cfg->type]; } @@ -77,8 +77,8 @@ static uint8_t packet_sizes[EasysetupTypeCOUNT] = { [EasysetupTypeBuds] = 31, [EasysetupTypeWatch] = 15, }; -void make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cfg) { - const EasysetupCfg* cfg = _cfg ? &_cfg->easysetup : NULL; +void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) { + EasysetupCfg* cfg = _cfg ? &_cfg->specific.easysetup : NULL; EasysetupType type; if(cfg && cfg->type != 0x00) { @@ -98,10 +98,14 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cf switch(type) { case EasysetupTypeBuds: { uint32_t model; - if(cfg && cfg->data.buds.model != 0x000000) { - model = cfg->data.buds.model; - } else { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: model = buds_models[rand() % buds_models_count].value; + break; + case ProtocolModeValue: + model = cfg->data.buds.model; + break; } packet[i++] = 27; // Size @@ -141,10 +145,14 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, const ProtocolCfg* _cf } case EasysetupTypeWatch: { uint8_t model; - if(cfg && cfg->data.watch.model != 0x00) { - model = cfg->data.watch.model; - } else { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: model = watch_models[rand() % watch_models_count].value; + break; + case ProtocolModeValue: + model = cfg->data.watch.model; + break; } packet[i++] = 14; // Size @@ -185,7 +193,8 @@ enum { }; static void config_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index); switch(cfg->type) { case EasysetupTypeBuds: { @@ -218,31 +227,36 @@ static void config_callback(void* _ctx, uint32_t index) { } } static void buds_model_changed(VariableItem* item) { - EasysetupCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + EasysetupCfg* cfg = &_cfg->specific.easysetup; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; + _cfg->mode = ProtocolModeValue; cfg->data.buds.model = buds_models[index].value; variable_item_set_current_value_text(item, buds_models[index].name); } else { - cfg->data.buds.model = 0x000000; + _cfg->mode = ProtocolModeRandom; variable_item_set_current_value_text(item, "Random"); } } static void watch_model_changed(VariableItem* item) { - EasysetupCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + EasysetupCfg* cfg = &_cfg->specific.easysetup; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; + _cfg->mode = ProtocolModeValue; cfg->data.watch.model = watch_models[index].value; variable_item_set_current_value_text(item, watch_models[index].name); } else { - cfg->data.watch.model = 0x00; + _cfg->mode = ProtocolModeRandom; variable_item_set_current_value_text(item, "Random"); } } static void extra_config(Ctx* ctx) { - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; VariableItemList* list = ctx->variable_item_list; VariableItem* item; size_t value_index; @@ -250,13 +264,16 @@ static void extra_config(Ctx* ctx) { switch(cfg->type) { case EasysetupTypeBuds: { item = variable_item_list_add( - list, "Model Code", buds_models_count + 1, buds_model_changed, cfg); + list, "Model Code", buds_models_count + 1, buds_model_changed, _cfg); const char* model_name = NULL; char model_name_buf[9]; - if(cfg->data.buds.model == 0x000000) { + switch(_cfg->mode) { + case ProtocolModeRandom: + default: model_name = "Random"; value_index = 0; - } else { + break; + case ProtocolModeValue: for(uint8_t i = 0; i < buds_models_count; i++) { if(cfg->data.buds.model == buds_models[i].value) { model_name = buds_models[i].name; @@ -269,6 +286,7 @@ static void extra_config(Ctx* ctx) { model_name = model_name_buf; value_index = buds_models_count + 1; } + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -278,13 +296,16 @@ static void extra_config(Ctx* ctx) { } case EasysetupTypeWatch: { item = variable_item_list_add( - list, "Model Code", watch_models_count + 1, watch_model_changed, cfg); + list, "Model Code", watch_models_count + 1, watch_model_changed, _cfg); const char* model_name = NULL; char model_name_buf[3]; - if(cfg->data.watch.model == 0x00) { + switch(_cfg->mode) { + case ProtocolModeRandom: + default: model_name = "Random"; value_index = 0; - } else { + break; + case ProtocolModeValue: for(uint8_t i = 0; i < watch_models_count; i++) { if(cfg->data.watch.model == watch_models[i].value) { model_name = watch_models[i].name; @@ -297,6 +318,7 @@ static void extra_config(Ctx* ctx) { model_name = model_name_buf; value_index = watch_models_count + 1; } + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -314,7 +336,7 @@ static uint8_t config_counts[EasysetupTypeCOUNT] = { [EasysetupTypeWatch] = ConfigWatchCOUNT - ConfigExtraStart - 1, }; static uint8_t config_count(const ProtocolCfg* _cfg) { - const EasysetupCfg* cfg = &_cfg->easysetup; + const EasysetupCfg* cfg = &_cfg->specific.easysetup; return config_counts[cfg->type]; } @@ -328,16 +350,18 @@ const Protocol protocol_easysetup = { static void buds_model_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; switch(index) { case 0: - cfg->data.buds.model = 0x000000; + _cfg->mode = ProtocolModeRandom; scene_manager_previous_scene(ctx->scene_manager); break; case buds_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom); break; default: + _cfg->mode = ProtocolModeValue; cfg->data.buds.model = buds_models[index - 1].value; scene_manager_previous_scene(ctx->scene_manager); break; @@ -345,27 +369,28 @@ static void buds_model_callback(void* _ctx, uint32_t index) { } void scene_easysetup_buds_model_on_enter(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; Submenu* submenu = ctx->submenu; uint32_t selected = 0; - bool found = false; submenu_reset(submenu); submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx); - if(cfg->data.buds.model == 0x000000) { - found = true; + if(_cfg->mode == ProtocolModeRandom) { selected = 0; } + + bool found = false; for(uint8_t i = 0; i < buds_models_count; i++) { submenu_add_item(submenu, buds_models[i].name, i + 1, buds_model_callback, ctx); - if(!found && cfg->data.buds.model == buds_models[i].value) { + if(!found && _cfg->mode == ProtocolModeValue && + cfg->data.buds.model == buds_models[i].value) { found = true; selected = i + 1; } } submenu_add_item(submenu, "Custom", buds_models_count + 1, buds_model_callback, ctx); - if(!found) { - found = true; + if(!found && _cfg->mode == ProtocolModeValue) { selected = buds_models_count + 1; } @@ -384,7 +409,9 @@ void scene_easysetup_buds_model_on_exit(void* _ctx) { static void buds_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; + _cfg->mode = ProtocolModeValue; cfg->data.buds.model = (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); scene_manager_previous_scene(ctx->scene_manager); @@ -392,7 +419,8 @@ static void buds_model_custom_callback(void* _ctx) { } void scene_easysetup_buds_model_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Model Code"); @@ -417,16 +445,18 @@ void scene_easysetup_buds_model_custom_on_exit(void* _ctx) { static void watch_model_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; switch(index) { case 0: - cfg->data.watch.model = 0x00; + _cfg->mode = ProtocolModeRandom; scene_manager_previous_scene(ctx->scene_manager); break; case watch_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom); break; default: + _cfg->mode = ProtocolModeValue; cfg->data.watch.model = watch_models[index - 1].value; scene_manager_previous_scene(ctx->scene_manager); break; @@ -434,27 +464,28 @@ static void watch_model_callback(void* _ctx, uint32_t index) { } void scene_easysetup_watch_model_on_enter(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; Submenu* submenu = ctx->submenu; uint32_t selected = 0; - bool found = false; submenu_reset(submenu); submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx); - if(cfg->data.watch.model == 0x00) { - found = true; + if(_cfg->mode == ProtocolModeRandom) { selected = 0; } + + bool found = false; for(uint8_t i = 0; i < watch_models_count; i++) { submenu_add_item(submenu, watch_models[i].name, i + 1, watch_model_callback, ctx); - if(!found && cfg->data.watch.model == watch_models[i].value) { + if(!found && _cfg->mode == ProtocolModeValue && + cfg->data.watch.model == watch_models[i].value) { found = true; selected = i + 1; } } submenu_add_item(submenu, "Custom", watch_models_count + 1, watch_model_callback, ctx); - if(!found) { - found = true; + if(!found && _cfg->mode == ProtocolModeValue) { selected = watch_models_count + 1; } @@ -473,14 +504,17 @@ void scene_easysetup_watch_model_on_exit(void* _ctx) { static void watch_model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; + _cfg->mode = ProtocolModeValue; cfg->data.watch.model = (ctx->byte_store[0] << 0x00); scene_manager_previous_scene(ctx->scene_manager); scene_manager_previous_scene(ctx->scene_manager); } void scene_easysetup_watch_model_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + EasysetupCfg* cfg = &_cfg->specific.easysetup; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Model Code"); diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index db3d37b35..9ab904dc6 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -51,14 +51,18 @@ static const char* get_name(const ProtocolCfg* _cfg) { return "FastPair"; } -static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { - const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { + FastpairCfg* cfg = _cfg ? &_cfg->specific.fastpair : NULL; uint32_t model; - if(cfg && cfg->model != 0x000000) { - model = cfg->model; - } else { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: model = models[rand() % models_count].value; + break; + case ProtocolModeValue: + model = cfg->model; + break; } uint8_t size = 14; @@ -107,30 +111,36 @@ static void config_callback(void* _ctx, uint32_t index) { } } static void model_changed(VariableItem* item) { - FastpairCfg* cfg = variable_item_get_context(item); + ProtocolCfg* _cfg = variable_item_get_context(item); + FastpairCfg* cfg = &_cfg->specific.fastpair; uint8_t index = variable_item_get_current_value_index(item); if(index) { index--; + _cfg->mode = ProtocolModeValue; cfg->model = models[index].value; variable_item_set_current_value_text(item, models[index].name); } else { - cfg->model = 0x000000; + _cfg->mode = ProtocolModeRandom; variable_item_set_current_value_text(item, "Random"); } } static void extra_config(Ctx* ctx) { - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + FastpairCfg* cfg = &_cfg->specific.fastpair; VariableItemList* list = ctx->variable_item_list; VariableItem* item; size_t value_index; - item = variable_item_list_add(list, "Model Code", models_count + 1, model_changed, cfg); + item = variable_item_list_add(list, "Model Code", models_count + 1, model_changed, _cfg); const char* model_name = NULL; char model_name_buf[9]; - if(cfg->model == 0x000000) { + switch(_cfg->mode) { + case ProtocolModeRandom: + default: model_name = "Random"; value_index = 0; - } else { + break; + case ProtocolModeValue: for(uint8_t i = 0; i < models_count; i++) { if(cfg->model == models[i].value) { model_name = models[i].name; @@ -143,6 +153,7 @@ static void extra_config(Ctx* ctx) { model_name = model_name_buf; value_index = models_count + 1; } + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -167,16 +178,18 @@ const Protocol protocol_fastpair = { static void model_callback(void* _ctx, uint32_t index) { Ctx* ctx = _ctx; - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + FastpairCfg* cfg = &_cfg->specific.fastpair; switch(index) { case 0: - cfg->model = 0x000000; + _cfg->mode = ProtocolModeRandom; scene_manager_previous_scene(ctx->scene_manager); break; case models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom); break; default: + _cfg->mode = ProtocolModeValue; cfg->model = models[index - 1].value; scene_manager_previous_scene(ctx->scene_manager); break; @@ -184,27 +197,27 @@ static void model_callback(void* _ctx, uint32_t index) { } void scene_fastpair_model_on_enter(void* _ctx) { Ctx* ctx = _ctx; - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + FastpairCfg* cfg = &_cfg->specific.fastpair; Submenu* submenu = ctx->submenu; uint32_t selected = 0; - bool found = false; submenu_reset(submenu); submenu_add_item(submenu, "Random", 0, model_callback, ctx); - if(cfg->model == 0x000000) { - found = true; + if(_cfg->mode == ProtocolModeRandom) { selected = 0; } + + bool found = false; for(uint8_t i = 0; i < models_count; i++) { submenu_add_item(submenu, models[i].name, i + 1, model_callback, ctx); - if(!found && cfg->model == models[i].value) { + if(!found && _cfg->mode == ProtocolModeValue && cfg->model == models[i].value) { found = true; selected = i + 1; } } submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx); - if(!found) { - found = true; + if(!found && _cfg->mode == ProtocolModeValue) { selected = models_count + 1; } @@ -223,7 +236,9 @@ void scene_fastpair_model_on_exit(void* _ctx) { static void model_custom_callback(void* _ctx) { Ctx* ctx = _ctx; - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + FastpairCfg* cfg = &_cfg->specific.fastpair; + _cfg->mode = ProtocolModeValue; cfg->model = (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00); scene_manager_previous_scene(ctx->scene_manager); @@ -231,7 +246,8 @@ static void model_custom_callback(void* _ctx) { } void scene_fastpair_model_custom_on_enter(void* _ctx) { Ctx* ctx = _ctx; - FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + FastpairCfg* cfg = &_cfg->specific.fastpair; ByteInput* byte_input = ctx->byte_input; byte_input_set_header_text(byte_input, "Enter custom Model Code"); diff --git a/applications/external/ble_spam/protocols/swiftpair.c b/applications/external/ble_spam/protocols/swiftpair.c index 3a4788312..7fc65cb0d 100644 --- a/applications/external/ble_spam/protocols/swiftpair.c +++ b/applications/external/ble_spam/protocols/swiftpair.c @@ -4,27 +4,33 @@ // Hacked together by @Willy-JL and @Spooks4576 // Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair +const char* names[] = { + "Assquach๐Ÿ’ฆ", + "Flipper ๐Ÿฌ", + "iOS 17 ๐ŸŽ", + "Kink๐Ÿ’ฆ", + "๐Ÿ‘‰๐Ÿ‘Œ", + "๐Ÿ”ต๐Ÿฆท", +}; +const uint8_t names_count = COUNT_OF(names); + static const char* get_name(const ProtocolCfg* _cfg) { UNUSED(_cfg); return "SwiftPair"; } -static void make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) { - const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL; +static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { + SwiftpairCfg* cfg = _cfg ? &_cfg->specific.swiftpair : NULL; const char* name; - if(cfg && cfg->name[0] != '\0') { + switch(cfg ? _cfg->mode : ProtocolModeRandom) { + case ProtocolModeRandom: + default: + name = names[rand() % names_count]; + break; + case ProtocolModeValue: name = cfg->name; - } else { - const char* names[] = { - "Assquach๐Ÿ’ฆ", - "Flipper ๐Ÿฌ", - "iOS 17 ๐ŸŽ", - "Kink๐Ÿ’ฆ", - "๐Ÿ‘‰๐Ÿ‘Œ", - "๐Ÿ”ต๐Ÿฆท", - }; - name = names[rand() % COUNT_OF(names)]; + break; } uint8_t name_len = strlen(name); @@ -67,12 +73,14 @@ static void config_callback(void* _ctx, uint32_t index) { } } static void extra_config(Ctx* ctx) { - SwiftpairCfg* cfg = &ctx->attack->payload.cfg.swiftpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + SwiftpairCfg* cfg = &_cfg->specific.swiftpair; VariableItemList* list = ctx->variable_item_list; VariableItem* item; item = variable_item_list_add(list, "Display Name", 0, NULL, NULL); - variable_item_set_current_value_text(item, cfg->name[0] != '\0' ? cfg->name : "Random"); + variable_item_set_current_value_text( + item, _cfg->mode == ProtocolModeRandom ? "Random" : cfg->name); variable_item_list_add(list, "Requires enabling SwiftPair", 0, NULL, NULL); @@ -94,15 +102,18 @@ const Protocol protocol_swiftpair = { static void name_callback(void* _ctx) { Ctx* ctx = _ctx; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + _cfg->mode = ProtocolModeValue; scene_manager_previous_scene(ctx->scene_manager); } void scene_swiftpair_name_on_enter(void* _ctx) { Ctx* ctx = _ctx; - SwiftpairCfg* cfg = &ctx->attack->payload.cfg.swiftpair; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + SwiftpairCfg* cfg = &_cfg->specific.swiftpair; TextInput* text_input = ctx->text_input; text_input_reset(text_input); - text_input_set_header_text(text_input, "Leave empty for random"); + text_input_set_header_text(text_input, "Press back for random"); text_input_set_result_callback( text_input, name_callback, ctx, cfg->name, sizeof(cfg->name), true); @@ -112,8 +123,11 @@ void scene_swiftpair_name_on_enter(void* _ctx) { view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewTextInput); } bool scene_swiftpair_name_on_event(void* _ctx, SceneManagerEvent event) { - UNUSED(_ctx); - UNUSED(event); + Ctx* ctx = _ctx; + ProtocolCfg* _cfg = &ctx->attack->payload.cfg; + if(event.type == SceneManagerEventTypeBack) { + _cfg->mode = ProtocolModeRandom; + } return false; } void scene_swiftpair_name_on_exit(void* _ctx) { From 76131dd4aaf5390c0b483674fdea362475d5454d Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 00:51:45 +0100 Subject: [PATCH 19/28] BLE Spam Bruteforce model codes functionality --- applications/external/ble_spam/ble_spam.c | 37 ++++++++++++--- .../external/ble_spam/protocols/_protocols.h | 6 +++ .../external/ble_spam/protocols/continuity.c | 46 +++++++++++++++++++ .../external/ble_spam/protocols/easysetup.c | 46 +++++++++++++++++++ .../external/ble_spam/protocols/fastpair.c | 23 ++++++++++ 5 files changed, 151 insertions(+), 7 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 54171cec6..cd6c5d215 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -334,7 +334,16 @@ static void draw_callback(Canvas* canvas, void* _ctx) { char str[32]; canvas_set_font(canvas, FontBatteryPercent); - snprintf(str, sizeof(str), "%ims", delays[state->delay]); + if(payload->cfg.mode == ProtocolModeBruteforce) { + snprintf( + str, + sizeof(str), + "0x%0*lX", + payload->cfg.bruteforce.size * 2, + payload->cfg.bruteforce.current); + } else { + snprintf(str, sizeof(str), "%ims", delays[state->delay]); + } canvas_draw_str_aligned(canvas, 116, 12, AlignRight, AlignBottom, str); canvas_draw_icon(canvas, 119, 6, &I_SmallArrowUp_3x5); canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5); @@ -419,15 +428,29 @@ static bool input_callback(InputEvent* input, void* _ctx) { } break; case InputKeyUp: - if(is_attack && state->delay < COUNT_OF(delays) - 1) { - state->delay++; - if(advertising) start_blink(state); + if(is_attack) { + ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; + if(_cfg->mode == ProtocolModeBruteforce) { + _cfg->bruteforce.current = + (_cfg->bruteforce.current + 1) % (1 << (_cfg->bruteforce.size * 8)); + _cfg->bruteforce.counter = 0; + } else if(state->delay < COUNT_OF(delays) - 1) { + state->delay++; + if(advertising) start_blink(state); + } } break; case InputKeyDown: - if(is_attack && state->delay > 0) { - state->delay--; - if(advertising) start_blink(state); + if(is_attack) { + ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; + if(_cfg->mode == ProtocolModeBruteforce) { + _cfg->bruteforce.current = + (_cfg->bruteforce.current - 1) % (1 << (_cfg->bruteforce.size * 8)); + _cfg->bruteforce.counter = 0; + } else if(state->delay > 0) { + state->delay--; + if(advertising) start_blink(state); + } } break; case InputKeyLeft: diff --git a/applications/external/ble_spam/protocols/_protocols.h b/applications/external/ble_spam/protocols/_protocols.h index c1395dab8..5bdc91b3f 100644 --- a/applications/external/ble_spam/protocols/_protocols.h +++ b/applications/external/ble_spam/protocols/_protocols.h @@ -8,10 +8,16 @@ typedef enum { ProtocolModeRandom, ProtocolModeValue, + ProtocolModeBruteforce, } ProtocolMode; struct ProtocolCfg { ProtocolMode mode; + struct { + uint8_t counter; + uint32_t current; + uint8_t size; + } bruteforce; union { ContinuityCfg continuity; FastpairCfg fastpair; diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index 6a7e130e5..2391c81bf 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -147,6 +147,13 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { case ProtocolModeValue: model = cfg->data.proximity_pair.model; break; + case ProtocolModeBruteforce: + if(_cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + if(_cfg->bruteforce.current++ >= 0xFFFF) _cfg->bruteforce.current = 0x0000; + } + model = cfg->data.proximity_pair.model = _cfg->bruteforce.current; + break; } uint8_t prefix; @@ -221,6 +228,13 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { case ProtocolModeValue: action = cfg->data.nearby_action.action; break; + case ProtocolModeBruteforce: + if(_cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + if(_cfg->bruteforce.current++ >= 0xFF) _cfg->bruteforce.current = 0x00; + } + action = cfg->data.nearby_action.action = _cfg->bruteforce.current; + break; } uint8_t flags; @@ -424,6 +438,10 @@ static void extra_config(Ctx* ctx) { value_index = pp_models_count + 1; } break; + case ProtocolModeBruteforce: + model_name = "Bruteforce"; + value_index = pp_models_count + 1; + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -486,6 +504,10 @@ static void extra_config(Ctx* ctx) { value_index = na_actions_count + 1; } break; + case ProtocolModeBruteforce: + action_name = "Bruteforce"; + value_index = na_actions_count + 1; + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, action_name); @@ -550,6 +572,13 @@ static void pp_model_callback(void* _ctx, uint32_t index) { case pp_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModelCustom); break; + case pp_models_count + 2: + _cfg->mode = ProtocolModeBruteforce; + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.current = cfg->data.proximity_pair.model; + _cfg->bruteforce.size = 2; + scene_manager_previous_scene(ctx->scene_manager); + break; default: _cfg->mode = ProtocolModeValue; cfg->data.proximity_pair.model = pp_models[index - 1].value; @@ -584,6 +613,11 @@ void scene_continuity_pp_model_on_enter(void* _ctx) { selected = pp_models_count + 1; } + submenu_add_item(submenu, "Bruteforce", pp_models_count + 2, pp_model_callback, ctx); + if(_cfg->mode == ProtocolModeBruteforce) { + selected = pp_models_count + 2; + } + submenu_set_selected_item(submenu, selected); view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); @@ -733,6 +767,13 @@ static void na_action_callback(void* _ctx, uint32_t index) { case na_actions_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaActionCustom); break; + case na_actions_count + 2: + _cfg->mode = ProtocolModeBruteforce; + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.current = cfg->data.nearby_action.action; + _cfg->bruteforce.size = 1; + scene_manager_previous_scene(ctx->scene_manager); + break; default: _cfg->mode = ProtocolModeValue; cfg->data.nearby_action.action = na_actions[index - 1].value; @@ -767,6 +808,11 @@ void scene_continuity_na_action_on_enter(void* _ctx) { selected = na_actions_count + 1; } + submenu_add_item(submenu, "Bruteforce", na_actions_count + 2, na_action_callback, ctx); + if(_cfg->mode == ProtocolModeBruteforce) { + selected = na_actions_count + 2; + } + submenu_set_selected_item(submenu, selected); view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index d13083b7d..adece5472 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -106,6 +106,13 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) { case ProtocolModeValue: model = cfg->data.buds.model; break; + case ProtocolModeBruteforce: + if(_cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + if(_cfg->bruteforce.current++ >= 0xFFFFFF) _cfg->bruteforce.current = 0x000000; + } + model = cfg->data.buds.model = _cfg->bruteforce.current; + break; } packet[i++] = 27; // Size @@ -153,6 +160,13 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) { case ProtocolModeValue: model = cfg->data.watch.model; break; + case ProtocolModeBruteforce: + if(_cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + if(_cfg->bruteforce.current++ >= 0xFF) _cfg->bruteforce.current = 0x00; + } + model = cfg->data.watch.model = _cfg->bruteforce.current; + break; } packet[i++] = 14; // Size @@ -287,6 +301,10 @@ static void extra_config(Ctx* ctx) { value_index = buds_models_count + 1; } break; + case ProtocolModeBruteforce: + model_name = "Bruteforce"; + value_index = buds_models_count + 1; + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -319,6 +337,10 @@ static void extra_config(Ctx* ctx) { value_index = watch_models_count + 1; } break; + case ProtocolModeBruteforce: + model_name = "Bruteforce"; + value_index = watch_models_count + 1; + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -360,6 +382,13 @@ static void buds_model_callback(void* _ctx, uint32_t index) { case buds_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom); break; + case buds_models_count + 2: + _cfg->mode = ProtocolModeBruteforce; + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.current = cfg->data.buds.model; + _cfg->bruteforce.size = 3; + scene_manager_previous_scene(ctx->scene_manager); + break; default: _cfg->mode = ProtocolModeValue; cfg->data.buds.model = buds_models[index - 1].value; @@ -394,6 +423,11 @@ void scene_easysetup_buds_model_on_enter(void* _ctx) { selected = buds_models_count + 1; } + submenu_add_item(submenu, "Bruteforce", buds_models_count + 2, buds_model_callback, ctx); + if(_cfg->mode == ProtocolModeBruteforce) { + selected = buds_models_count + 2; + } + submenu_set_selected_item(submenu, selected); view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); @@ -455,6 +489,13 @@ static void watch_model_callback(void* _ctx, uint32_t index) { case watch_models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom); break; + case watch_models_count + 2: + _cfg->mode = ProtocolModeBruteforce; + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.current = cfg->data.watch.model; + _cfg->bruteforce.size = 1; + scene_manager_previous_scene(ctx->scene_manager); + break; default: _cfg->mode = ProtocolModeValue; cfg->data.watch.model = watch_models[index - 1].value; @@ -489,6 +530,11 @@ void scene_easysetup_watch_model_on_enter(void* _ctx) { selected = watch_models_count + 1; } + submenu_add_item(submenu, "Bruteforce", watch_models_count + 2, watch_model_callback, ctx); + if(_cfg->mode == ProtocolModeBruteforce) { + selected = watch_models_count + 2; + } + submenu_set_selected_item(submenu, selected); view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index 9ab904dc6..ef77580f6 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -63,6 +63,13 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { case ProtocolModeValue: model = cfg->model; break; + case ProtocolModeBruteforce: + if(_cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + if(_cfg->bruteforce.current++ >= 0xFFFFFF) _cfg->bruteforce.current = 0x000000; + } + model = cfg->model = _cfg->bruteforce.current; + break; } uint8_t size = 14; @@ -154,6 +161,10 @@ static void extra_config(Ctx* ctx) { value_index = models_count + 1; } break; + case ProtocolModeBruteforce: + model_name = "Bruteforce"; + value_index = models_count + 1; + break; } variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, model_name); @@ -188,6 +199,13 @@ static void model_callback(void* _ctx, uint32_t index) { case models_count + 1: scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom); break; + case models_count + 2: + _cfg->mode = ProtocolModeBruteforce; + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.current = cfg->model; + _cfg->bruteforce.size = 3; + scene_manager_previous_scene(ctx->scene_manager); + break; default: _cfg->mode = ProtocolModeValue; cfg->model = models[index - 1].value; @@ -221,6 +239,11 @@ void scene_fastpair_model_on_enter(void* _ctx) { selected = models_count + 1; } + submenu_add_item(submenu, "Bruteforce", models_count + 2, model_callback, ctx); + if(_cfg->mode == ProtocolModeBruteforce) { + selected = models_count + 2; + } + submenu_set_selected_item(submenu, selected); view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu); From 636becc3ba57ea0e48ee677c841d6f19ac393d42 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:10:45 +0100 Subject: [PATCH 20/28] Fix text, add codes by @DiamondRoPlayz @xAstroBoy --- .../external/ble_spam/protocols/easysetup.c | 10 ++++---- .../external/ble_spam/protocols/fastpair.c | 25 ++++++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index adece5472..eaf755b18 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -36,9 +36,9 @@ const struct { const char* name; } watch_models[] = { {0x1A, "Fallback Watch"}, - {0x01, "White Watch4 Classic 44"}, - {0x02, "Black Watch4 Classic 40"}, - {0x03, "White Watch4 Classic 40"}, + {0x01, "White Watch4 Classic 44m"}, + {0x02, "Black Watch4 Classic 40m"}, + {0x03, "White Watch4 Classic 40m"}, {0x04, "Black Watch4 44mm"}, {0x05, "Silver Watch4 44mm"}, {0x06, "Green Watch4 44mm"}, @@ -59,8 +59,8 @@ const struct { {0x1B, "Black Watch6 Pink 40mm"}, {0x1C, "Gold Watch6 Gold 40mm"}, {0x1D, "Silver Watch6 Cyan 44mm"}, - {0x1E, "Black Watch6 Classic 43mm"}, - {0x20, "Green Watch6 Classic 43mm"}, + {0x1E, "Black Watch6 Classic 43m"}, + {0x20, "Green Watch6 Classic 43m"}, }; const uint8_t watch_models_count = COUNT_OF(watch_models); diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index ef77580f6..fcfb75a67 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -11,21 +11,40 @@ const struct { // Genuine actions {0x00000C, "Set Up Device"}, - // Genuine devices - {0x00000A, "Anti-Spoofing Test (lmao)"}, + // Genuine non-production/forgotten (good job Google) {0x0001F0, "Bisto CSR8670 Dev Board"}, {0x000047, "Arduino 101"}, + {0x00000A, "Anti-Spoof Test"}, + {0x0A0000, "Anti-Spoof Test 2"}, + {0x00000B, "Google Gphones"}, + {0x0B0000, "Google Gphones 2"}, + {0x0C0000, "Google Gphones 3"}, + {0x00000D, "Test 00000D"}, + {0x000007, "Android Auto"}, + {0x070000, "Android Auto 2"}, + {0x000008, "Foocorp Foophones"}, + {0x080000, "Foocorp Foophones 2"}, + {0x000009, "Test Android TV"}, + {0x090000, "Test Android TV 2"}, + {0x000048, "Fast Pair Headphones"}, + {0x000049, "Fast Pair Headphones 2"}, + + // Genuine devices {0xCD8256, "Bose NC 700"}, + {0x0000F0, "Bose QuietComfort 35 II"}, + {0x821F66, "JBL Flip 6"}, {0xF52494, "JBL Buds Pro"}, {0x718FA4, "JBL Live 300TWS"}, - {0x821F66, "JBL Flip 6"}, + {0x0002F0, "JBL Everest 110GA"}, {0x92BBBD, "Pixel Buds"}, {0x000006, "Google Pixel buds"}, + {0x060000, "Google Pixel buds 2"}, {0xD446A7, "Sony XM5"}, {0x2D7A23, "Sony WF-1000XM4"}, {0x0E30C3, "Razer Hammerhead TWS"}, {0x72EF8D, "Razer Hammerhead TWS X"}, {0x72FB00, "Soundcore Spirit Pro GVA"}, + {0x0003F0, "LG HBS-835S"}, // Custom debug popups {0xD99CA1, "Flipper Zero"}, From 54e7cbce8fbfac93f713e59a62d2d5f2fabfdd73 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:16:48 +0100 Subject: [PATCH 21/28] =?UTF-8?q?Bump=20BLE=20Spam=20version=20(i=20forgor?= =?UTF-8?q?=20=F0=9F=92=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/external/ble_spam/application.fam | 2 +- applications/external/ble_spam/ble_spam.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/external/ble_spam/application.fam b/applications/external/ble_spam/application.fam index 532a55cfb..1f04d7f4f 100644 --- a/applications/external/ble_spam/application.fam +++ b/applications/external/ble_spam/application.fam @@ -8,7 +8,7 @@ App( fap_category="Bluetooth", fap_author="@Willy-JL @ECTO-1A @Spooks4576", fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam", - fap_version="3.3", + fap_version="4.0", fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications", fap_icon_assets="icons", fap_icon_assets_symbol="ble_spam", diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index cd6c5d215..2f7ab4e8b 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -322,7 +322,7 @@ static void draw_callback(Canvas* canvas, void* _ctx) { "App+Spam: \e#WillyJL\e# XFW\n" "Apple+Crash: \e#ECTO-1A\e#\n" "Android+Win: \e#Spooks4576\e#\n" - " Version \e#3.3\e#", + " Version \e#4.0\e#", false); break; default: { From ed364cbffd4477eb8e8d376cfdfdd4b823c1c820 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:19:12 +0100 Subject: [PATCH 22/28] Fix reset menu dialog bug --- .../scenes/xtreme_app_scene_interface_mainmenu_reset.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c index 625cd1f88..c797ff288 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_mainmenu_reset.c @@ -37,6 +37,9 @@ bool xtreme_app_scene_interface_mainmenu_reset_on_event(void* context, SceneMana app->require_reboot = true; xtreme_app_apply(app); break; + case DialogExResultLeft: + scene_manager_previous_scene(app->scene_manager); + break; default: break; } From 8eaff22935e8b1499d1fbe78f62d6bf8619d09a1 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:38:22 +0100 Subject: [PATCH 23/28] Simplify bruteforce code --nobuild --- applications/external/ble_spam/ble_spam.c | 16 +++++++++++----- .../external/ble_spam/protocols/_protocols.h | 2 +- .../external/ble_spam/protocols/continuity.c | 16 ++++------------ .../external/ble_spam/protocols/easysetup.c | 16 ++++------------ .../external/ble_spam/protocols/fastpair.c | 8 ++------ 5 files changed, 22 insertions(+), 36 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 2f7ab4e8b..229eee0d4 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -162,11 +162,17 @@ static int32_t adv_thread(void* _ctx) { uint8_t mac[GAP_MAC_ADDR_SIZE]; Payload* payload = &attacks[state->index].payload; const Protocol* protocol = attacks[state->index].protocol; + ProtocolCfg* _cfg = &payload->cfg; if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac)); if(state->ctx.led_indicator) start_blink(state); while(state->advertising) { if(protocol) { + if(_cfg->mode == ProtocolModeBruteforce && _cfg->bruteforce.counter++ >= 10) { + _cfg->bruteforce.counter = 0; + _cfg->bruteforce.value = + (_cfg->bruteforce.value + 1) % (1 << (_cfg->bruteforce.size * 8)); + } protocol->make_packet(&size, &packet, &payload->cfg); } else { protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL); @@ -340,7 +346,7 @@ static void draw_callback(Canvas* canvas, void* _ctx) { sizeof(str), "0x%0*lX", payload->cfg.bruteforce.size * 2, - payload->cfg.bruteforce.current); + payload->cfg.bruteforce.value); } else { snprintf(str, sizeof(str), "%ims", delays[state->delay]); } @@ -431,9 +437,9 @@ static bool input_callback(InputEvent* input, void* _ctx) { if(is_attack) { ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; if(_cfg->mode == ProtocolModeBruteforce) { - _cfg->bruteforce.current = - (_cfg->bruteforce.current + 1) % (1 << (_cfg->bruteforce.size * 8)); _cfg->bruteforce.counter = 0; + _cfg->bruteforce.value = + (_cfg->bruteforce.value + 1) % (1 << (_cfg->bruteforce.size * 8)); } else if(state->delay < COUNT_OF(delays) - 1) { state->delay++; if(advertising) start_blink(state); @@ -444,9 +450,9 @@ static bool input_callback(InputEvent* input, void* _ctx) { if(is_attack) { ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; if(_cfg->mode == ProtocolModeBruteforce) { - _cfg->bruteforce.current = - (_cfg->bruteforce.current - 1) % (1 << (_cfg->bruteforce.size * 8)); _cfg->bruteforce.counter = 0; + _cfg->bruteforce.value = + (_cfg->bruteforce.value - 1) % (1 << (_cfg->bruteforce.size * 8)); } else if(state->delay > 0) { state->delay--; if(advertising) start_blink(state); diff --git a/applications/external/ble_spam/protocols/_protocols.h b/applications/external/ble_spam/protocols/_protocols.h index 5bdc91b3f..a34bb1e98 100644 --- a/applications/external/ble_spam/protocols/_protocols.h +++ b/applications/external/ble_spam/protocols/_protocols.h @@ -15,7 +15,7 @@ struct ProtocolCfg { ProtocolMode mode; struct { uint8_t counter; - uint32_t current; + uint32_t value; uint8_t size; } bruteforce; union { diff --git a/applications/external/ble_spam/protocols/continuity.c b/applications/external/ble_spam/protocols/continuity.c index 2391c81bf..5babbd9cd 100644 --- a/applications/external/ble_spam/protocols/continuity.c +++ b/applications/external/ble_spam/protocols/continuity.c @@ -148,11 +148,7 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { model = cfg->data.proximity_pair.model; break; case ProtocolModeBruteforce: - if(_cfg->bruteforce.counter++ >= 10) { - _cfg->bruteforce.counter = 0; - if(_cfg->bruteforce.current++ >= 0xFFFF) _cfg->bruteforce.current = 0x0000; - } - model = cfg->data.proximity_pair.model = _cfg->bruteforce.current; + model = cfg->data.proximity_pair.model = _cfg->bruteforce.value; break; } @@ -229,11 +225,7 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { action = cfg->data.nearby_action.action; break; case ProtocolModeBruteforce: - if(_cfg->bruteforce.counter++ >= 10) { - _cfg->bruteforce.counter = 0; - if(_cfg->bruteforce.current++ >= 0xFF) _cfg->bruteforce.current = 0x00; - } - action = cfg->data.nearby_action.action = _cfg->bruteforce.current; + action = cfg->data.nearby_action.action = _cfg->bruteforce.value; break; } @@ -575,7 +567,7 @@ static void pp_model_callback(void* _ctx, uint32_t index) { case pp_models_count + 2: _cfg->mode = ProtocolModeBruteforce; _cfg->bruteforce.counter = 0; - _cfg->bruteforce.current = cfg->data.proximity_pair.model; + _cfg->bruteforce.value = cfg->data.proximity_pair.model; _cfg->bruteforce.size = 2; scene_manager_previous_scene(ctx->scene_manager); break; @@ -770,7 +762,7 @@ static void na_action_callback(void* _ctx, uint32_t index) { case na_actions_count + 2: _cfg->mode = ProtocolModeBruteforce; _cfg->bruteforce.counter = 0; - _cfg->bruteforce.current = cfg->data.nearby_action.action; + _cfg->bruteforce.value = cfg->data.nearby_action.action; _cfg->bruteforce.size = 1; scene_manager_previous_scene(ctx->scene_manager); break; diff --git a/applications/external/ble_spam/protocols/easysetup.c b/applications/external/ble_spam/protocols/easysetup.c index eaf755b18..8aff3521c 100644 --- a/applications/external/ble_spam/protocols/easysetup.c +++ b/applications/external/ble_spam/protocols/easysetup.c @@ -107,11 +107,7 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) { model = cfg->data.buds.model; break; case ProtocolModeBruteforce: - if(_cfg->bruteforce.counter++ >= 10) { - _cfg->bruteforce.counter = 0; - if(_cfg->bruteforce.current++ >= 0xFFFFFF) _cfg->bruteforce.current = 0x000000; - } - model = cfg->data.buds.model = _cfg->bruteforce.current; + model = cfg->data.buds.model = _cfg->bruteforce.value; break; } @@ -161,11 +157,7 @@ void make_packet(uint8_t* out_size, uint8_t** out_packet, ProtocolCfg* _cfg) { model = cfg->data.watch.model; break; case ProtocolModeBruteforce: - if(_cfg->bruteforce.counter++ >= 10) { - _cfg->bruteforce.counter = 0; - if(_cfg->bruteforce.current++ >= 0xFF) _cfg->bruteforce.current = 0x00; - } - model = cfg->data.watch.model = _cfg->bruteforce.current; + model = cfg->data.watch.model = _cfg->bruteforce.value; break; } @@ -385,7 +377,7 @@ static void buds_model_callback(void* _ctx, uint32_t index) { case buds_models_count + 2: _cfg->mode = ProtocolModeBruteforce; _cfg->bruteforce.counter = 0; - _cfg->bruteforce.current = cfg->data.buds.model; + _cfg->bruteforce.value = cfg->data.buds.model; _cfg->bruteforce.size = 3; scene_manager_previous_scene(ctx->scene_manager); break; @@ -492,7 +484,7 @@ static void watch_model_callback(void* _ctx, uint32_t index) { case watch_models_count + 2: _cfg->mode = ProtocolModeBruteforce; _cfg->bruteforce.counter = 0; - _cfg->bruteforce.current = cfg->data.watch.model; + _cfg->bruteforce.value = cfg->data.watch.model; _cfg->bruteforce.size = 1; scene_manager_previous_scene(ctx->scene_manager); break; diff --git a/applications/external/ble_spam/protocols/fastpair.c b/applications/external/ble_spam/protocols/fastpair.c index fcfb75a67..e4ab936da 100644 --- a/applications/external/ble_spam/protocols/fastpair.c +++ b/applications/external/ble_spam/protocols/fastpair.c @@ -83,11 +83,7 @@ static void make_packet(uint8_t* _size, uint8_t** _packet, ProtocolCfg* _cfg) { model = cfg->model; break; case ProtocolModeBruteforce: - if(_cfg->bruteforce.counter++ >= 10) { - _cfg->bruteforce.counter = 0; - if(_cfg->bruteforce.current++ >= 0xFFFFFF) _cfg->bruteforce.current = 0x000000; - } - model = cfg->model = _cfg->bruteforce.current; + model = cfg->model = _cfg->bruteforce.value; break; } @@ -221,7 +217,7 @@ static void model_callback(void* _ctx, uint32_t index) { case models_count + 2: _cfg->mode = ProtocolModeBruteforce; _cfg->bruteforce.counter = 0; - _cfg->bruteforce.current = cfg->model; + _cfg->bruteforce.value = cfg->model; _cfg->bruteforce.size = 3; scene_manager_previous_scene(ctx->scene_manager); break; From 1b9ad5be80cf1c14e33a75f21300ab7be322a6a5 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 05:03:47 +0100 Subject: [PATCH 24/28] Bruteforce mode controls: manual send and delay --- applications/external/ble_spam/ble_spam.c | 97 +++++++++++++++++++---- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 229eee0d4..e77ae4926 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -131,8 +131,17 @@ typedef struct { uint8_t delay; FuriThread* thread; int8_t index; + bool ignore_bruteforce; } State; +const NotificationSequence solid_message = { + &message_red_0, + &message_green_255, + &message_blue_255, + &message_do_not_reset, + &message_delay_10, + NULL, +}; NotificationMessage blink_message = { .type = NotificationMessageTypeLedBlinkStart, .data.led_blink.color = LightBlue | LightGreen, @@ -355,14 +364,30 @@ static void draw_callback(Canvas* canvas, void* _ctx) { canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5); canvas_set_font(canvas, FontBatteryPercent); - snprintf( - str, - sizeof(str), - "%02i/%02i: %s", - state->index + 1, - ATTACKS_COUNT, - protocol ? protocol->get_name(&payload->cfg) : "Everything AND"); - canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str); + if(payload->cfg.mode == ProtocolModeBruteforce) { + canvas_draw_str_aligned(canvas, 62, 22, AlignCenter, AlignBottom, "Bruteforce"); + if(delays[state->delay] < 100) { + snprintf(str, sizeof(str), "%ims>", delays[state->delay]); + } else { + snprintf(str, sizeof(str), "%.1fs>", (double)delays[state->delay] / 1000); + } + uint16_t w = canvas_string_width(canvas, str); + elements_slightly_rounded_box(canvas, 3, 14, 30, 10); + elements_slightly_rounded_box(canvas, 119 - w, 14, 6 + w, 10); + canvas_invert_color(canvas); + canvas_draw_str_aligned(canvas, 5, 22, AlignLeft, AlignBottom, "index + 1, + ATTACKS_COUNT, + protocol ? protocol->get_name(&payload->cfg) : "Everything AND"); + canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 22, str); + } canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 4, 33, attack->title); @@ -418,6 +443,7 @@ static bool input_callback(InputEvent* input, void* _ctx) { consumed = true; bool is_attack = state->index >= 0 && state->index <= ATTACKS_COUNT - 1; + ProtocolCfg* _cfg = is_attack ? &attacks[state->index].payload.cfg : NULL; bool advertising = state->advertising; switch(input->key) { @@ -435,7 +461,6 @@ static bool input_callback(InputEvent* input, void* _ctx) { break; case InputKeyUp: if(is_attack) { - ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; if(_cfg->mode == ProtocolModeBruteforce) { _cfg->bruteforce.counter = 0; _cfg->bruteforce.value = @@ -448,7 +473,6 @@ static bool input_callback(InputEvent* input, void* _ctx) { break; case InputKeyDown: if(is_attack) { - ProtocolCfg* _cfg = &attacks[state->index].payload.cfg; if(_cfg->mode == ProtocolModeBruteforce) { _cfg->bruteforce.counter = 0; _cfg->bruteforce.value = @@ -460,15 +484,56 @@ static bool input_callback(InputEvent* input, void* _ctx) { } break; case InputKeyLeft: - if(state->index > PAGE_MIN) { - if(advertising) toggle_adv(state); - state->index--; + if(input->type == InputTypeLong) { + state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true; + } + if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce || + _cfg->mode != ProtocolModeBruteforce) { + if(state->index > PAGE_MIN) { + if(advertising) toggle_adv(state); + state->index--; + } + } else { + if(!advertising) { + bool resume = furi_hal_bt_is_active(); + furi_hal_bt_stop_advertising(); + Payload* payload = &attacks[state->index].payload; + const Protocol* protocol = attacks[state->index].protocol; + + uint8_t size; + uint8_t* packet; + protocol->make_packet(&size, &packet, &payload->cfg); + furi_hal_bt_custom_adv_set(packet, size); + free(packet); + + uint8_t mac[GAP_MAC_ADDR_SIZE]; + furi_hal_random_fill_buf(mac, sizeof(mac)); + uint16_t delay = delays[state->delay]; + furi_hal_bt_custom_adv_start(delay, delay, 0x00, mac, 0x1F); + if(state->ctx.led_indicator) + notification_message(state->ctx.notification, &solid_message); + furi_delay_ms(10); + furi_hal_bt_custom_adv_stop(); + + if(state->ctx.led_indicator) + notification_message_block(state->ctx.notification, &sequence_reset_rgb); + if(resume) furi_hal_bt_start_advertising(); + } } break; case InputKeyRight: - if(state->index < PAGE_MAX) { - if(advertising) toggle_adv(state); - state->index++; + if(input->type == InputTypeLong) { + state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true; + } + if(input->type == InputTypeShort || !is_attack || state->ignore_bruteforce || + _cfg->mode != ProtocolModeBruteforce) { + if(state->index < PAGE_MAX) { + if(advertising) toggle_adv(state); + state->index++; + } + } else { + state->delay = (state->delay + 1) % COUNT_OF(delays); + if(advertising) start_blink(state); } break; case InputKeyBack: From b12ef9e596099aab66d782e47ab8986d8e4da8fc Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 05:04:10 +0100 Subject: [PATCH 25/28] Help section for bruteforce --- applications/external/ble_spam/ble_spam.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index e77ae4926..46d74685b 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -214,10 +214,11 @@ static void toggle_adv(State* state) { } } -#define PAGE_MIN (-4) +#define PAGE_MIN (-5) #define PAGE_MAX ATTACKS_COUNT enum { - PageHelpApps = PAGE_MIN, + PageHelpBruteforce = PAGE_MIN, + PageHelpApps, PageHelpDelay, PageHelpDistance, PageHelpInfoConfig, @@ -259,6 +260,23 @@ static void draw_callback(Canvas* canvas, void* _ctx) { canvas_draw_str(canvas, 14, 12, "BLE Spam"); switch(state->index) { + case PageHelpBruteforce: + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); + elements_text_box( + canvas, + 4, + 16, + 120, + 48, + AlignLeft, + AlignTop, + "\e#Bruteforce\e# cycles codes\n" + "to find popups, hold left and\n" + "right to send manually and\n" + "change delay", + false); + break; case PageHelpApps: canvas_set_font(canvas, FontBatteryPercent); canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help"); From b7d1e12e7faea49a21df7d031060209fc67807b6 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 05:04:19 +0100 Subject: [PATCH 26/28] BLE Spam 4.1 --- applications/external/ble_spam/application.fam | 2 +- applications/external/ble_spam/ble_spam.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/external/ble_spam/application.fam b/applications/external/ble_spam/application.fam index 1f04d7f4f..d19322fd9 100644 --- a/applications/external/ble_spam/application.fam +++ b/applications/external/ble_spam/application.fam @@ -8,7 +8,7 @@ App( fap_category="Bluetooth", fap_author="@Willy-JL @ECTO-1A @Spooks4576", fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam", - fap_version="4.0", + fap_version="4.1", fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications", fap_icon_assets="icons", fap_icon_assets_symbol="ble_spam", diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 46d74685b..9d7af8467 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -355,7 +355,7 @@ static void draw_callback(Canvas* canvas, void* _ctx) { "App+Spam: \e#WillyJL\e# XFW\n" "Apple+Crash: \e#ECTO-1A\e#\n" "Android+Win: \e#Spooks4576\e#\n" - " Version \e#4.0\e#", + " Version \e#4.1\e#", false); break; default: { From 059324b2986120504fb31d8048ed27003812007a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 05:06:36 +0100 Subject: [PATCH 27/28] smh --- applications/external/ble_spam/ble_spam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 9d7af8467..72d7040b3 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -383,7 +383,7 @@ static void draw_callback(Canvas* canvas, void* _ctx) { canvas_set_font(canvas, FontBatteryPercent); if(payload->cfg.mode == ProtocolModeBruteforce) { - canvas_draw_str_aligned(canvas, 62, 22, AlignCenter, AlignBottom, "Bruteforce"); + canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignBottom, "Bruteforce"); if(delays[state->delay] < 100) { snprintf(str, sizeof(str), "%ims>", delays[state->delay]); } else { From e4309dcb8a726c063f714413279f13913b7c9342 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 25 Oct 2023 05:30:04 +0100 Subject: [PATCH 28/28] Dont repeat delay cycling --nobuild --- applications/external/ble_spam/ble_spam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/ble_spam/ble_spam.c b/applications/external/ble_spam/ble_spam.c index 72d7040b3..6e1a8cb24 100644 --- a/applications/external/ble_spam/ble_spam.c +++ b/applications/external/ble_spam/ble_spam.c @@ -549,7 +549,7 @@ static bool input_callback(InputEvent* input, void* _ctx) { if(advertising) toggle_adv(state); state->index++; } - } else { + } else if(input->type == InputTypeLong) { state->delay = (state->delay + 1) % COUNT_OF(delays); if(advertising) start_blink(state); }