mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-12 16:28:36 -07:00
Merge branch 'dev' of https://github.com/Flipper-XFW/Xtreme-Firmware into dev
This commit is contained in:
6
.github/workflow_data/devbuild.py
vendored
6
.github/workflow_data/devbuild.py
vendored
@@ -12,6 +12,12 @@ if __name__ == "__main__":
|
|||||||
event = json.load(f)
|
event = json.load(f)
|
||||||
|
|
||||||
client = nextcloud_client.Client(os.environ["NC_HOST"])
|
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"])
|
client.login(os.environ["NC_USER"], os.environ["NC_PASS"])
|
||||||
|
|
||||||
for file in (
|
for file in (
|
||||||
|
|||||||
2
.github/workflow_data/webhook.py
vendored
2
.github/workflow_data/webhook.py
vendored
@@ -36,7 +36,7 @@ if __name__ == "__main__":
|
|||||||
for i, commit in enumerate(event["commits"]):
|
for i, commit in enumerate(event["commits"]):
|
||||||
msg = commit['message'].splitlines()[0].replace("`", "")
|
msg = commit['message'].splitlines()[0].replace("`", "")
|
||||||
msg = msg[:50] + ("..." if len(msg) > 50 else "")
|
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:
|
if len(desc) > 2020:
|
||||||
desc = desc.rsplit("\n", 1)[0] + f"\n+ {count - i} more commits"
|
desc = desc.rsplit("\n", 1)[0] + f"\n+ {count - i} more commits"
|
||||||
break
|
break
|
||||||
|
|||||||
7
.github/workflow_data/webupdater.py
vendored
7
.github/workflow_data/webupdater.py
vendored
@@ -1,9 +1,16 @@
|
|||||||
import nextcloud_client
|
import nextcloud_client
|
||||||
|
import requests
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
client = nextcloud_client.Client(os.environ["NC_HOST"])
|
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"])
|
client.login(os.environ["NC_USER"], os.environ["NC_PASS"])
|
||||||
|
|
||||||
file = os.environ["ARTIFACT_TGZ"]
|
file = os.environ["ARTIFACT_TGZ"]
|
||||||
|
|||||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -16,6 +16,7 @@ concurrency:
|
|||||||
env:
|
env:
|
||||||
TARGETS: f7
|
TARGETS: f7
|
||||||
DEFAULT_TARGET: f7
|
DEFAULT_TARGET: f7
|
||||||
|
FBT_GIT_SUBMODULE_SHALLOW: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -57,6 +58,7 @@ jobs:
|
|||||||
if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')"
|
if: "github.event_name == 'push' && github.ref_name == 'dev' && !contains(github.event.head_commit.message, '--nobuild')"
|
||||||
env:
|
env:
|
||||||
NC_HOST: "https://cloud.cynthialabs.net/"
|
NC_HOST: "https://cloud.cynthialabs.net/"
|
||||||
|
NC_USERAGENT: "${{ secrets.NC_USERAGENT }}"
|
||||||
NC_USER: "${{ secrets.NC_USER }}"
|
NC_USER: "${{ secrets.NC_USER }}"
|
||||||
NC_PASS: "${{ secrets.NC_PASS }}"
|
NC_PASS: "${{ secrets.NC_PASS }}"
|
||||||
BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }}
|
BUILD_WEBHOOK: ${{ secrets.BUILD_WEBHOOK }}
|
||||||
|
|||||||
1
.github/workflows/hotfix.yml
vendored
1
.github/workflows/hotfix.yml
vendored
@@ -59,6 +59,7 @@ jobs:
|
|||||||
- name: "Upload to webupdater"
|
- name: "Upload to webupdater"
|
||||||
env:
|
env:
|
||||||
NC_HOST: "https://cloud.cynthialabs.net/"
|
NC_HOST: "https://cloud.cynthialabs.net/"
|
||||||
|
NC_USERAGENT: "${{ secrets.NC_USERAGENT }}"
|
||||||
NC_USER: "${{ secrets.NC_USER }}"
|
NC_USER: "${{ secrets.NC_USER }}"
|
||||||
NC_PASS: "${{ secrets.NC_PASS }}"
|
NC_PASS: "${{ secrets.NC_PASS }}"
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -55,6 +55,7 @@ jobs:
|
|||||||
- name: "Upload to webupdater"
|
- name: "Upload to webupdater"
|
||||||
env:
|
env:
|
||||||
NC_HOST: "https://cloud.cynthialabs.net/"
|
NC_HOST: "https://cloud.cynthialabs.net/"
|
||||||
|
NC_USERAGENT: "${{ secrets.NC_USERAGENT }}"
|
||||||
NC_USER: "${{ secrets.NC_USER }}"
|
NC_USER: "${{ secrets.NC_USER }}"
|
||||||
NC_PASS: "${{ secrets.NC_PASS }}"
|
NC_PASS: "${{ secrets.NC_PASS }}"
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ App(
|
|||||||
fap_category="Bluetooth",
|
fap_category="Bluetooth",
|
||||||
fap_author="@Willy-JL @ECTO-1A @Spooks4576",
|
fap_author="@Willy-JL @ECTO-1A @Spooks4576",
|
||||||
fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam",
|
fap_weburl="https://github.com/Flipper-XFW/Xtreme-Apps/tree/dev/ble_spam",
|
||||||
fap_version="3.3",
|
fap_version="4.1",
|
||||||
fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications",
|
fap_description="Flood BLE advertisements to cause spammy and annoying popups/notifications",
|
||||||
fap_icon_assets="icons",
|
fap_icon_assets="icons",
|
||||||
fap_icon_assets_symbol="ble_spam",
|
fap_icon_assets_symbol="ble_spam",
|
||||||
|
|||||||
230
applications/external/ble_spam/ble_spam.c
vendored
230
applications/external/ble_spam/ble_spam.c
vendored
@@ -30,13 +30,10 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = false,
|
.random_mac = false,
|
||||||
.cfg =
|
.cfg.specific.continuity =
|
||||||
{
|
{
|
||||||
.continuity =
|
.type = ContinuityTypeCustomCrash,
|
||||||
{
|
.data = {},
|
||||||
.type = ContinuityTypeCustomCrash,
|
|
||||||
.data = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -47,13 +44,10 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = false,
|
.random_mac = false,
|
||||||
.cfg =
|
.cfg.specific.continuity =
|
||||||
{
|
{
|
||||||
.continuity =
|
.type = ContinuityTypeNearbyAction,
|
||||||
{
|
.data = {},
|
||||||
.type = ContinuityTypeNearbyAction,
|
|
||||||
.data = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -64,13 +58,10 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = false,
|
.random_mac = false,
|
||||||
.cfg =
|
.cfg.specific.continuity =
|
||||||
{
|
{
|
||||||
.continuity =
|
.type = ContinuityTypeProximityPair,
|
||||||
{
|
.data = {},
|
||||||
.type = ContinuityTypeProximityPair,
|
|
||||||
.data = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -81,10 +72,7 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = true,
|
.random_mac = true,
|
||||||
.cfg =
|
.cfg.specific.fastpair = {},
|
||||||
{
|
|
||||||
.fastpair = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -94,13 +82,10 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = true,
|
.random_mac = true,
|
||||||
.cfg =
|
.cfg.specific.easysetup =
|
||||||
{
|
{
|
||||||
.easysetup =
|
.type = EasysetupTypeBuds,
|
||||||
{
|
.data = {},
|
||||||
.type = EasysetupTypeBuds,
|
|
||||||
.data = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -111,13 +96,10 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = true,
|
.random_mac = true,
|
||||||
.cfg =
|
.cfg.specific.easysetup =
|
||||||
{
|
{
|
||||||
.easysetup =
|
.type = EasysetupTypeWatch,
|
||||||
{
|
.data = {},
|
||||||
.type = EasysetupTypeWatch,
|
|
||||||
.data = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -128,10 +110,7 @@ static Attack attacks[] = {
|
|||||||
.payload =
|
.payload =
|
||||||
{
|
{
|
||||||
.random_mac = true,
|
.random_mac = true,
|
||||||
.cfg =
|
.cfg.specific.swiftpair = {},
|
||||||
{
|
|
||||||
.swiftpair = {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -152,8 +131,17 @@ typedef struct {
|
|||||||
uint8_t delay;
|
uint8_t delay;
|
||||||
FuriThread* thread;
|
FuriThread* thread;
|
||||||
int8_t index;
|
int8_t index;
|
||||||
|
bool ignore_bruteforce;
|
||||||
} State;
|
} 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 = {
|
NotificationMessage blink_message = {
|
||||||
.type = NotificationMessageTypeLedBlinkStart,
|
.type = NotificationMessageTypeLedBlinkStart,
|
||||||
.data.led_blink.color = LightBlue | LightGreen,
|
.data.led_blink.color = LightBlue | LightGreen,
|
||||||
@@ -183,11 +171,17 @@ static int32_t adv_thread(void* _ctx) {
|
|||||||
uint8_t mac[GAP_MAC_ADDR_SIZE];
|
uint8_t mac[GAP_MAC_ADDR_SIZE];
|
||||||
Payload* payload = &attacks[state->index].payload;
|
Payload* payload = &attacks[state->index].payload;
|
||||||
const Protocol* protocol = attacks[state->index].protocol;
|
const Protocol* protocol = attacks[state->index].protocol;
|
||||||
|
ProtocolCfg* _cfg = &payload->cfg;
|
||||||
if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac));
|
if(!payload->random_mac) furi_hal_random_fill_buf(mac, sizeof(mac));
|
||||||
if(state->ctx.led_indicator) start_blink(state);
|
if(state->ctx.led_indicator) start_blink(state);
|
||||||
|
|
||||||
while(state->advertising) {
|
while(state->advertising) {
|
||||||
if(protocol) {
|
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);
|
protocol->make_packet(&size, &packet, &payload->cfg);
|
||||||
} else {
|
} else {
|
||||||
protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL);
|
protocols[rand() % protocols_count]->make_packet(&size, &packet, NULL);
|
||||||
@@ -220,10 +214,11 @@ static void toggle_adv(State* state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PAGE_MIN (-4)
|
#define PAGE_MIN (-5)
|
||||||
#define PAGE_MAX ATTACKS_COUNT
|
#define PAGE_MAX ATTACKS_COUNT
|
||||||
enum {
|
enum {
|
||||||
PageHelpApps = PAGE_MIN,
|
PageHelpBruteforce = PAGE_MIN,
|
||||||
|
PageHelpApps,
|
||||||
PageHelpDelay,
|
PageHelpDelay,
|
||||||
PageHelpDistance,
|
PageHelpDistance,
|
||||||
PageHelpInfoConfig,
|
PageHelpInfoConfig,
|
||||||
@@ -265,6 +260,23 @@ static void draw_callback(Canvas* canvas, void* _ctx) {
|
|||||||
canvas_draw_str(canvas, 14, 12, "BLE Spam");
|
canvas_draw_str(canvas, 14, 12, "BLE Spam");
|
||||||
|
|
||||||
switch(state->index) {
|
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:
|
case PageHelpApps:
|
||||||
canvas_set_font(canvas, FontBatteryPercent);
|
canvas_set_font(canvas, FontBatteryPercent);
|
||||||
canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help");
|
canvas_draw_str_aligned(canvas, 124, 12, AlignRight, AlignBottom, "Help");
|
||||||
@@ -343,7 +355,7 @@ static void draw_callback(Canvas* canvas, void* _ctx) {
|
|||||||
"App+Spam: \e#WillyJL\e# XFW\n"
|
"App+Spam: \e#WillyJL\e# XFW\n"
|
||||||
"Apple+Crash: \e#ECTO-1A\e#\n"
|
"Apple+Crash: \e#ECTO-1A\e#\n"
|
||||||
"Android+Win: \e#Spooks4576\e#\n"
|
"Android+Win: \e#Spooks4576\e#\n"
|
||||||
" Version \e#3.3\e#",
|
" Version \e#4.1\e#",
|
||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
@@ -355,20 +367,45 @@ static void draw_callback(Canvas* canvas, void* _ctx) {
|
|||||||
char str[32];
|
char str[32];
|
||||||
|
|
||||||
canvas_set_font(canvas, FontBatteryPercent);
|
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.value);
|
||||||
|
} else {
|
||||||
|
snprintf(str, sizeof(str), "%ims", delays[state->delay]);
|
||||||
|
}
|
||||||
canvas_draw_str_aligned(canvas, 116, 12, AlignRight, AlignBottom, str);
|
canvas_draw_str_aligned(canvas, 116, 12, AlignRight, AlignBottom, str);
|
||||||
canvas_draw_icon(canvas, 119, 6, &I_SmallArrowUp_3x5);
|
canvas_draw_icon(canvas, 119, 6, &I_SmallArrowUp_3x5);
|
||||||
canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5);
|
canvas_draw_icon(canvas, 119, 10, &I_SmallArrowDown_3x5);
|
||||||
|
|
||||||
canvas_set_font(canvas, FontBatteryPercent);
|
canvas_set_font(canvas, FontBatteryPercent);
|
||||||
snprintf(
|
if(payload->cfg.mode == ProtocolModeBruteforce) {
|
||||||
str,
|
canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignBottom, "Bruteforce");
|
||||||
sizeof(str),
|
if(delays[state->delay] < 100) {
|
||||||
"%02i/%02i: %s",
|
snprintf(str, sizeof(str), "%ims>", delays[state->delay]);
|
||||||
state->index + 1,
|
} else {
|
||||||
ATTACKS_COUNT,
|
snprintf(str, sizeof(str), "%.1fs>", (double)delays[state->delay] / 1000);
|
||||||
protocol ? protocol->get_name(&payload->cfg) : "Everything AND");
|
}
|
||||||
canvas_draw_str(canvas, 4 - (state->index < 19 ? 1 : 0), 21, str);
|
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, "<Send");
|
||||||
|
canvas_draw_str_aligned(canvas, 122, 22, AlignRight, AlignBottom, str);
|
||||||
|
canvas_invert_color(canvas);
|
||||||
|
} else {
|
||||||
|
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), 22, str);
|
||||||
|
}
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
canvas_draw_str(canvas, 4, 33, attack->title);
|
canvas_draw_str(canvas, 4, 33, attack->title);
|
||||||
@@ -424,6 +461,7 @@ static bool input_callback(InputEvent* input, void* _ctx) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
|
|
||||||
bool is_attack = state->index >= 0 && state->index <= ATTACKS_COUNT - 1;
|
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;
|
bool advertising = state->advertising;
|
||||||
|
|
||||||
switch(input->key) {
|
switch(input->key) {
|
||||||
@@ -440,27 +478,80 @@ static bool input_callback(InputEvent* input, void* _ctx) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyUp:
|
case InputKeyUp:
|
||||||
if(is_attack && state->delay < COUNT_OF(delays) - 1) {
|
if(is_attack) {
|
||||||
state->delay++;
|
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||||
if(advertising) start_blink(state);
|
_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyDown:
|
case InputKeyDown:
|
||||||
if(is_attack && state->delay > 0) {
|
if(is_attack) {
|
||||||
state->delay--;
|
if(_cfg->mode == ProtocolModeBruteforce) {
|
||||||
if(advertising) start_blink(state);
|
_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyLeft:
|
case InputKeyLeft:
|
||||||
if(state->index > PAGE_MIN) {
|
if(input->type == InputTypeLong) {
|
||||||
if(advertising) toggle_adv(state);
|
state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true;
|
||||||
state->index--;
|
}
|
||||||
|
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;
|
break;
|
||||||
case InputKeyRight:
|
case InputKeyRight:
|
||||||
if(state->index < PAGE_MAX) {
|
if(input->type == InputTypeLong) {
|
||||||
if(advertising) toggle_adv(state);
|
state->ignore_bruteforce = _cfg ? (_cfg->mode != ProtocolModeBruteforce) : true;
|
||||||
state->index++;
|
}
|
||||||
|
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 if(input->type == InputTypeLong) {
|
||||||
|
state->delay = (state->delay + 1) % COUNT_OF(delays);
|
||||||
|
if(advertising) start_blink(state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyBack:
|
case InputKeyBack:
|
||||||
@@ -488,9 +579,17 @@ static void lock_timer_callback(void* _ctx) {
|
|||||||
state->lock_count = 0;
|
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) {
|
static bool back_event_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
State* state = _ctx;
|
||||||
return scene_manager_handle_back_event(ctx->scene_manager);
|
return scene_manager_handle_back_event(state->ctx.scene_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ble_spam(void* p) {
|
int32_t ble_spam(void* p) {
|
||||||
@@ -507,7 +606,8 @@ int32_t ble_spam(void* p) {
|
|||||||
Gui* gui = furi_record_open(RECORD_GUI);
|
Gui* gui = furi_record_open(RECORD_GUI);
|
||||||
state->ctx.view_dispatcher = view_dispatcher_alloc();
|
state->ctx.view_dispatcher = view_dispatcher_alloc();
|
||||||
view_dispatcher_enable_queue(state->ctx.view_dispatcher);
|
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);
|
view_dispatcher_set_navigation_event_callback(state->ctx.view_dispatcher, back_event_callback);
|
||||||
state->ctx.scene_manager = scene_manager_alloc(&scene_handlers, &state->ctx);
|
state->ctx.scene_manager = scene_manager_alloc(&scene_handlers, &state->ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
#include <core/core_defines.h>
|
#include <core/core_defines.h>
|
||||||
#include "../ble_spam.h"
|
#include "../ble_spam.h"
|
||||||
|
|
||||||
typedef union ProtocolCfg ProtocolCfg;
|
typedef struct ProtocolCfg ProtocolCfg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const Icon* icon;
|
const Icon* icon;
|
||||||
const char* (*get_name)(const ProtocolCfg* _cfg);
|
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);
|
void (*extra_config)(Ctx* ctx);
|
||||||
uint8_t (*config_count)(const ProtocolCfg* _cfg);
|
uint8_t (*config_count)(const ProtocolCfg* _cfg);
|
||||||
} Protocol;
|
} Protocol;
|
||||||
|
|||||||
@@ -5,11 +5,25 @@
|
|||||||
#include "easysetup.h"
|
#include "easysetup.h"
|
||||||
#include "swiftpair.h"
|
#include "swiftpair.h"
|
||||||
|
|
||||||
union ProtocolCfg {
|
typedef enum {
|
||||||
ContinuityCfg continuity;
|
ProtocolModeRandom,
|
||||||
FastpairCfg fastpair;
|
ProtocolModeValue,
|
||||||
EasysetupCfg easysetup;
|
ProtocolModeBruteforce,
|
||||||
SwiftpairCfg swiftpair;
|
} ProtocolMode;
|
||||||
|
|
||||||
|
struct ProtocolCfg {
|
||||||
|
ProtocolMode mode;
|
||||||
|
struct {
|
||||||
|
uint8_t counter;
|
||||||
|
uint32_t value;
|
||||||
|
uint8_t size;
|
||||||
|
} bruteforce;
|
||||||
|
union {
|
||||||
|
ContinuityCfg continuity;
|
||||||
|
FastpairCfg fastpair;
|
||||||
|
EasysetupCfg easysetup;
|
||||||
|
SwiftpairCfg swiftpair;
|
||||||
|
} specific;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const Protocol* protocols[];
|
extern const Protocol* protocols[];
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ static const char* type_names[ContinuityTypeCOUNT] = {
|
|||||||
[ContinuityTypeNearbyInfo] = "Nearby Info",
|
[ContinuityTypeNearbyInfo] = "Nearby Info",
|
||||||
[ContinuityTypeCustomCrash] = "Continuity Custom",
|
[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;
|
const ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
return type_names[cfg->type];
|
return type_names[cfg->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +87,11 @@ static uint8_t packet_sizes[ContinuityTypeCOUNT] = {
|
|||||||
[ContinuityTypeNearbyInfo] = HEADER_LEN + 5,
|
[ContinuityTypeNearbyInfo] = HEADER_LEN + 5,
|
||||||
[ContinuityTypeCustomCrash] = HEADER_LEN + 11,
|
[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, ProtocolCfg* _cfg) {
|
||||||
const ContinuityCfg* cfg = _cfg ? &_cfg->continuity : NULL;
|
ContinuityCfg* cfg = _cfg ? &_cfg->specific.continuity : NULL;
|
||||||
|
|
||||||
ContinuityType type;
|
ContinuityType type;
|
||||||
if(cfg) {
|
if(cfg && cfg->type != 0x00) {
|
||||||
type = cfg->type;
|
type = cfg->type;
|
||||||
} else {
|
} else {
|
||||||
const ContinuityType types[] = {
|
const ContinuityType types[] = {
|
||||||
@@ -139,14 +139,21 @@ static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const Prot
|
|||||||
|
|
||||||
case ContinuityTypeProximityPair: {
|
case ContinuityTypeProximityPair: {
|
||||||
uint16_t model;
|
uint16_t model;
|
||||||
if(cfg && cfg->data.proximity_pair.model != 0x0000) {
|
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||||
model = cfg->data.proximity_pair.model;
|
case ProtocolModeRandom:
|
||||||
} else {
|
default:
|
||||||
model = pp_models[rand() % pp_models_count].value;
|
model = pp_models[rand() % pp_models_count].value;
|
||||||
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
|
model = cfg->data.proximity_pair.model;
|
||||||
|
break;
|
||||||
|
case ProtocolModeBruteforce:
|
||||||
|
model = cfg->data.proximity_pair.model = _cfg->bruteforce.value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t prefix;
|
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;
|
prefix = cfg->data.proximity_pair.prefix;
|
||||||
} else {
|
} else {
|
||||||
if(model == 0x0055 || model == 0x0030)
|
if(model == 0x0055 || model == 0x0030)
|
||||||
@@ -209,10 +216,17 @@ static void continuity_make_packet(uint8_t* _size, uint8_t** _packet, const Prot
|
|||||||
|
|
||||||
case ContinuityTypeNearbyAction: {
|
case ContinuityTypeNearbyAction: {
|
||||||
uint8_t action;
|
uint8_t action;
|
||||||
if(cfg && cfg->data.nearby_action.action != 0x00) {
|
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||||
action = cfg->data.nearby_action.action;
|
case ProtocolModeRandom:
|
||||||
} else {
|
default:
|
||||||
action = na_actions[rand() % na_actions_count].value;
|
action = na_actions[rand() % na_actions_count].value;
|
||||||
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
|
action = cfg->data.nearby_action.action;
|
||||||
|
break;
|
||||||
|
case ProtocolModeBruteforce:
|
||||||
|
action = cfg->data.nearby_action.action = _cfg->bruteforce.value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
@@ -293,7 +307,8 @@ enum {
|
|||||||
};
|
};
|
||||||
static void config_callback(void* _ctx, uint32_t index) {
|
static void config_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
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);
|
scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
|
||||||
switch(cfg->type) {
|
switch(cfg->type) {
|
||||||
case ContinuityTypeProximityPair: {
|
case ContinuityTypeProximityPair: {
|
||||||
@@ -341,19 +356,22 @@ static void config_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void pp_model_changed(VariableItem* item) {
|
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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.proximity_pair.model = pp_models[index].value;
|
cfg->data.proximity_pair.model = pp_models[index].value;
|
||||||
variable_item_set_current_value_text(item, pp_models[index].name);
|
variable_item_set_current_value_text(item, pp_models[index].name);
|
||||||
} else {
|
} else {
|
||||||
cfg->data.proximity_pair.model = 0x0000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
variable_item_set_current_value_text(item, "Random");
|
variable_item_set_current_value_text(item, "Random");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void pp_prefix_changed(VariableItem* item) {
|
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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
@@ -365,33 +383,39 @@ static void pp_prefix_changed(VariableItem* item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void na_action_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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.nearby_action.action = na_actions[index].value;
|
cfg->data.nearby_action.action = na_actions[index].value;
|
||||||
variable_item_set_current_value_text(item, na_actions[index].name);
|
variable_item_set_current_value_text(item, na_actions[index].name);
|
||||||
} else {
|
} else {
|
||||||
cfg->data.nearby_action.action = 0x00;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
variable_item_set_current_value_text(item, "Random");
|
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;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
VariableItemList* list = ctx->variable_item_list;
|
VariableItemList* list = ctx->variable_item_list;
|
||||||
VariableItem* item;
|
VariableItem* item;
|
||||||
size_t value_index;
|
size_t value_index;
|
||||||
|
|
||||||
switch(cfg->type) {
|
switch(cfg->type) {
|
||||||
case ContinuityTypeProximityPair: {
|
case ContinuityTypeProximityPair: {
|
||||||
item =
|
item = variable_item_list_add(
|
||||||
variable_item_list_add(list, "Model Code", pp_models_count + 1, pp_model_changed, cfg);
|
list, "Model Code", pp_models_count + 1, pp_model_changed, _cfg);
|
||||||
const char* model_name = NULL;
|
const char* model_name = NULL;
|
||||||
char model_name_buf[5];
|
char model_name_buf[5];
|
||||||
if(cfg->data.proximity_pair.model == 0x0000) {
|
switch(_cfg->mode) {
|
||||||
|
case ProtocolModeRandom:
|
||||||
|
default:
|
||||||
model_name = "Random";
|
model_name = "Random";
|
||||||
value_index = 0;
|
value_index = 0;
|
||||||
} else {
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
for(uint8_t i = 0; i < pp_models_count; i++) {
|
for(uint8_t i = 0; i < pp_models_count; i++) {
|
||||||
if(cfg->data.proximity_pair.model == pp_models[i].value) {
|
if(cfg->data.proximity_pair.model == pp_models[i].value) {
|
||||||
model_name = pp_models[i].name;
|
model_name = pp_models[i].name;
|
||||||
@@ -405,12 +429,17 @@ static void continuity_extra_config(Ctx* ctx) {
|
|||||||
model_name = model_name_buf;
|
model_name = model_name_buf;
|
||||||
value_index = pp_models_count + 1;
|
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_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, model_name);
|
variable_item_set_current_value_text(item, model_name);
|
||||||
|
|
||||||
item =
|
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;
|
const char* prefix_name = NULL;
|
||||||
char prefix_name_buf[3];
|
char prefix_name_buf[3];
|
||||||
if(cfg->data.proximity_pair.prefix == 0x00) {
|
if(cfg->data.proximity_pair.prefix == 0x00) {
|
||||||
@@ -440,13 +469,16 @@ static void continuity_extra_config(Ctx* ctx) {
|
|||||||
}
|
}
|
||||||
case ContinuityTypeNearbyAction: {
|
case ContinuityTypeNearbyAction: {
|
||||||
item = variable_item_list_add(
|
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;
|
const char* action_name = NULL;
|
||||||
char action_name_buf[3];
|
char action_name_buf[3];
|
||||||
if(cfg->data.nearby_action.action == 0x00) {
|
switch(_cfg->mode) {
|
||||||
|
case ProtocolModeRandom:
|
||||||
|
default:
|
||||||
action_name = "Random";
|
action_name = "Random";
|
||||||
value_index = 0;
|
value_index = 0;
|
||||||
} else {
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
for(uint8_t i = 0; i < na_actions_count; i++) {
|
for(uint8_t i = 0; i < na_actions_count; i++) {
|
||||||
if(cfg->data.nearby_action.action == na_actions[i].value) {
|
if(cfg->data.nearby_action.action == na_actions[i].value) {
|
||||||
action_name = na_actions[i].name;
|
action_name = na_actions[i].name;
|
||||||
@@ -463,6 +495,11 @@ static void continuity_extra_config(Ctx* ctx) {
|
|||||||
action_name = action_name_buf;
|
action_name = action_name_buf;
|
||||||
value_index = na_actions_count + 1;
|
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_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, action_name);
|
variable_item_set_current_value_text(item, action_name);
|
||||||
@@ -502,31 +539,40 @@ static uint8_t config_counts[ContinuityTypeCOUNT] = {
|
|||||||
[ContinuityTypeNearbyInfo] = 0,
|
[ContinuityTypeNearbyInfo] = 0,
|
||||||
[ContinuityTypeCustomCrash] = ConfigCcCOUNT - ConfigExtraStart - 1,
|
[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;
|
const ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
return config_counts[cfg->type];
|
return config_counts[cfg->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Protocol protocol_continuity = {
|
const Protocol protocol_continuity = {
|
||||||
.icon = &I_apple,
|
.icon = &I_apple,
|
||||||
.get_name = continuity_get_name,
|
.get_name = get_name,
|
||||||
.make_packet = continuity_make_packet,
|
.make_packet = make_packet,
|
||||||
.extra_config = continuity_extra_config,
|
.extra_config = extra_config,
|
||||||
.config_count = continuity_config_count,
|
.config_count = config_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pp_model_callback(void* _ctx, uint32_t index) {
|
static void pp_model_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->data.proximity_pair.model = 0x0000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
case pp_models_count + 1:
|
case pp_models_count + 1:
|
||||||
scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModelCustom);
|
scene_manager_next_scene(ctx->scene_manager, SceneContinuityPpModelCustom);
|
||||||
break;
|
break;
|
||||||
|
case pp_models_count + 2:
|
||||||
|
_cfg->mode = ProtocolModeBruteforce;
|
||||||
|
_cfg->bruteforce.counter = 0;
|
||||||
|
_cfg->bruteforce.value = cfg->data.proximity_pair.model;
|
||||||
|
_cfg->bruteforce.size = 2;
|
||||||
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.proximity_pair.model = pp_models[index - 1].value;
|
cfg->data.proximity_pair.model = pp_models[index - 1].value;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
@@ -534,30 +580,36 @@ static void pp_model_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_continuity_pp_model_on_enter(void* _ctx) {
|
void scene_continuity_pp_model_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
|
||||||
submenu_reset(submenu);
|
submenu_reset(submenu);
|
||||||
|
|
||||||
submenu_add_item(submenu, "Random", 0, pp_model_callback, ctx);
|
submenu_add_item(submenu, "Random", 0, pp_model_callback, ctx);
|
||||||
if(cfg->data.proximity_pair.model == 0x0000) {
|
if(_cfg->mode == ProtocolModeRandom) {
|
||||||
found = true;
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for(uint8_t i = 0; i < pp_models_count; i++) {
|
for(uint8_t i = 0; i < pp_models_count; i++) {
|
||||||
submenu_add_item(submenu, pp_models[i].name, i + 1, pp_model_callback, ctx);
|
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;
|
found = true;
|
||||||
selected = i + 1;
|
selected = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", pp_models_count + 1, pp_model_callback, ctx);
|
submenu_add_item(submenu, "Custom", pp_models_count + 1, pp_model_callback, ctx);
|
||||||
if(!found) {
|
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||||
found = true;
|
|
||||||
selected = pp_models_count + 1;
|
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);
|
submenu_set_selected_item(submenu, selected);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||||
@@ -573,12 +625,17 @@ void scene_continuity_pp_model_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void pp_model_custom_callback(void* _ctx) {
|
static void pp_model_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_continuity_pp_model_custom_on_enter(void* _ctx) {
|
void scene_continuity_pp_model_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||||
@@ -597,14 +654,13 @@ bool scene_continuity_pp_model_custom_on_event(void* _ctx, SceneManagerEvent eve
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_continuity_pp_model_custom_on_exit(void* _ctx) {
|
void scene_continuity_pp_model_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_ctx);
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
|
||||||
cfg->data.proximity_pair.model = (ctx->byte_store[0] << 0x08) + (ctx->byte_store[1] << 0x00);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pp_prefix_callback(void* _ctx, uint32_t index) {
|
static void pp_prefix_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->data.proximity_pair.prefix = 0x00;
|
cfg->data.proximity_pair.prefix = 0x00;
|
||||||
@@ -621,7 +677,8 @@ static void pp_prefix_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -632,6 +689,7 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
|||||||
found = true;
|
found = true;
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint8_t i = 0; i < pp_prefixes_count; i++) {
|
for(uint8_t i = 0; i < pp_prefixes_count; i++) {
|
||||||
submenu_add_item(submenu, pp_prefixes[i].name, i + 1, pp_prefix_callback, ctx);
|
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) {
|
if(!found && cfg->data.proximity_pair.prefix == pp_prefixes[i].value) {
|
||||||
@@ -641,7 +699,6 @@ void scene_continuity_pp_prefix_on_enter(void* _ctx) {
|
|||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", pp_prefixes_count + 1, pp_prefix_callback, ctx);
|
submenu_add_item(submenu, "Custom", pp_prefixes_count + 1, pp_prefix_callback, ctx);
|
||||||
if(!found) {
|
if(!found) {
|
||||||
found = true;
|
|
||||||
selected = pp_prefixes_count + 1;
|
selected = pp_prefixes_count + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,12 +717,16 @@ void scene_continuity_pp_prefix_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void pp_prefix_custom_callback(void* _ctx) {
|
static void pp_prefix_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_continuity_pp_prefix_custom_on_enter(void* _ctx) {
|
void scene_continuity_pp_prefix_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Prefix");
|
byte_input_set_header_text(byte_input, "Enter custom Prefix");
|
||||||
@@ -683,23 +744,30 @@ bool scene_continuity_pp_prefix_custom_on_event(void* _ctx, SceneManagerEvent ev
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) {
|
void scene_continuity_pp_prefix_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_ctx);
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
|
||||||
cfg->data.proximity_pair.prefix = (ctx->byte_store[0] << 0x00);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void na_action_callback(void* _ctx, uint32_t index) {
|
static void na_action_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
ContinuityCfg* cfg = &_cfg->specific.continuity;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->data.nearby_action.action = 0x00;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
case na_actions_count + 1:
|
case na_actions_count + 1:
|
||||||
scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaActionCustom);
|
scene_manager_next_scene(ctx->scene_manager, SceneContinuityNaActionCustom);
|
||||||
break;
|
break;
|
||||||
|
case na_actions_count + 2:
|
||||||
|
_cfg->mode = ProtocolModeBruteforce;
|
||||||
|
_cfg->bruteforce.counter = 0;
|
||||||
|
_cfg->bruteforce.value = cfg->data.nearby_action.action;
|
||||||
|
_cfg->bruteforce.size = 1;
|
||||||
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.nearby_action.action = na_actions[index - 1].value;
|
cfg->data.nearby_action.action = na_actions[index - 1].value;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
@@ -707,30 +775,36 @@ static void na_action_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_continuity_na_action_on_enter(void* _ctx) {
|
void scene_continuity_na_action_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
|
||||||
submenu_reset(submenu);
|
submenu_reset(submenu);
|
||||||
|
|
||||||
submenu_add_item(submenu, "Random", 0, na_action_callback, ctx);
|
submenu_add_item(submenu, "Random", 0, na_action_callback, ctx);
|
||||||
if(cfg->data.nearby_action.action == 0x00) {
|
if(_cfg->mode == ProtocolModeRandom) {
|
||||||
found = true;
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for(uint8_t i = 0; i < na_actions_count; i++) {
|
for(uint8_t i = 0; i < na_actions_count; i++) {
|
||||||
submenu_add_item(submenu, na_actions[i].name, i + 1, na_action_callback, ctx);
|
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;
|
found = true;
|
||||||
selected = i + 1;
|
selected = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", na_actions_count + 1, na_action_callback, ctx);
|
submenu_add_item(submenu, "Custom", na_actions_count + 1, na_action_callback, ctx);
|
||||||
if(!found) {
|
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||||
found = true;
|
|
||||||
selected = na_actions_count + 1;
|
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);
|
submenu_set_selected_item(submenu, selected);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||||
@@ -746,12 +820,17 @@ void scene_continuity_na_action_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void na_action_custom_callback(void* _ctx) {
|
static void na_action_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_continuity_na_action_custom_on_enter(void* _ctx) {
|
void scene_continuity_na_action_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Action Type");
|
byte_input_set_header_text(byte_input, "Enter custom Action Type");
|
||||||
@@ -769,9 +848,7 @@ bool scene_continuity_na_action_custom_on_event(void* _ctx, SceneManagerEvent ev
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_continuity_na_action_custom_on_exit(void* _ctx) {
|
void scene_continuity_na_action_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_ctx);
|
||||||
ContinuityCfg* cfg = &ctx->attack->payload.cfg.continuity;
|
|
||||||
cfg->data.nearby_action.action = (ctx->byte_store[0] << 0x00);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void na_flags_callback(void* _ctx) {
|
static void na_flags_callback(void* _ctx) {
|
||||||
@@ -780,7 +857,8 @@ static void na_flags_callback(void* _ctx) {
|
|||||||
}
|
}
|
||||||
void scene_continuity_na_flags_on_enter(void* _ctx) {
|
void scene_continuity_na_flags_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Press back for automatic");
|
byte_input_set_header_text(byte_input, "Press back for automatic");
|
||||||
@@ -801,6 +879,7 @@ bool scene_continuity_na_flags_on_event(void* _ctx, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
void scene_continuity_na_flags_on_exit(void* _ctx) {
|
void scene_continuity_na_flags_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _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);
|
cfg->data.nearby_action.flags = (ctx->byte_store[0] << 0x00);
|
||||||
}
|
}
|
||||||
|
|||||||
202
applications/external/ble_spam/protocols/easysetup.c
vendored
202
applications/external/ble_spam/protocols/easysetup.c
vendored
@@ -36,9 +36,9 @@ const struct {
|
|||||||
const char* name;
|
const char* name;
|
||||||
} watch_models[] = {
|
} watch_models[] = {
|
||||||
{0x1A, "Fallback Watch"},
|
{0x1A, "Fallback Watch"},
|
||||||
{0x01, "White Watch4 Classic 44"},
|
{0x01, "White Watch4 Classic 44m"},
|
||||||
{0x02, "Black Watch4 Classic 40"},
|
{0x02, "Black Watch4 Classic 40m"},
|
||||||
{0x03, "White Watch4 Classic 40"},
|
{0x03, "White Watch4 Classic 40m"},
|
||||||
{0x04, "Black Watch4 44mm"},
|
{0x04, "Black Watch4 44mm"},
|
||||||
{0x05, "Silver Watch4 44mm"},
|
{0x05, "Silver Watch4 44mm"},
|
||||||
{0x06, "Green Watch4 44mm"},
|
{0x06, "Green Watch4 44mm"},
|
||||||
@@ -59,8 +59,8 @@ const struct {
|
|||||||
{0x1B, "Black Watch6 Pink 40mm"},
|
{0x1B, "Black Watch6 Pink 40mm"},
|
||||||
{0x1C, "Gold Watch6 Gold 40mm"},
|
{0x1C, "Gold Watch6 Gold 40mm"},
|
||||||
{0x1D, "Silver Watch6 Cyan 44mm"},
|
{0x1D, "Silver Watch6 Cyan 44mm"},
|
||||||
{0x1E, "Black Watch6 Classic 43mm"},
|
{0x1E, "Black Watch6 Classic 43m"},
|
||||||
{0x20, "Green Watch6 Classic 43mm"},
|
{0x20, "Green Watch6 Classic 43m"},
|
||||||
};
|
};
|
||||||
const uint8_t watch_models_count = COUNT_OF(watch_models);
|
const uint8_t watch_models_count = COUNT_OF(watch_models);
|
||||||
|
|
||||||
@@ -68,8 +68,8 @@ static const char* type_names[EasysetupTypeCOUNT] = {
|
|||||||
[EasysetupTypeBuds] = "EasySetup Buds",
|
[EasysetupTypeBuds] = "EasySetup Buds",
|
||||||
[EasysetupTypeWatch] = "EasySetup Watch",
|
[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;
|
const EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||||
return type_names[cfg->type];
|
return type_names[cfg->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,14 +77,18 @@ static uint8_t packet_sizes[EasysetupTypeCOUNT] = {
|
|||||||
[EasysetupTypeBuds] = 31,
|
[EasysetupTypeBuds] = 31,
|
||||||
[EasysetupTypeWatch] = 15,
|
[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, ProtocolCfg* _cfg) {
|
||||||
const EasysetupCfg* cfg = _cfg ? &_cfg->easysetup : NULL;
|
EasysetupCfg* cfg = _cfg ? &_cfg->specific.easysetup : NULL;
|
||||||
|
|
||||||
EasysetupType type;
|
EasysetupType type;
|
||||||
if(cfg) {
|
if(cfg && cfg->type != 0x00) {
|
||||||
type = cfg->type;
|
type = cfg->type;
|
||||||
} else {
|
} else {
|
||||||
type = rand() % EasysetupTypeCOUNT;
|
const EasysetupType types[] = {
|
||||||
|
EasysetupTypeBuds,
|
||||||
|
EasysetupTypeWatch,
|
||||||
|
};
|
||||||
|
type = types[rand() % COUNT_OF(types)];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t size = packet_sizes[type];
|
uint8_t size = packet_sizes[type];
|
||||||
@@ -94,10 +98,17 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case EasysetupTypeBuds: {
|
case EasysetupTypeBuds: {
|
||||||
uint32_t model;
|
uint32_t model;
|
||||||
if(cfg && cfg->data.buds.model != 0x000000) {
|
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||||
model = cfg->data.buds.model;
|
case ProtocolModeRandom:
|
||||||
} else {
|
default:
|
||||||
model = buds_models[rand() % buds_models_count].value;
|
model = buds_models[rand() % buds_models_count].value;
|
||||||
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
|
model = cfg->data.buds.model;
|
||||||
|
break;
|
||||||
|
case ProtocolModeBruteforce:
|
||||||
|
model = cfg->data.buds.model = _cfg->bruteforce.value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet[i++] = 27; // Size
|
packet[i++] = 27; // Size
|
||||||
@@ -137,10 +148,17 @@ void easysetup_make_packet(uint8_t* out_size, uint8_t** out_packet, const Protoc
|
|||||||
}
|
}
|
||||||
case EasysetupTypeWatch: {
|
case EasysetupTypeWatch: {
|
||||||
uint8_t model;
|
uint8_t model;
|
||||||
if(cfg && cfg->data.watch.model != 0x00) {
|
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||||
model = cfg->data.watch.model;
|
case ProtocolModeRandom:
|
||||||
} else {
|
default:
|
||||||
model = watch_models[rand() % watch_models_count].value;
|
model = watch_models[rand() % watch_models_count].value;
|
||||||
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
|
model = cfg->data.watch.model;
|
||||||
|
break;
|
||||||
|
case ProtocolModeBruteforce:
|
||||||
|
model = cfg->data.watch.model = _cfg->bruteforce.value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet[i++] = 14; // Size
|
packet[i++] = 14; // Size
|
||||||
@@ -181,7 +199,8 @@ enum {
|
|||||||
};
|
};
|
||||||
static void config_callback(void* _ctx, uint32_t index) {
|
static void config_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
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);
|
scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
|
||||||
switch(cfg->type) {
|
switch(cfg->type) {
|
||||||
case EasysetupTypeBuds: {
|
case EasysetupTypeBuds: {
|
||||||
@@ -214,31 +233,36 @@ static void config_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void buds_model_changed(VariableItem* item) {
|
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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.buds.model = buds_models[index].value;
|
cfg->data.buds.model = buds_models[index].value;
|
||||||
variable_item_set_current_value_text(item, buds_models[index].name);
|
variable_item_set_current_value_text(item, buds_models[index].name);
|
||||||
} else {
|
} else {
|
||||||
cfg->data.buds.model = 0x000000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
variable_item_set_current_value_text(item, "Random");
|
variable_item_set_current_value_text(item, "Random");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void watch_model_changed(VariableItem* item) {
|
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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.watch.model = watch_models[index].value;
|
cfg->data.watch.model = watch_models[index].value;
|
||||||
variable_item_set_current_value_text(item, watch_models[index].name);
|
variable_item_set_current_value_text(item, watch_models[index].name);
|
||||||
} else {
|
} else {
|
||||||
cfg->data.watch.model = 0x00;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
variable_item_set_current_value_text(item, "Random");
|
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;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||||
VariableItemList* list = ctx->variable_item_list;
|
VariableItemList* list = ctx->variable_item_list;
|
||||||
VariableItem* item;
|
VariableItem* item;
|
||||||
size_t value_index;
|
size_t value_index;
|
||||||
@@ -246,13 +270,16 @@ static void easysetup_extra_config(Ctx* ctx) {
|
|||||||
switch(cfg->type) {
|
switch(cfg->type) {
|
||||||
case EasysetupTypeBuds: {
|
case EasysetupTypeBuds: {
|
||||||
item = variable_item_list_add(
|
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;
|
const char* model_name = NULL;
|
||||||
char model_name_buf[9];
|
char model_name_buf[9];
|
||||||
if(cfg->data.buds.model == 0x000000) {
|
switch(_cfg->mode) {
|
||||||
|
case ProtocolModeRandom:
|
||||||
|
default:
|
||||||
model_name = "Random";
|
model_name = "Random";
|
||||||
value_index = 0;
|
value_index = 0;
|
||||||
} else {
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
for(uint8_t i = 0; i < buds_models_count; i++) {
|
for(uint8_t i = 0; i < buds_models_count; i++) {
|
||||||
if(cfg->data.buds.model == buds_models[i].value) {
|
if(cfg->data.buds.model == buds_models[i].value) {
|
||||||
model_name = buds_models[i].name;
|
model_name = buds_models[i].name;
|
||||||
@@ -265,6 +292,11 @@ static void easysetup_extra_config(Ctx* ctx) {
|
|||||||
model_name = model_name_buf;
|
model_name = model_name_buf;
|
||||||
value_index = buds_models_count + 1;
|
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_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, model_name);
|
variable_item_set_current_value_text(item, model_name);
|
||||||
@@ -274,13 +306,16 @@ static void easysetup_extra_config(Ctx* ctx) {
|
|||||||
}
|
}
|
||||||
case EasysetupTypeWatch: {
|
case EasysetupTypeWatch: {
|
||||||
item = variable_item_list_add(
|
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;
|
const char* model_name = NULL;
|
||||||
char model_name_buf[3];
|
char model_name_buf[3];
|
||||||
if(cfg->data.watch.model == 0x00) {
|
switch(_cfg->mode) {
|
||||||
|
case ProtocolModeRandom:
|
||||||
|
default:
|
||||||
model_name = "Random";
|
model_name = "Random";
|
||||||
value_index = 0;
|
value_index = 0;
|
||||||
} else {
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
for(uint8_t i = 0; i < watch_models_count; i++) {
|
for(uint8_t i = 0; i < watch_models_count; i++) {
|
||||||
if(cfg->data.watch.model == watch_models[i].value) {
|
if(cfg->data.watch.model == watch_models[i].value) {
|
||||||
model_name = watch_models[i].name;
|
model_name = watch_models[i].name;
|
||||||
@@ -293,6 +328,11 @@ static void easysetup_extra_config(Ctx* ctx) {
|
|||||||
model_name = model_name_buf;
|
model_name = model_name_buf;
|
||||||
value_index = watch_models_count + 1;
|
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_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, model_name);
|
variable_item_set_current_value_text(item, model_name);
|
||||||
@@ -309,31 +349,40 @@ static uint8_t config_counts[EasysetupTypeCOUNT] = {
|
|||||||
[EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1,
|
[EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1,
|
||||||
[EasysetupTypeWatch] = ConfigWatchCOUNT - 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;
|
const EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||||
return config_counts[cfg->type];
|
return config_counts[cfg->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Protocol protocol_easysetup = {
|
const Protocol protocol_easysetup = {
|
||||||
.icon = &I_android,
|
.icon = &I_android,
|
||||||
.get_name = easysetup_get_name,
|
.get_name = get_name,
|
||||||
.make_packet = easysetup_make_packet,
|
.make_packet = make_packet,
|
||||||
.extra_config = easysetup_extra_config,
|
.extra_config = extra_config,
|
||||||
.config_count = easysetup_config_count,
|
.config_count = config_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void buds_model_callback(void* _ctx, uint32_t index) {
|
static void buds_model_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->data.buds.model = 0x000000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
case buds_models_count + 1:
|
case buds_models_count + 1:
|
||||||
scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom);
|
scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom);
|
||||||
break;
|
break;
|
||||||
|
case buds_models_count + 2:
|
||||||
|
_cfg->mode = ProtocolModeBruteforce;
|
||||||
|
_cfg->bruteforce.counter = 0;
|
||||||
|
_cfg->bruteforce.value = cfg->data.buds.model;
|
||||||
|
_cfg->bruteforce.size = 3;
|
||||||
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.buds.model = buds_models[index - 1].value;
|
cfg->data.buds.model = buds_models[index - 1].value;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
@@ -341,30 +390,36 @@ static void buds_model_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_easysetup_buds_model_on_enter(void* _ctx) {
|
void scene_easysetup_buds_model_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
|
||||||
submenu_reset(submenu);
|
submenu_reset(submenu);
|
||||||
|
|
||||||
submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx);
|
submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx);
|
||||||
if(cfg->data.buds.model == 0x000000) {
|
if(_cfg->mode == ProtocolModeRandom) {
|
||||||
found = true;
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for(uint8_t i = 0; i < buds_models_count; i++) {
|
for(uint8_t i = 0; i < buds_models_count; i++) {
|
||||||
submenu_add_item(submenu, buds_models[i].name, i + 1, buds_model_callback, ctx);
|
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;
|
found = true;
|
||||||
selected = i + 1;
|
selected = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", buds_models_count + 1, buds_model_callback, ctx);
|
submenu_add_item(submenu, "Custom", buds_models_count + 1, buds_model_callback, ctx);
|
||||||
if(!found) {
|
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||||
found = true;
|
|
||||||
selected = buds_models_count + 1;
|
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);
|
submenu_set_selected_item(submenu, selected);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||||
@@ -380,12 +435,18 @@ void scene_easysetup_buds_model_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void buds_model_custom_callback(void* _ctx) {
|
static void buds_model_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_easysetup_buds_model_custom_on_enter(void* _ctx) {
|
void scene_easysetup_buds_model_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||||
@@ -405,24 +466,30 @@ bool scene_easysetup_buds_model_custom_on_event(void* _ctx, SceneManagerEvent ev
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_easysetup_buds_model_custom_on_exit(void* _ctx) {
|
void scene_easysetup_buds_model_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void watch_model_callback(void* _ctx, uint32_t index) {
|
static void watch_model_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
EasysetupCfg* cfg = &_cfg->specific.easysetup;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->data.watch.model = 0x00;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
case watch_models_count + 1:
|
case watch_models_count + 1:
|
||||||
scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom);
|
scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom);
|
||||||
break;
|
break;
|
||||||
|
case watch_models_count + 2:
|
||||||
|
_cfg->mode = ProtocolModeBruteforce;
|
||||||
|
_cfg->bruteforce.counter = 0;
|
||||||
|
_cfg->bruteforce.value = cfg->data.watch.model;
|
||||||
|
_cfg->bruteforce.size = 1;
|
||||||
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->data.watch.model = watch_models[index - 1].value;
|
cfg->data.watch.model = watch_models[index - 1].value;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
@@ -430,30 +497,36 @@ static void watch_model_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_easysetup_watch_model_on_enter(void* _ctx) {
|
void scene_easysetup_watch_model_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
|
||||||
submenu_reset(submenu);
|
submenu_reset(submenu);
|
||||||
|
|
||||||
submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx);
|
submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx);
|
||||||
if(cfg->data.watch.model == 0x00) {
|
if(_cfg->mode == ProtocolModeRandom) {
|
||||||
found = true;
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for(uint8_t i = 0; i < watch_models_count; i++) {
|
for(uint8_t i = 0; i < watch_models_count; i++) {
|
||||||
submenu_add_item(submenu, watch_models[i].name, i + 1, watch_model_callback, ctx);
|
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;
|
found = true;
|
||||||
selected = i + 1;
|
selected = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", watch_models_count + 1, watch_model_callback, ctx);
|
submenu_add_item(submenu, "Custom", watch_models_count + 1, watch_model_callback, ctx);
|
||||||
if(!found) {
|
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||||
found = true;
|
|
||||||
selected = watch_models_count + 1;
|
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);
|
submenu_set_selected_item(submenu, selected);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||||
@@ -469,12 +542,17 @@ void scene_easysetup_watch_model_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void watch_model_custom_callback(void* _ctx) {
|
static void watch_model_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_easysetup_watch_model_custom_on_enter(void* _ctx) {
|
void scene_easysetup_watch_model_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||||
@@ -492,7 +570,5 @@ bool scene_easysetup_watch_model_custom_on_event(void* _ctx, SceneManagerEvent e
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_easysetup_watch_model_custom_on_exit(void* _ctx) {
|
void scene_easysetup_watch_model_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_ctx);
|
||||||
EasysetupCfg* cfg = &ctx->attack->payload.cfg.easysetup;
|
|
||||||
cfg->data.watch.model = (ctx->byte_store[0] << 0x00);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
// Research by @Spooks4576
|
// Research by @Spooks4576
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EasysetupTypeBuds,
|
EasysetupTypeBuds = 0x01, // Skip 0 as it means unset
|
||||||
EasysetupTypeWatch,
|
EasysetupTypeWatch,
|
||||||
EasysetupTypeCOUNT,
|
EasysetupTypeCOUNT,
|
||||||
} EasysetupType;
|
} EasysetupType;
|
||||||
|
|||||||
127
applications/external/ble_spam/protocols/fastpair.c
vendored
127
applications/external/ble_spam/protocols/fastpair.c
vendored
@@ -8,17 +8,43 @@ const struct {
|
|||||||
uint32_t value;
|
uint32_t value;
|
||||||
const char* name;
|
const char* name;
|
||||||
} models[] = {
|
} models[] = {
|
||||||
|
// Genuine actions
|
||||||
|
{0x00000C, "Set Up Device"},
|
||||||
|
|
||||||
|
// 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
|
// Genuine devices
|
||||||
{0xCD8256, "Bose NC 700"},
|
{0xCD8256, "Bose NC 700"},
|
||||||
|
{0x0000F0, "Bose QuietComfort 35 II"},
|
||||||
|
{0x821F66, "JBL Flip 6"},
|
||||||
{0xF52494, "JBL Buds Pro"},
|
{0xF52494, "JBL Buds Pro"},
|
||||||
{0x718FA4, "JBL Live 300TWS"},
|
{0x718FA4, "JBL Live 300TWS"},
|
||||||
{0x821F66, "JBL Flip 6"},
|
{0x0002F0, "JBL Everest 110GA"},
|
||||||
{0x92BBBD, "Pixel Buds"},
|
{0x92BBBD, "Pixel Buds"},
|
||||||
|
{0x000006, "Google Pixel buds"},
|
||||||
|
{0x060000, "Google Pixel buds 2"},
|
||||||
{0xD446A7, "Sony XM5"},
|
{0xD446A7, "Sony XM5"},
|
||||||
{0x2D7A23, "Sony WF-1000XM4"},
|
{0x2D7A23, "Sony WF-1000XM4"},
|
||||||
{0x0E30C3, "Razer Hammerhead TWS"},
|
{0x0E30C3, "Razer Hammerhead TWS"},
|
||||||
{0x72EF8D, "Razer Hammerhead TWS X"},
|
{0x72EF8D, "Razer Hammerhead TWS X"},
|
||||||
{0x72FB00, "Soundcore Spirit Pro GVA"},
|
{0x72FB00, "Soundcore Spirit Pro GVA"},
|
||||||
|
{0x0003F0, "LG HBS-835S"},
|
||||||
|
|
||||||
// Custom debug popups
|
// Custom debug popups
|
||||||
{0xD99CA1, "Flipper Zero"},
|
{0xD99CA1, "Flipper Zero"},
|
||||||
@@ -39,19 +65,26 @@ const struct {
|
|||||||
};
|
};
|
||||||
const uint8_t models_count = COUNT_OF(models);
|
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);
|
UNUSED(_cfg);
|
||||||
return "FastPair";
|
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, ProtocolCfg* _cfg) {
|
||||||
const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL;
|
FastpairCfg* cfg = _cfg ? &_cfg->specific.fastpair : NULL;
|
||||||
|
|
||||||
uint32_t model;
|
uint32_t model;
|
||||||
if(cfg && cfg->model != 0x000000) {
|
switch(cfg ? _cfg->mode : ProtocolModeRandom) {
|
||||||
model = cfg->model;
|
case ProtocolModeRandom:
|
||||||
} else {
|
default:
|
||||||
model = models[rand() % models_count].value;
|
model = models[rand() % models_count].value;
|
||||||
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
|
model = cfg->model;
|
||||||
|
break;
|
||||||
|
case ProtocolModeBruteforce:
|
||||||
|
model = cfg->model = _cfg->bruteforce.value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t size = 14;
|
uint8_t size = 14;
|
||||||
@@ -100,30 +133,36 @@ static void config_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void model_changed(VariableItem* item) {
|
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);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
if(index) {
|
if(index) {
|
||||||
index--;
|
index--;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->model = models[index].value;
|
cfg->model = models[index].value;
|
||||||
variable_item_set_current_value_text(item, models[index].name);
|
variable_item_set_current_value_text(item, models[index].name);
|
||||||
} else {
|
} else {
|
||||||
cfg->model = 0x000000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
variable_item_set_current_value_text(item, "Random");
|
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;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||||
VariableItemList* list = ctx->variable_item_list;
|
VariableItemList* list = ctx->variable_item_list;
|
||||||
VariableItem* item;
|
VariableItem* item;
|
||||||
size_t value_index;
|
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;
|
const char* model_name = NULL;
|
||||||
char model_name_buf[9];
|
char model_name_buf[9];
|
||||||
if(cfg->model == 0x000000) {
|
switch(_cfg->mode) {
|
||||||
|
case ProtocolModeRandom:
|
||||||
|
default:
|
||||||
model_name = "Random";
|
model_name = "Random";
|
||||||
value_index = 0;
|
value_index = 0;
|
||||||
} else {
|
break;
|
||||||
|
case ProtocolModeValue:
|
||||||
for(uint8_t i = 0; i < models_count; i++) {
|
for(uint8_t i = 0; i < models_count; i++) {
|
||||||
if(cfg->model == models[i].value) {
|
if(cfg->model == models[i].value) {
|
||||||
model_name = models[i].name;
|
model_name = models[i].name;
|
||||||
@@ -136,6 +175,11 @@ static void fastpair_extra_config(Ctx* ctx) {
|
|||||||
model_name = model_name_buf;
|
model_name = model_name_buf;
|
||||||
value_index = models_count + 1;
|
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_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, model_name);
|
variable_item_set_current_value_text(item, model_name);
|
||||||
@@ -145,31 +189,40 @@ static void fastpair_extra_config(Ctx* ctx) {
|
|||||||
variable_item_list_set_enter_callback(list, config_callback, 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);
|
UNUSED(_cfg);
|
||||||
return ConfigCOUNT - ConfigExtraStart - 1;
|
return ConfigCOUNT - ConfigExtraStart - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Protocol protocol_fastpair = {
|
const Protocol protocol_fastpair = {
|
||||||
.icon = &I_android,
|
.icon = &I_android,
|
||||||
.get_name = fastpair_get_name,
|
.get_name = get_name,
|
||||||
.make_packet = fastpair_make_packet,
|
.make_packet = make_packet,
|
||||||
.extra_config = fastpair_extra_config,
|
.extra_config = extra_config,
|
||||||
.config_count = fastpair_config_count,
|
.config_count = config_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void model_callback(void* _ctx, uint32_t index) {
|
static void model_callback(void* _ctx, uint32_t index) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
FastpairCfg* cfg = &_cfg->specific.fastpair;
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg->model = 0x000000;
|
_cfg->mode = ProtocolModeRandom;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
case models_count + 1:
|
case models_count + 1:
|
||||||
scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom);
|
scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom);
|
||||||
break;
|
break;
|
||||||
|
case models_count + 2:
|
||||||
|
_cfg->mode = ProtocolModeBruteforce;
|
||||||
|
_cfg->bruteforce.counter = 0;
|
||||||
|
_cfg->bruteforce.value = cfg->model;
|
||||||
|
_cfg->bruteforce.size = 3;
|
||||||
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
cfg->model = models[index - 1].value;
|
cfg->model = models[index - 1].value;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
break;
|
break;
|
||||||
@@ -177,30 +230,35 @@ static void model_callback(void* _ctx, uint32_t index) {
|
|||||||
}
|
}
|
||||||
void scene_fastpair_model_on_enter(void* _ctx) {
|
void scene_fastpair_model_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
Submenu* submenu = ctx->submenu;
|
||||||
uint32_t selected = 0;
|
uint32_t selected = 0;
|
||||||
bool found = false;
|
|
||||||
submenu_reset(submenu);
|
submenu_reset(submenu);
|
||||||
|
|
||||||
submenu_add_item(submenu, "Random", 0, model_callback, ctx);
|
submenu_add_item(submenu, "Random", 0, model_callback, ctx);
|
||||||
if(cfg->model == 0x000000) {
|
if(_cfg->mode == ProtocolModeRandom) {
|
||||||
found = true;
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for(uint8_t i = 0; i < models_count; i++) {
|
for(uint8_t i = 0; i < models_count; i++) {
|
||||||
submenu_add_item(submenu, models[i].name, i + 1, model_callback, ctx);
|
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;
|
found = true;
|
||||||
selected = i + 1;
|
selected = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx);
|
submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx);
|
||||||
if(!found) {
|
if(!found && _cfg->mode == ProtocolModeValue) {
|
||||||
found = true;
|
|
||||||
selected = models_count + 1;
|
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);
|
submenu_set_selected_item(submenu, selected);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
|
||||||
@@ -216,12 +274,18 @@ void scene_fastpair_model_on_exit(void* _ctx) {
|
|||||||
|
|
||||||
static void model_custom_callback(void* _ctx) {
|
static void model_custom_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
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);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_fastpair_model_custom_on_enter(void* _ctx) {
|
void scene_fastpair_model_custom_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
ByteInput* byte_input = ctx->byte_input;
|
||||||
|
|
||||||
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
byte_input_set_header_text(byte_input, "Enter custom Model Code");
|
||||||
@@ -241,8 +305,5 @@ bool scene_fastpair_model_custom_on_event(void* _ctx, SceneManagerEvent event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_fastpair_model_custom_on_exit(void* _ctx) {
|
void scene_fastpair_model_custom_on_exit(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
UNUSED(_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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,27 +4,33 @@
|
|||||||
// Hacked together by @Willy-JL and @Spooks4576
|
// Hacked together by @Willy-JL and @Spooks4576
|
||||||
// Documentation at https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/bluetooth-swift-pair
|
// 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) {
|
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);
|
UNUSED(_cfg);
|
||||||
return "SwiftPair";
|
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, ProtocolCfg* _cfg) {
|
||||||
const SwiftpairCfg* cfg = _cfg ? &_cfg->swiftpair : NULL;
|
SwiftpairCfg* cfg = _cfg ? &_cfg->specific.swiftpair : NULL;
|
||||||
|
|
||||||
const char* name;
|
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;
|
name = cfg->name;
|
||||||
} else {
|
break;
|
||||||
const char* names[] = {
|
|
||||||
"Assquach💦",
|
|
||||||
"Flipper 🐬",
|
|
||||||
"iOS 17 🍎",
|
|
||||||
"Kink💦",
|
|
||||||
"👉👌",
|
|
||||||
"🔵🦷",
|
|
||||||
};
|
|
||||||
name = names[rand() % COUNT_OF(names)];
|
|
||||||
}
|
}
|
||||||
uint8_t name_len = strlen(name);
|
uint8_t name_len = strlen(name);
|
||||||
|
|
||||||
@@ -66,43 +72,48 @@ static void config_callback(void* _ctx, uint32_t index) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void swiftpair_extra_config(Ctx* ctx) {
|
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;
|
VariableItemList* list = ctx->variable_item_list;
|
||||||
VariableItem* item;
|
VariableItem* item;
|
||||||
|
|
||||||
item = variable_item_list_add(list, "Display Name", 0, NULL, NULL);
|
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);
|
variable_item_list_add(list, "Requires enabling SwiftPair", 0, NULL, NULL);
|
||||||
|
|
||||||
variable_item_list_set_enter_callback(list, config_callback, 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);
|
UNUSED(_cfg);
|
||||||
return ConfigCOUNT - ConfigExtraStart - 1;
|
return ConfigCOUNT - ConfigExtraStart - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Protocol protocol_swiftpair = {
|
const Protocol protocol_swiftpair = {
|
||||||
.icon = &I_windows,
|
.icon = &I_windows,
|
||||||
.get_name = swiftpair_get_name,
|
.get_name = get_name,
|
||||||
.make_packet = swiftpair_make_packet,
|
.make_packet = make_packet,
|
||||||
.extra_config = swiftpair_extra_config,
|
.extra_config = extra_config,
|
||||||
.config_count = swiftpair_config_count,
|
.config_count = config_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void name_callback(void* _ctx) {
|
static void name_callback(void* _ctx) {
|
||||||
Ctx* ctx = _ctx;
|
Ctx* ctx = _ctx;
|
||||||
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
_cfg->mode = ProtocolModeValue;
|
||||||
scene_manager_previous_scene(ctx->scene_manager);
|
scene_manager_previous_scene(ctx->scene_manager);
|
||||||
}
|
}
|
||||||
void scene_swiftpair_name_on_enter(void* _ctx) {
|
void scene_swiftpair_name_on_enter(void* _ctx) {
|
||||||
Ctx* ctx = _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;
|
TextInput* text_input = ctx->text_input;
|
||||||
text_input_reset(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_set_result_callback(
|
||||||
text_input, name_callback, ctx, cfg->name, sizeof(cfg->name), true);
|
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);
|
view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewTextInput);
|
||||||
}
|
}
|
||||||
bool scene_swiftpair_name_on_event(void* _ctx, SceneManagerEvent event) {
|
bool scene_swiftpair_name_on_event(void* _ctx, SceneManagerEvent event) {
|
||||||
UNUSED(_ctx);
|
Ctx* ctx = _ctx;
|
||||||
UNUSED(event);
|
ProtocolCfg* _cfg = &ctx->attack->payload.cfg;
|
||||||
|
if(event.type == SceneManagerEventTypeBack) {
|
||||||
|
_cfg->mode = ProtocolModeRandom;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void scene_swiftpair_name_on_exit(void* _ctx) {
|
void scene_swiftpair_name_on_exit(void* _ctx) {
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ bool xtreme_app_scene_interface_mainmenu_reset_on_event(void* context, SceneMana
|
|||||||
app->require_reboot = true;
|
app->require_reboot = true;
|
||||||
xtreme_app_apply(app);
|
xtreme_app_apply(app);
|
||||||
break;
|
break;
|
||||||
|
case DialogExResultLeft:
|
||||||
|
scene_manager_previous_scene(app->scene_manager);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, " 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_icon(dialog, 21, 13, &I_Cry_dolph_55x52);
|
||||||
dialog_ex_set_left_button_text(dialog, "Back");
|
dialog_ex_set_left_button_text(dialog, "Battery");
|
||||||
dialog_ex_set_right_button_text(dialog, "OFF");
|
dialog_ex_set_right_button_text(dialog, "OFF");
|
||||||
dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback);
|
dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback);
|
||||||
dialog_ex_set_context(dialog, app);
|
dialog_ex_set_context(dialog, app);
|
||||||
@@ -34,10 +34,7 @@ bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent ev
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == DialogExResultLeft) {
|
if(event.event == DialogExResultLeft) {
|
||||||
if(!scene_manager_previous_scene(app->scene_manager)) {
|
scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneBatteryInfo);
|
||||||
scene_manager_stop(app->scene_manager);
|
|
||||||
view_dispatcher_stop(app->view_dispatcher);
|
|
||||||
}
|
|
||||||
} else if(event.event == DialogExResultRight) {
|
} else if(event.event == DialogExResultRight) {
|
||||||
power_off(app->power);
|
power_off(app->power);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,10 @@ static bool battery_info_input_callback(InputEvent* event, void* context) {
|
|||||||
|
|
||||||
BatteryInfo* battery_info = 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) {
|
if(event->key == InputKeyLeft) {
|
||||||
event->key = InputKeyBack;
|
event->key = InputKeyBack;
|
||||||
} else if(event->key == InputKeyRight) {
|
} else if(event->key == InputKeyRight) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ typedef struct {
|
|||||||
bool left_mouse_held;
|
bool left_mouse_held;
|
||||||
bool right_mouse_pressed;
|
bool right_mouse_pressed;
|
||||||
bool connected;
|
bool connected;
|
||||||
|
uint8_t acceleration;
|
||||||
HidTransport transport;
|
HidTransport transport;
|
||||||
} HidMouseModel;
|
} HidMouseModel;
|
||||||
|
|
||||||
@@ -119,6 +120,11 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
|
|||||||
hid_mouse->view,
|
hid_mouse->view,
|
||||||
HidMouseModel * model,
|
HidMouseModel * model,
|
||||||
{
|
{
|
||||||
|
model->acceleration = (event->type == InputTypePress) ? 1 :
|
||||||
|
(event->type == InputTypeRelease) ? 0 :
|
||||||
|
(model->acceleration >= 20) ? 20 :
|
||||||
|
model->acceleration + 1;
|
||||||
|
|
||||||
if(event->key == InputKeyBack) {
|
if(event->key == InputKeyBack) {
|
||||||
if(event->type == InputTypeShort) {
|
if(event->type == InputTypeShort) {
|
||||||
hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT);
|
hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT);
|
||||||
@@ -150,7 +156,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
|
|||||||
model->right_pressed = true;
|
model->right_pressed = true;
|
||||||
hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0);
|
hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0);
|
||||||
} else if(event->type == InputTypeRepeat) {
|
} else if(event->type == InputTypeRepeat) {
|
||||||
hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0);
|
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) {
|
} else if(event->type == InputTypeRelease) {
|
||||||
model->right_pressed = false;
|
model->right_pressed = false;
|
||||||
}
|
}
|
||||||
@@ -159,7 +166,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
|
|||||||
model->left_pressed = true;
|
model->left_pressed = true;
|
||||||
hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0);
|
hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0);
|
||||||
} else if(event->type == InputTypeRepeat) {
|
} else if(event->type == InputTypeRepeat) {
|
||||||
hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0);
|
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) {
|
} else if(event->type == InputTypeRelease) {
|
||||||
model->left_pressed = false;
|
model->left_pressed = false;
|
||||||
}
|
}
|
||||||
@@ -168,7 +176,9 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
|
|||||||
model->down_pressed = true;
|
model->down_pressed = true;
|
||||||
hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT);
|
hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT);
|
||||||
} else if(event->type == InputTypeRepeat) {
|
} else if(event->type == InputTypeRepeat) {
|
||||||
hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG);
|
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) {
|
} else if(event->type == InputTypeRelease) {
|
||||||
model->down_pressed = false;
|
model->down_pressed = false;
|
||||||
}
|
}
|
||||||
@@ -177,7 +187,8 @@ static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
|
|||||||
model->up_pressed = true;
|
model->up_pressed = true;
|
||||||
hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT);
|
hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT);
|
||||||
} else if(event->type == InputTypeRepeat) {
|
} else if(event->type == InputTypeRepeat) {
|
||||||
hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG);
|
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) {
|
} else if(event->type == InputTypeRelease) {
|
||||||
model->up_pressed = false;
|
model->up_pressed = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,21 +201,30 @@ bool subrem_view_remote_input(InputEvent* event, void* context) {
|
|||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubRemViewRemote* subrem_view_remote = context;
|
SubRemViewRemote* subrem_view_remote = context;
|
||||||
|
|
||||||
if(event->key == InputKeyBack && event->type == InputTypeLong) {
|
if(event->key == InputKeyBack && event->type == InputTypePress) {
|
||||||
subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context);
|
bool is_stopping = false;
|
||||||
return true;
|
|
||||||
} else if(event->key == InputKeyBack && event->type == InputTypeShort) {
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
subrem_view_remote->view,
|
subrem_view_remote->view,
|
||||||
SubRemViewRemoteModel * model,
|
SubRemViewRemoteModel * model,
|
||||||
{ model->pressed_btn = 0; },
|
{
|
||||||
|
if(model->state == SubRemViewRemoteStateSending) {
|
||||||
|
is_stopping = true;
|
||||||
|
model->pressed_btn = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
true);
|
true);
|
||||||
subrem_view_remote->callback(
|
|
||||||
SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context);
|
//Cant send exit the app inside that with_model,locks the model and the app will hang and not unload!
|
||||||
return true;
|
if(is_stopping)
|
||||||
} else if(event->key == InputKeyBack) {
|
subrem_view_remote->callback(
|
||||||
|
SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context);
|
||||||
|
else
|
||||||
|
subrem_view_remote->callback(
|
||||||
|
SubRemCustomEventViewRemoteBack, subrem_view_remote->context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BACK button processing end
|
// BACK button processing end
|
||||||
|
|
||||||
if(event->key == InputKeyUp && event->type == InputTypePress) {
|
if(event->key == InputKeyUp && event->type == InputTypePress) {
|
||||||
|
|||||||
11
fbt
11
fbt
@@ -5,7 +5,8 @@
|
|||||||
set -eu;
|
set -eu;
|
||||||
|
|
||||||
# private variables
|
# 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)";
|
SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd -P)";
|
||||||
SCONS_DEFAULT_FLAGS="--warn=target-not-built";
|
SCONS_DEFAULT_FLAGS="--warn=target-not-built";
|
||||||
SCONS_EP="python3 -m SCons";
|
SCONS_EP="python3 -m SCons";
|
||||||
@@ -15,6 +16,7 @@ FBT_NOENV="${FBT_NOENV:-""}";
|
|||||||
FBT_NO_SYNC="${FBT_NO_SYNC:-""}";
|
FBT_NO_SYNC="${FBT_NO_SYNC:-""}";
|
||||||
FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}";
|
FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}";
|
||||||
FBT_VERBOSE="${FBT_VERBOSE:-""}";
|
FBT_VERBOSE="${FBT_VERBOSE:-""}";
|
||||||
|
FBT_GIT_SUBMODULE_SHALLOW="${FBT_GIT_SUBMODULE_SHALLOW:-""}";
|
||||||
|
|
||||||
if [ -z "$FBT_NOENV" ]; then
|
if [ -z "$FBT_NOENV" ]; then
|
||||||
FBT_VERBOSE="$FBT_VERBOSE" . "$SCRIPT_PATH/scripts/toolchain/fbtenv.sh";
|
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\"";
|
echo "\".git\" directory not found, please clone repo via \"git clone\"";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
git submodule update --init --recursive --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 --recursive $_FBT_CLONE_FLAGS;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$SCONS_EP $SCONS_DEFAULT_FLAGS "$@"
|
$SCONS_EP $SCONS_DEFAULT_FLAGS "$@"
|
||||||
|
|||||||
12
fbt.cmd
12
fbt.cmd
@@ -4,10 +4,18 @@ call "%~dp0scripts\toolchain\fbtenv.cmd" env
|
|||||||
set SCONS_EP=python -m SCons
|
set SCONS_EP=python -m SCons
|
||||||
|
|
||||||
if [%FBT_NO_SYNC%] == [] (
|
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" (
|
if exist ".git" (
|
||||||
git submodule update --init --recursive --depth 1 --jobs %NUMBER_OF_PROCESSORS%
|
git submodule update --init --recursive --recursive %_FBT_CLONE_FLAGS%
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo Failed to update submodules, set FBT_NO_SYNC to skip
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
) else (
|
) 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
|
exit /b 1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -613,10 +613,31 @@ static Elf32_Addr elf_address_of_by_hash(ELFFile* elf, uint32_t hash) {
|
|||||||
return ELF_INVALID_ADDRESS;
|
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) {
|
static bool elf_relocate_fast(ELFFile* elf, ELFSection* s) {
|
||||||
UNUSED(elf);
|
UNUSED(elf);
|
||||||
const uint8_t* start = s->fast_rel->data;
|
const uint8_t* start = s->fast_rel->data;
|
||||||
const uint8_t version = *start;
|
const uint8_t version = *start;
|
||||||
|
bool no_errors = true;
|
||||||
|
|
||||||
if(version != FAST_RELOCATION_VERSION) {
|
if(version != FAST_RELOCATION_VERSION) {
|
||||||
FURI_LOG_E(TAG, "Unsupported fast relocation version %d", 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) {
|
if(address == ELF_INVALID_ADDRESS) {
|
||||||
FURI_LOG_E(TAG, "Failed to resolve address for hash %lX", hash_or_section_index);
|
FuriString* symbol_name = furi_string_alloc();
|
||||||
return false;
|
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++) {
|
no_errors = false;
|
||||||
uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF;
|
start += 3 * offsets_count;
|
||||||
start += 3;
|
} else {
|
||||||
// FURI_LOG_I(TAG, " Fast relocation offset %ld: %ld", j, offset);
|
for(uint32_t j = 0; j < offsets_count; j++) {
|
||||||
Elf32_Addr relAddr = ((Elf32_Addr)s->data) + offset;
|
uint32_t offset = *((uint32_t*)start) & 0x00FFFFFF;
|
||||||
elf_relocate_symbol(elf, relAddr, type, address);
|
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);
|
free(s->fast_rel);
|
||||||
s->fast_rel = NULL;
|
s->fast_rel = NULL;
|
||||||
|
|
||||||
return true;
|
return no_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool elf_relocate_section(ELFFile* elf, ELFSection* section) {
|
static bool elf_relocate_section(ELFFile* elf, ELFSection* section) {
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ class FlipperApplication:
|
|||||||
def is_default_deployable(self):
|
def is_default_deployable(self):
|
||||||
return self.apptype != FlipperAppType.DEBUG and self.fap_category != "Examples"
|
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):
|
def __post_init__(self):
|
||||||
if self.apptype == FlipperAppType.PLUGIN:
|
if self.apptype == FlipperAppType.PLUGIN:
|
||||||
self.stack_size = 0
|
self.stack_size = 0
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class AppBuilder:
|
|||||||
self.ext_apps_work_dir = env["EXT_APPS_WORK_DIR"]
|
self.ext_apps_work_dir = env["EXT_APPS_WORK_DIR"]
|
||||||
self.app_work_dir = self.get_app_work_dir(env, app)
|
self.app_work_dir = self.get_app_work_dir(env, app)
|
||||||
self.app_alias = f"fap_{self.app.appid}"
|
self.app_alias = f"fap_{self.app.appid}"
|
||||||
|
self.icons_src = None
|
||||||
self.externally_built_files = []
|
self.externally_built_files = []
|
||||||
self.private_libs = []
|
self.private_libs = []
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ class AppBuilder:
|
|||||||
)
|
)
|
||||||
self.app_env.Alias("_fap_icons", fap_icons)
|
self.app_env.Alias("_fap_icons", fap_icons)
|
||||||
self.fw_env.Append(_APP_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):
|
def _build_private_libs(self):
|
||||||
for lib_def in self.app.fap_private_libs:
|
for lib_def in self.app.fap_private_libs:
|
||||||
@@ -160,6 +162,10 @@ class AppBuilder:
|
|||||||
if not app_sources:
|
if not app_sources:
|
||||||
raise UserError(f"No source files found for {self.app.appid}")
|
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
|
## Uncomment for debug
|
||||||
# print(f"App sources for {self.app.appid}: {list(f.path for f in app_sources)}")
|
# 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"))
|
self.app._assets_dirs.append(self.app_work_dir.Dir("assets"))
|
||||||
|
|
||||||
app_artifacts.validator = self.app_env.ValidateAppImports(
|
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]
|
)[0]
|
||||||
|
|
||||||
if self.app.apptype == FlipperAppType.PLUGIN:
|
if self.app.apptype == FlipperAppType.PLUGIN:
|
||||||
@@ -300,7 +308,10 @@ def validate_app_imports(target, source, env):
|
|||||||
+ fg.brightmagenta(f"{disabled_api_syms}")
|
+ fg.brightmagenta(f"{disabled_api_syms}")
|
||||||
+ fg.brightyellow(")")
|
+ 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):
|
def GetExtAppByIdOrPath(env, app_dir):
|
||||||
|
|||||||
@@ -20,10 +20,9 @@ def GlobRecursive(env, pattern, node=".", exclude=[]):
|
|||||||
source=True,
|
source=True,
|
||||||
exclude=exclude,
|
exclude=exclude,
|
||||||
)
|
)
|
||||||
# Otherwise, just check if that's an existing file path
|
# Otherwise, just assume that file at path exists
|
||||||
# NB: still creates "virtual" nodes as part of existence check
|
else:
|
||||||
elif (file_node := node.File(pattern)).exists() or file_node.rexists():
|
results.append(node.File(pattern))
|
||||||
results.append(file_node)
|
|
||||||
# print(f"Glob result for {pattern} from {node}: {results}")
|
# print(f"Glob result for {pattern} from {node}: {results}")
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ vars.AddVariables(
|
|||||||
"CDC Port of Flipper to use, if multiple are connected",
|
"CDC Port of Flipper to use, if multiple are connected",
|
||||||
"auto",
|
"auto",
|
||||||
),
|
),
|
||||||
|
BoolVariable(
|
||||||
|
"STRICT_FAP_IMPORT_CHECK",
|
||||||
|
help="Enable strict import check for .faps",
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Return("vars")
|
Return("vars")
|
||||||
|
|||||||
@@ -270,6 +270,11 @@ vars.AddVariables(
|
|||||||
"clangd",
|
"clangd",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
BoolVariable(
|
||||||
|
"STRICT_FAP_IMPORT_CHECK",
|
||||||
|
help="Enable strict import check for .faps",
|
||||||
|
default=True,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Return("vars")
|
Return("vars")
|
||||||
|
|||||||
Reference in New Issue
Block a user