mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-23 21:13:16 +00:00
Merge branch 'mpu' into dev
This commit is contained in:
commit
9dc337a02c
23 changed files with 410 additions and 137 deletions
|
@ -5,6 +5,6 @@ App(
|
|||
entry_point="arkanoid_game_app",
|
||||
cdefines=["APP_ARKANOID_GAME"],
|
||||
requires=["gui"],
|
||||
stack_size=4 * 1024,
|
||||
stack_size=1 * 1024,
|
||||
order=30,
|
||||
)
|
||||
|
|
|
@ -6,5 +6,5 @@ App(
|
|||
cdefines=["APP_FLIP_FRID"],
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
order=13,
|
||||
order=15,
|
||||
)
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <nrf24.h>
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
#include "mousejacker_ducky.h"
|
||||
|
||||
#define TAG "mousejacker"
|
||||
|
@ -31,14 +30,8 @@ typedef struct {
|
|||
InputEvent input;
|
||||
} PluginEvent;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
bool ducky_err;
|
||||
bool addr_err;
|
||||
} PluginState;
|
||||
|
||||
uint8_t addrs_count = 0;
|
||||
uint8_t addr_idx = 0;
|
||||
uint8_t loaded_addrs[MAX_ADDRS][6]; // first byte is rate, the rest are the address
|
||||
|
||||
char target_fmt_text[] = "Target addr: %s";
|
||||
|
@ -54,7 +47,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
|||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
if(!plugin_state->addr_err && !plugin_state->ducky_err) {
|
||||
if(!plugin_state->addr_err && !plugin_state->ducky_err && !plugin_state->is_thread_running) {
|
||||
snprintf(target_text, sizeof(target_text), target_fmt_text, target_address_str);
|
||||
canvas_draw_str_aligned(canvas, 7, 10, AlignLeft, AlignBottom, target_text);
|
||||
canvas_draw_str_aligned(canvas, 22, 20, AlignLeft, AlignBottom, "<- select address ->");
|
||||
|
@ -70,9 +63,17 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
|||
canvas, 7, 40, AlignLeft, AlignBottom, "Run (NRF24: Sniff) app first!");
|
||||
} else if(plugin_state->ducky_err) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 10, 10, AlignLeft, AlignBottom, "Error: No mousejacker folder");
|
||||
canvas_draw_str_aligned(canvas, 10, 20, AlignLeft, AlignBottom, "or duckyscript file");
|
||||
canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, "loading error");
|
||||
canvas, 3, 10, AlignLeft, AlignBottom, "Error: No mousejacker folder");
|
||||
canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "or duckyscript file");
|
||||
canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "loading error");
|
||||
} else if(plugin_state->is_thread_running) {
|
||||
canvas_draw_str_aligned(canvas, 3, 10, AlignLeft, AlignBottom, "Running duckyscript");
|
||||
canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "press back");
|
||||
canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "to exit");
|
||||
} else {
|
||||
canvas_draw_str_aligned(canvas, 3, 10, AlignLeft, AlignBottom, "Unknown Error");
|
||||
canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "press back");
|
||||
canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "to exit");
|
||||
}
|
||||
|
||||
release_mutex((ValueMutex*)ctx, plugin_state);
|
||||
|
@ -86,8 +87,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
|||
}
|
||||
|
||||
static void mousejacker_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->x = 50;
|
||||
plugin_state->y = 30;
|
||||
plugin_state->is_thread_running = false;
|
||||
}
|
||||
|
||||
static void hexlify(uint8_t* in, uint8_t size, char* out) {
|
||||
|
@ -108,7 +108,7 @@ static bool open_ducky_script(Stream* stream) {
|
|||
furi_record_close("dialogs");
|
||||
if(ret) {
|
||||
if(!file_stream_open(stream, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_I(TAG, "Cannot open file \"%s\"", (path));
|
||||
FURI_LOG_D(TAG, "Cannot open file \"%s\"", (path));
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ static bool open_addrs_file(Stream* stream) {
|
|||
furi_record_close("dialogs");
|
||||
if(ret) {
|
||||
if(!file_stream_open(stream, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_I(TAG, "Cannot open file \"%s\"", (path));
|
||||
FURI_LOG_D(TAG, "Cannot open file \"%s\"", (path));
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
@ -138,29 +138,34 @@ static bool open_addrs_file(Stream* stream) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_ducky_file(Stream* file_stream, uint8_t* addr, uint8_t addr_size, uint8_t rate) {
|
||||
static bool process_ducky_file(
|
||||
Stream* file_stream,
|
||||
uint8_t* addr,
|
||||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
PluginState* plugin_state) {
|
||||
size_t file_size = 0;
|
||||
size_t bytes_read = 0;
|
||||
uint8_t* file_buf;
|
||||
bool loaded = false;
|
||||
FURI_LOG_I(TAG, "opening ducky script");
|
||||
FURI_LOG_D(TAG, "opening ducky script");
|
||||
if(open_ducky_script(file_stream)) {
|
||||
file_size = stream_size(file_stream);
|
||||
if(file_size == (size_t)0) {
|
||||
FURI_LOG_I(TAG, "load failed. file_size: %d", file_size);
|
||||
FURI_LOG_D(TAG, "load failed. file_size: %d", file_size);
|
||||
return loaded;
|
||||
}
|
||||
file_buf = malloc(file_size);
|
||||
memset(file_buf, 0, file_size);
|
||||
bytes_read = stream_read(file_stream, file_buf, file_size);
|
||||
if(bytes_read == file_size) {
|
||||
FURI_LOG_I(TAG, "executing ducky script");
|
||||
mj_process_ducky_script(nrf24_HANDLE, addr, addr_size, rate, (char*)file_buf);
|
||||
FURI_LOG_I(TAG, "finished execution");
|
||||
FURI_LOG_D(TAG, "executing ducky script");
|
||||
mj_process_ducky_script(
|
||||
nrf24_HANDLE, addr, addr_size, rate, (char*)file_buf, plugin_state);
|
||||
FURI_LOG_D(TAG, "finished execution");
|
||||
loaded = true;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "load failed. file size: %d", file_size);
|
||||
FURI_LOG_D(TAG, "load failed. file size: %d", file_size);
|
||||
}
|
||||
free(file_buf);
|
||||
}
|
||||
|
@ -179,19 +184,19 @@ static bool load_addrs_file(Stream* file_stream) {
|
|||
uint32_t i_addr_lo = 0;
|
||||
uint32_t i_addr_hi = 0;
|
||||
bool loaded = false;
|
||||
FURI_LOG_I(TAG, "opening addrs file");
|
||||
FURI_LOG_D(TAG, "opening addrs file");
|
||||
addrs_count = 0;
|
||||
if(open_addrs_file(file_stream)) {
|
||||
file_size = stream_size(file_stream);
|
||||
if(file_size == (size_t)0) {
|
||||
FURI_LOG_I(TAG, "load failed. file_size: %d", file_size);
|
||||
FURI_LOG_D(TAG, "load failed. file_size: %d", file_size);
|
||||
return loaded;
|
||||
}
|
||||
file_buf = malloc(file_size);
|
||||
memset(file_buf, 0, file_size);
|
||||
bytes_read = stream_read(file_stream, file_buf, file_size);
|
||||
if(bytes_read == file_size) {
|
||||
FURI_LOG_I(TAG, "loading addrs file");
|
||||
FURI_LOG_D(TAG, "loading addrs file");
|
||||
char* line = strtok((char*)file_buf, "\n");
|
||||
|
||||
while(line != NULL) {
|
||||
|
@ -211,17 +216,54 @@ static bool load_addrs_file(Stream* file_stream) {
|
|||
loaded = true;
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "load failed. file size: %d", file_size);
|
||||
FURI_LOG_D(TAG, "load failed. file size: %d", file_size);
|
||||
}
|
||||
free(file_buf);
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
// entrypoint for worker
|
||||
static int32_t mj_worker_thread(void* ctx) {
|
||||
PluginState* plugin_state = ctx;
|
||||
bool ducky_ok = false;
|
||||
if(!plugin_state->addr_err) {
|
||||
plugin_state->is_thread_running = true;
|
||||
plugin_state->file_stream = file_stream_alloc(plugin_state->storage);
|
||||
nrf24_find_channel(
|
||||
nrf24_HANDLE,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
5,
|
||||
loaded_addrs[addr_idx][0],
|
||||
2,
|
||||
LOGITECH_MAX_CHANNEL,
|
||||
true);
|
||||
ducky_ok = process_ducky_file(
|
||||
plugin_state->file_stream,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
5,
|
||||
loaded_addrs[addr_idx][0],
|
||||
plugin_state);
|
||||
if(!ducky_ok) {
|
||||
plugin_state->ducky_err = true;
|
||||
} else {
|
||||
plugin_state->ducky_err = false;
|
||||
}
|
||||
stream_free(plugin_state->file_stream);
|
||||
}
|
||||
plugin_state->is_thread_running = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void start_mjthread(PluginState* plugin_state) {
|
||||
if(!plugin_state->is_thread_running) {
|
||||
furi_thread_start(plugin_state->mjthread);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mousejacker_app(void* p) {
|
||||
UNUSED(p);
|
||||
uint8_t addr_idx = 0;
|
||||
bool ducky_ok = false;
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
|
||||
PluginState* plugin_state = malloc(sizeof(PluginState));
|
||||
|
@ -243,19 +285,25 @@ int32_t mousejacker_app(void* p) {
|
|||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_mkdir(storage, MOUSEJACKER_APP_PATH_FOLDER);
|
||||
Stream* file_stream = file_stream_alloc(storage);
|
||||
plugin_state->storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_mkdir(plugin_state->storage, MOUSEJACKER_APP_PATH_FOLDER);
|
||||
plugin_state->file_stream = file_stream_alloc(plugin_state->storage);
|
||||
|
||||
plugin_state->mjthread = furi_thread_alloc();
|
||||
furi_thread_set_name(plugin_state->mjthread, "MJ Worker");
|
||||
furi_thread_set_stack_size(plugin_state->mjthread, 2048);
|
||||
furi_thread_set_context(plugin_state->mjthread, plugin_state);
|
||||
furi_thread_set_callback(plugin_state->mjthread, mj_worker_thread);
|
||||
|
||||
// spawn load file dialog to choose sniffed addresses file
|
||||
if(load_addrs_file(file_stream)) {
|
||||
if(load_addrs_file(plugin_state->file_stream)) {
|
||||
addr_idx = 0;
|
||||
hexlify(&loaded_addrs[addr_idx][1], 5, target_address_str);
|
||||
plugin_state->addr_err = false;
|
||||
} else {
|
||||
plugin_state->addr_err = true;
|
||||
}
|
||||
stream_free(file_stream);
|
||||
stream_free(plugin_state->file_stream);
|
||||
nrf24_init();
|
||||
|
||||
PluginEvent event;
|
||||
|
@ -288,44 +336,31 @@ int32_t mousejacker_app(void* p) {
|
|||
break;
|
||||
case InputKeyOk:
|
||||
if(!plugin_state->addr_err) {
|
||||
file_stream = file_stream_alloc(storage);
|
||||
nrf24_find_channel(
|
||||
nrf24_HANDLE,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
5,
|
||||
loaded_addrs[addr_idx][0],
|
||||
2,
|
||||
LOGITECH_MAX_CHANNEL,
|
||||
true);
|
||||
ducky_ok = process_ducky_file(
|
||||
file_stream,
|
||||
loaded_addrs[addr_idx] + 1,
|
||||
5,
|
||||
loaded_addrs[addr_idx][0]);
|
||||
if(!ducky_ok) {
|
||||
plugin_state->ducky_err = true;
|
||||
} else {
|
||||
plugin_state->ducky_err = false;
|
||||
if(!plugin_state->is_thread_running) {
|
||||
start_mjthread(plugin_state);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
stream_free(file_stream);
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
plugin_state->close_thread_please = true;
|
||||
if(plugin_state->is_thread_running && plugin_state->mjthread) {
|
||||
furi_thread_join(
|
||||
plugin_state->mjthread); // wait until thread is finished
|
||||
}
|
||||
plugin_state->close_thread_please = false;
|
||||
processing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_D("mousejacker", "furi_message_queue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
release_mutex(&state_mutex, plugin_state);
|
||||
}
|
||||
|
||||
furi_thread_free(plugin_state->mjthread);
|
||||
furi_hal_spi_release(nrf24_HANDLE);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
|
@ -333,6 +368,7 @@ int32_t mousejacker_app(void* p) {
|
|||
furi_record_close(RECORD_STORAGE);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
free(plugin_state);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -87,7 +87,7 @@ static uint32_t mj_ducky_get_command_len(const char* line) {
|
|||
}
|
||||
|
||||
static bool mj_get_ducky_key(char* key, size_t keylen, MJDuckyKey* dk) {
|
||||
//FURI_LOG_I(TAG, "looking up key %s with length %d", key, keylen);
|
||||
//FURI_LOG_D(TAG, "looking up key %s with length %d", key, keylen);
|
||||
for(uint i = 0; i < sizeof(mj_ducky_keys) / sizeof(MJDuckyKey); i++) {
|
||||
if(!strncmp(mj_ducky_keys[i].name, key, keylen)) {
|
||||
memcpy(dk, &mj_ducky_keys[i], sizeof(MJDuckyKey));
|
||||
|
@ -113,10 +113,16 @@ static void inject_packet(
|
|||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
uint8_t* payload,
|
||||
size_t payload_size) {
|
||||
size_t payload_size,
|
||||
PluginState* plugin_state) {
|
||||
uint8_t rt_count = 0;
|
||||
while(1) {
|
||||
if(nrf24_txpacket(handle, payload, payload_size, true)) break;
|
||||
if(!plugin_state->is_thread_running || plugin_state->close_thread_please) {
|
||||
return;
|
||||
}
|
||||
if(nrf24_txpacket(handle, payload, payload_size, true)) {
|
||||
break;
|
||||
}
|
||||
|
||||
rt_count++;
|
||||
// retransmit threshold exceeded, scan for new channel
|
||||
|
@ -129,8 +135,10 @@ static void inject_packet(
|
|||
rate,
|
||||
LOGITECH_MIN_CHANNEL,
|
||||
LOGITECH_MAX_CHANNEL,
|
||||
true) > LOGITECH_MAX_CHANNEL)
|
||||
true) > LOGITECH_MAX_CHANNEL) {
|
||||
return; // fail
|
||||
}
|
||||
//FURI_LOG_D("mj", "find channel passed, %d", tessst);
|
||||
|
||||
rt_count = 0;
|
||||
}
|
||||
|
@ -150,7 +158,8 @@ static void send_hid_packet(
|
|||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
uint8_t mod,
|
||||
uint8_t hid) {
|
||||
uint8_t hid,
|
||||
PluginState* plugin_state) {
|
||||
uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0};
|
||||
build_hid_packet(0, 0, hid_payload);
|
||||
if(hid == prev_hid)
|
||||
|
@ -160,11 +169,13 @@ static void send_hid_packet(
|
|||
addr_size,
|
||||
rate,
|
||||
hid_payload,
|
||||
LOGITECH_HID_TEMPLATE_SIZE); // empty hid packet
|
||||
LOGITECH_HID_TEMPLATE_SIZE,
|
||||
plugin_state); // empty hid packet
|
||||
|
||||
prev_hid = hid;
|
||||
build_hid_packet(mod, hid, hid_payload);
|
||||
inject_packet(handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE);
|
||||
inject_packet(
|
||||
handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE, plugin_state);
|
||||
furi_delay_ms(12);
|
||||
}
|
||||
|
||||
|
@ -175,11 +186,15 @@ static bool mj_process_ducky_line(
|
|||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
char* line,
|
||||
char* prev_line) {
|
||||
char* prev_line,
|
||||
PluginState* plugin_state) {
|
||||
MJDuckyKey dk;
|
||||
uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0};
|
||||
char* line_tmp = line;
|
||||
uint32_t line_len = strlen(line);
|
||||
if(!plugin_state->is_thread_running || plugin_state->close_thread_please) {
|
||||
return true;
|
||||
}
|
||||
for(uint32_t i = 0; i < line_len; i++) {
|
||||
if((line_tmp[i] != ' ') && (line_tmp[i] != '\t') && (line_tmp[i] != '\n')) {
|
||||
line_tmp = &line_tmp[i];
|
||||
|
@ -188,7 +203,7 @@ static bool mj_process_ducky_line(
|
|||
if(i == line_len - 1) return true; // Skip empty lines
|
||||
}
|
||||
|
||||
FURI_LOG_I(TAG, "line: %s", line_tmp);
|
||||
FURI_LOG_D(TAG, "line: %s", line_tmp);
|
||||
|
||||
// General commands
|
||||
if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) {
|
||||
|
@ -208,10 +223,20 @@ static bool mj_process_ducky_line(
|
|||
addr_size,
|
||||
rate,
|
||||
hid_payload,
|
||||
LOGITECH_HID_TEMPLATE_SIZE); // empty hid packet
|
||||
LOGITECH_HID_TEMPLATE_SIZE,
|
||||
plugin_state); // empty hid packet
|
||||
for(uint32_t i = 0; i < delay_count; i++) {
|
||||
if(!plugin_state->is_thread_running || plugin_state->close_thread_please) {
|
||||
return true;
|
||||
}
|
||||
inject_packet(
|
||||
handle, addr, addr_size, rate, LOGITECH_KEEPALIVE, LOGITECH_KEEPALIVE_SIZE);
|
||||
handle,
|
||||
addr,
|
||||
addr_size,
|
||||
rate,
|
||||
LOGITECH_KEEPALIVE,
|
||||
LOGITECH_KEEPALIVE_SIZE,
|
||||
plugin_state);
|
||||
furi_delay_ms(10);
|
||||
}
|
||||
return true;
|
||||
|
@ -223,7 +248,7 @@ static bool mj_process_ducky_line(
|
|||
for(size_t i = 0; i < strlen(line_tmp); i++) {
|
||||
if(!mj_get_ducky_key(&line_tmp[i], 1, &dk)) return false;
|
||||
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -236,15 +261,15 @@ static bool mj_process_ducky_line(
|
|||
repeat_cnt = atoi(line_tmp);
|
||||
if(repeat_cnt < 2) return false;
|
||||
|
||||
FURI_LOG_I(TAG, "repeating %s %d times", prev_line, repeat_cnt);
|
||||
FURI_LOG_D(TAG, "repeating %s %d times", prev_line, repeat_cnt);
|
||||
for(uint32_t i = 0; i < repeat_cnt; i++)
|
||||
mj_process_ducky_line(handle, addr, addr_size, rate, prev_line, NULL);
|
||||
mj_process_ducky_line(handle, addr, addr_size, rate, prev_line, NULL, plugin_state);
|
||||
|
||||
return true;
|
||||
} else if(strncmp(line_tmp, "ALT", strlen("ALT")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "GUI", strlen("GUI")) == 0 ||
|
||||
|
@ -252,72 +277,72 @@ static bool mj_process_ducky_line(
|
|||
strncmp(line_tmp, "COMMAND", strlen("COMMAND")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 8, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 8, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "CTRL-ALT", strlen("CTRL-ALT")) == 0 ||
|
||||
strncmp(line_tmp, "CONTROL-ALT", strlen("CONTROL-ALT")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4 | 1, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4 | 1, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "CTRL-SHIFT", strlen("CTRL-SHIFT")) == 0 ||
|
||||
strncmp(line_tmp, "CONTROL-SHIFT", strlen("CONTROL-SHIFT")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4 | 2, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 4 | 2, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "CTRL", strlen("CTRL")) == 0 ||
|
||||
strncmp(line_tmp, "CONTROL", strlen("CONTROL")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 1, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 1, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(strncmp(line_tmp, "SHIFT", strlen("SHIFT")) == 0) {
|
||||
line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1];
|
||||
if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 2, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod | 2, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "ESC", strlen("ESC")) == 0 ||
|
||||
strncmp(line_tmp, "APP", strlen("APP")) == 0 ||
|
||||
strncmp(line_tmp, "ESCAPE", strlen("ESCAPE")) == 0) {
|
||||
if(!mj_get_ducky_key("ESCAPE", 6, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(strncmp(line_tmp, "ENTER", strlen("ENTER")) == 0) {
|
||||
if(!mj_get_ducky_key("ENTER", 5, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "UP", strlen("UP")) == 0 ||
|
||||
strncmp(line_tmp, "UPARROW", strlen("UPARROW")) == 0) {
|
||||
if(!mj_get_ducky_key("UP", 2, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "DOWN", strlen("DOWN")) == 0 ||
|
||||
strncmp(line_tmp, "DOWNARROW", strlen("DOWNARROW")) == 0) {
|
||||
if(!mj_get_ducky_key("DOWN", 4, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "LEFT", strlen("LEFT")) == 0 ||
|
||||
strncmp(line_tmp, "LEFTARROW", strlen("LEFTARROW")) == 0) {
|
||||
if(!mj_get_ducky_key("LEFT", 4, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(
|
||||
strncmp(line_tmp, "RIGHT", strlen("RIGHT")) == 0 ||
|
||||
strncmp(line_tmp, "RIGHTARROW", strlen("RIGHTARROW")) == 0) {
|
||||
if(!mj_get_ducky_key("RIGHT", 5, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
} else if(strncmp(line_tmp, "SPACE", strlen("SPACE")) == 0) {
|
||||
if(!mj_get_ducky_key("SPACE", 5, &dk)) return false;
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid);
|
||||
send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -329,17 +354,19 @@ void mj_process_ducky_script(
|
|||
uint8_t* addr,
|
||||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
char* script) {
|
||||
char* script,
|
||||
PluginState* plugin_state) {
|
||||
uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0};
|
||||
char* prev_line = NULL;
|
||||
|
||||
inject_packet(handle, addr, addr_size, rate, LOGITECH_HELLO, LOGITECH_HELLO_SIZE);
|
||||
inject_packet(
|
||||
handle, addr, addr_size, rate, LOGITECH_HELLO, LOGITECH_HELLO_SIZE, plugin_state);
|
||||
char* line = strtok(script, "\n");
|
||||
while(line != NULL) {
|
||||
if(strcmp(&line[strlen(line) - 1], "\r") == 0) line[strlen(line) - 1] = (char)0;
|
||||
|
||||
if(!mj_process_ducky_line(handle, addr, addr_size, rate, line, prev_line))
|
||||
FURI_LOG_I(TAG, "unable to process ducky script line: %s", line);
|
||||
if(!mj_process_ducky_line(handle, addr, addr_size, rate, line, prev_line, plugin_state))
|
||||
FURI_LOG_D(TAG, "unable to process ducky script line: %s", line);
|
||||
|
||||
prev_line = line;
|
||||
line = strtok(NULL, "\n");
|
||||
|
@ -351,5 +378,6 @@ void mj_process_ducky_script(
|
|||
addr_size,
|
||||
rate,
|
||||
hid_payload,
|
||||
LOGITECH_HID_TEMPLATE_SIZE); // empty hid packet at end
|
||||
LOGITECH_HID_TEMPLATE_SIZE,
|
||||
plugin_state); // empty hid packet at end
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include <nrf24.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -19,12 +20,23 @@ typedef struct {
|
|||
uint8_t mod;
|
||||
} MJDuckyKey;
|
||||
|
||||
typedef struct {
|
||||
bool ducky_err;
|
||||
bool addr_err;
|
||||
bool is_thread_running;
|
||||
bool close_thread_please;
|
||||
Storage* storage;
|
||||
FuriThread* mjthread;
|
||||
Stream* file_stream;
|
||||
} PluginState;
|
||||
|
||||
void mj_process_ducky_script(
|
||||
FuriHalSpiBusHandle* handle,
|
||||
uint8_t* addr,
|
||||
uint8_t addr_size,
|
||||
uint8_t rate,
|
||||
char* script);
|
||||
char* script,
|
||||
PluginState* plugin_state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
App(
|
||||
appid="sub_playlist",
|
||||
name=".sub Playlist",
|
||||
name="Sub-GHz Playlist",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="playlist_app",
|
||||
cdefines=["APP_PLAYLIST"],
|
||||
|
|
|
@ -310,6 +310,9 @@ static int32_t playlist_worker_thread(void* ctx) {
|
|||
++worker->meta->current_playlist_repetition;
|
||||
// send playlist
|
||||
worker->meta->current_count = 0;
|
||||
if(worker->ctl_request_exit) {
|
||||
break;
|
||||
}
|
||||
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
|
@ -464,7 +467,7 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
|||
canvas_draw_str_aligned(canvas, 1, 19, AlignLeft, AlignTop, string_get_cstr(temp_str));
|
||||
|
||||
if(app->meta->playlist_repetitions <= 0) {
|
||||
string_printf(temp_str, "Repeat: yes", app->meta->playlist_repetitions);
|
||||
string_printf(temp_str, "Repeat: inf", app->meta->playlist_repetitions);
|
||||
} else if(app->meta->playlist_repetitions == 1) {
|
||||
string_printf(temp_str, "Repeat: no", app->meta->playlist_repetitions);
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,7 @@ int playlist_count_playlist_items(Storage* storage, const char* file_path) {
|
|||
++count;
|
||||
}
|
||||
flipper_format_file_close(format);
|
||||
flipper_format_free(format);
|
||||
string_clear(data);
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@ App(
|
|||
cdefines=["APP_SPECTRUM_ANALYZER"],
|
||||
requires=["gui"],
|
||||
icon="A_SpectrumAnalyzer_14",
|
||||
stack_size=4 * 1024,
|
||||
stack_size=2 * 1024,
|
||||
order=12,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
App(
|
||||
appid="subbrute",
|
||||
name="SubGHz Bruteforcer",
|
||||
name="Sub-GHz Bruteforcer",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="subbrute_start",
|
||||
cdefines=["APP_SUB_BRUTE"],
|
||||
|
|
|
@ -162,7 +162,7 @@ void subbrute_scene_entrypoint_on_draw(Canvas* canvas, SubBruteState* context) {
|
|||
|
||||
// Title
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 64, 6, AlignCenter, AlignTop, "SubGHz Fuzzer");
|
||||
canvas_draw_str_aligned(canvas, 64, 6, AlignCenter, AlignTop, "Sub-GHz Bruteforcer");
|
||||
|
||||
if(context->menu_index > SubBruteAttackLoadFile) {
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
|
|
@ -134,6 +134,7 @@ bool subbrute_load(SubBruteState* context, const char* file_path) {
|
|||
string_clear(temp_str);
|
||||
flipper_format_file_close(fff_data_file);
|
||||
flipper_format_free(fff_data_file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
if(result) {
|
||||
FURI_LOG_I(TAG, "Loaded successfully");
|
||||
string_reset(context->notification_msg);
|
||||
|
@ -197,6 +198,9 @@ bool subbrute_load_protocol_from_file(SubBruteState* context) {
|
|||
string_t file_path;
|
||||
string_init(file_path);
|
||||
string_set_str(file_path, SUBGHZ_APP_PATH_FOLDER);
|
||||
context->environment = subghz_environment_alloc();
|
||||
context->receiver = subghz_receiver_alloc_init(context->environment);
|
||||
subghz_receiver_set_filter(context->receiver, SubGhzProtocolFlag_Decodable);
|
||||
|
||||
// Input events and views are managed by file_select
|
||||
bool res = dialog_file_browser_show(
|
||||
|
@ -206,6 +210,9 @@ bool subbrute_load_protocol_from_file(SubBruteState* context) {
|
|||
res = subbrute_load(context, string_get_cstr(file_path));
|
||||
}
|
||||
|
||||
subghz_environment_free(context->environment);
|
||||
subghz_receiver_free(context->receiver);
|
||||
|
||||
string_clear(file_path);
|
||||
|
||||
return res;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <lib/subghz/transmitter.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
uint64_t subbrute_counter = 0;
|
||||
//uint64_t subbrute_counter = 0;
|
||||
uint64_t max_value;
|
||||
bool locked = false;
|
||||
bool toSave = false;
|
||||
|
@ -63,8 +63,8 @@ void prepare_emit(SubBruteState* context) {
|
|||
void clear_emit(SubBruteState* context) {
|
||||
UNUSED(context);
|
||||
|
||||
furi_hal_subghz_stop_async_tx();
|
||||
furi_hal_subghz_idle();
|
||||
//furi_hal_subghz_stop_async_tx();
|
||||
//furi_hal_subghz_idle();
|
||||
furi_hal_subghz_sleep();
|
||||
}
|
||||
/*
|
||||
|
@ -172,8 +172,6 @@ void subbrute_send_packet_parsed(SubBruteState* context) {
|
|||
|
||||
stream_clean(context->stream);
|
||||
stream_write_string(context->stream, context->flipper_format_string);
|
||||
|
||||
subbrute_emit(context);
|
||||
}
|
||||
|
||||
void subbrute_send_packet(SubBruteState* context) {
|
||||
|
@ -181,6 +179,7 @@ void subbrute_send_packet(SubBruteState* context) {
|
|||
// subbrute_send_raw_packet(context);
|
||||
//} else {
|
||||
subbrute_send_packet_parsed(context);
|
||||
subbrute_emit(context);
|
||||
//}
|
||||
string_clear(context->flipper_format_string);
|
||||
}
|
||||
|
@ -189,6 +188,9 @@ void subbrute_scene_run_attack_on_exit(SubBruteState* context) {
|
|||
if(!toSave) {
|
||||
clear_emit(context);
|
||||
furi_thread_free(context->bruthread);
|
||||
flipper_format_free(context->flipper_format);
|
||||
subghz_receiver_free(context->receiver);
|
||||
subghz_environment_free(context->environment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,8 +203,8 @@ void subbrute_scene_run_attack_on_tick(SubBruteState* context) {
|
|||
subbrute_send_packet(context);
|
||||
|
||||
if(context->payload == max_value) {
|
||||
context->payload = 0x00;
|
||||
subbrute_counter = 0;
|
||||
//context->payload = 0x00;
|
||||
//subbrute_counter = 0;
|
||||
context->is_attacking = false;
|
||||
notification_message(context->notify, &sequence_blink_stop);
|
||||
notification_message(context->notify, &sequence_single_vibro);
|
||||
|
@ -219,7 +221,7 @@ void subbrute_scene_run_attack_on_tick(SubBruteState* context) {
|
|||
}
|
||||
void subbrute_run_timer(SubBruteState* context) {
|
||||
while(true) {
|
||||
if(context->close_thread_please) {
|
||||
if(!context->is_attacking) {
|
||||
context->is_thread_running = false;
|
||||
break;
|
||||
}
|
||||
|
@ -260,6 +262,8 @@ void subbrute_scene_run_attack_on_enter(SubBruteState* context) {
|
|||
context->flipper_format = flipper_format_string_alloc();
|
||||
context->stream = flipper_format_get_raw_stream(context->flipper_format);
|
||||
context->environment = subghz_environment_alloc();
|
||||
context->receiver = subghz_receiver_alloc_init(context->environment);
|
||||
subghz_receiver_set_filter(context->receiver, SubGhzProtocolFlag_Decodable);
|
||||
|
||||
prepare_emit(context);
|
||||
context->bruthread = furi_thread_alloc();
|
||||
|
@ -280,6 +284,8 @@ void subbrute_scene_run_attack_on_event(SubBruteEvent event, SubBruteState* cont
|
|||
break;
|
||||
case InputKeyUp:
|
||||
if(!context->is_attacking) {
|
||||
subbrute_send_packet_parsed(context);
|
||||
string_clear(context->flipper_format_string);
|
||||
toSave = true;
|
||||
context->current_scene = SceneSaveName;
|
||||
}
|
||||
|
@ -289,6 +295,10 @@ void subbrute_scene_run_attack_on_event(SubBruteEvent event, SubBruteState* cont
|
|||
context->payload--;
|
||||
subbrute_send_packet(context);
|
||||
notification_message(context->notify, &sequence_blink_blue_10);
|
||||
} else if(!context->is_attacking && context->payload == 0x00) {
|
||||
context->payload = max_value;
|
||||
subbrute_send_packet(context);
|
||||
notification_message(context->notify, &sequence_blink_blue_10);
|
||||
}
|
||||
break;
|
||||
case InputKeyRight:
|
||||
|
@ -296,35 +306,43 @@ void subbrute_scene_run_attack_on_event(SubBruteEvent event, SubBruteState* cont
|
|||
context->payload++;
|
||||
subbrute_send_packet(context);
|
||||
notification_message(context->notify, &sequence_blink_blue_10);
|
||||
} else if(!context->is_attacking && context->payload == max_value) {
|
||||
context->payload = 0x00;
|
||||
subbrute_send_packet(context);
|
||||
notification_message(context->notify, &sequence_blink_blue_10);
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(!context->is_attacking) {
|
||||
if(context->payload == max_value) {
|
||||
context->payload = 0x00;
|
||||
//subbrute_counter = 0;
|
||||
}
|
||||
context->is_attacking = true;
|
||||
start_bruthread(context);
|
||||
notification_message(context->notify, &sequence_blink_start_blue);
|
||||
} else {
|
||||
context->is_attacking = false;
|
||||
context->close_thread_please = true;
|
||||
//context->close_thread_please = true;
|
||||
if(context->is_thread_running && context->bruthread) {
|
||||
furi_thread_join(context->bruthread); // wait until thread is finished
|
||||
}
|
||||
context->close_thread_please = false;
|
||||
//context->close_thread_please = false;
|
||||
notification_message(context->notify, &sequence_blink_stop);
|
||||
notification_message(context->notify, &sequence_single_vibro);
|
||||
}
|
||||
break;
|
||||
case InputKeyBack:
|
||||
locked = false;
|
||||
context->close_thread_please = true;
|
||||
//context->close_thread_please = true;
|
||||
context->is_attacking = false;
|
||||
if(context->is_thread_running && context->bruthread) {
|
||||
furi_thread_join(context->bruthread); // wait until thread is finished
|
||||
}
|
||||
context->close_thread_please = false;
|
||||
//context->close_thread_please = false;
|
||||
string_reset(context->notification_msg);
|
||||
context->payload = 0x00;
|
||||
subbrute_counter = 0;
|
||||
//subbrute_counter = 0;
|
||||
notification_message(context->notify, &sequence_blink_stop);
|
||||
if(context->attack == SubBruteAttackLoadFile) {
|
||||
context->current_scene = SceneSelectField;
|
||||
|
|
|
@ -75,10 +75,8 @@ SubBruteState* subbrute_alloc() {
|
|||
|
||||
subbrute->preset_def = malloc(sizeof(SubGhzPresetDefinition));
|
||||
|
||||
subbrute->flipper_format = flipper_format_string_alloc();
|
||||
subbrute->environment = subghz_environment_alloc();
|
||||
subbrute->receiver = subghz_receiver_alloc_init(subbrute->environment);
|
||||
subghz_receiver_set_filter(subbrute->receiver, SubGhzProtocolFlag_Decodable);
|
||||
//subbrute->flipper_format = flipper_format_string_alloc();
|
||||
//subbrute->environment = subghz_environment_alloc();
|
||||
|
||||
return subbrute;
|
||||
}
|
||||
|
@ -103,9 +101,9 @@ void subbrute_free(SubBruteState* subbrute) {
|
|||
string_clear(subbrute->candidate);
|
||||
string_clear(subbrute->flipper_format_string);
|
||||
|
||||
flipper_format_free(subbrute->flipper_format);
|
||||
subghz_environment_free(subbrute->environment);
|
||||
subghz_receiver_free(subbrute->receiver);
|
||||
//flipper_format_free(subbrute->flipper_format);
|
||||
//subghz_environment_free(subbrute->environment);
|
||||
//subghz_receiver_free(subbrute->receiver);
|
||||
|
||||
free(subbrute->preset_def);
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ FIRMWARE_APPS = {
|
|||
# Svc
|
||||
"basic_services",
|
||||
# Apps
|
||||
#"basic_apps",
|
||||
"basic_apps",
|
||||
"updater_app",
|
||||
"storage_move_to_sd",
|
||||
"archive",
|
||||
|
@ -109,7 +109,7 @@ FIRMWARE_APPS = {
|
|||
# Plugins
|
||||
#"basic_plugins",
|
||||
# Debug
|
||||
"debug_apps",
|
||||
#"debug_apps",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ extern uint32_t SystemCoreClock;
|
|||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
|
@ -145,3 +145,7 @@ standard names. */
|
|||
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1
|
||||
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION \
|
||||
1 /* required only for Keil but does not hurt otherwise */
|
||||
|
||||
#define traceTASK_SWITCHED_IN() \
|
||||
extern void furi_hal_mpu_set_stack_protection(uint32_t* stack); \
|
||||
furi_hal_mpu_set_stack_protection((uint32_t*)pxCurrentTCB->pxStack)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <furi_hal.h>
|
||||
#include <furi_hal_memory.h>
|
||||
#include <furi_hal_mpu.h>
|
||||
|
||||
#include <stm32wbxx_ll_cortex.h>
|
||||
|
||||
|
@ -36,6 +37,7 @@ void furi_hal_deinit_early() {
|
|||
}
|
||||
|
||||
void furi_hal_init() {
|
||||
furi_hal_mpu_init();
|
||||
furi_hal_clock_init();
|
||||
furi_hal_console_init();
|
||||
furi_hal_rtc_init();
|
||||
|
@ -82,17 +84,6 @@ void furi_hal_init() {
|
|||
// FatFS driver initialization
|
||||
MX_FATFS_Init();
|
||||
FURI_LOG_I(TAG, "FATFS OK");
|
||||
|
||||
// Partial null pointer dereference protection
|
||||
LL_MPU_Disable();
|
||||
LL_MPU_ConfigRegion(
|
||||
LL_MPU_REGION_NUMBER0,
|
||||
0x00,
|
||||
0x0,
|
||||
LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | LL_MPU_ACCESS_BUFFERABLE |
|
||||
LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | LL_MPU_TEX_LEVEL1 |
|
||||
LL_MPU_INSTRUCTION_ACCESS_ENABLE);
|
||||
LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT);
|
||||
}
|
||||
|
||||
void furi_hal_switch(void* address) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <stm32wbxx.h>
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_cortex.h>
|
||||
|
||||
#define TAG "FuriHalInterrupt"
|
||||
|
||||
|
@ -95,6 +96,10 @@ void furi_hal_interrupt_init() {
|
|||
LL_SYSCFG_DisableIT_FPU_IDC();
|
||||
LL_SYSCFG_DisableIT_FPU_IXC();
|
||||
|
||||
LL_HANDLER_EnableFault(LL_HANDLER_FAULT_USG);
|
||||
LL_HANDLER_EnableFault(LL_HANDLER_FAULT_BUS);
|
||||
LL_HANDLER_EnableFault(LL_HANDLER_FAULT_MEM);
|
||||
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
}
|
||||
|
||||
|
@ -241,6 +246,20 @@ void HardFault_Handler() {
|
|||
}
|
||||
|
||||
void MemManage_Handler() {
|
||||
if(FURI_BIT(SCB->CFSR, SCB_CFSR_MMARVALID_Pos)) {
|
||||
uint32_t memfault_address = SCB->MMFAR;
|
||||
if(memfault_address < (1024 * 1024)) {
|
||||
// from 0x00 to 1MB, see FuriHalMpuRegionNULL
|
||||
furi_crash("NULL pointer dereference");
|
||||
} else {
|
||||
// write or read of MPU region 1 (FuriHalMpuRegionStack)
|
||||
furi_crash("MPU fault, possibly stack overflow");
|
||||
}
|
||||
} else if(FURI_BIT(SCB->CFSR, SCB_CFSR_MSTKERR_Pos)) {
|
||||
// push to stack on MPU region 1 (FuriHalMpuRegionStack)
|
||||
furi_crash("MemManage fault, possibly stack overflow");
|
||||
}
|
||||
|
||||
furi_crash("MemManage");
|
||||
}
|
||||
|
||||
|
|
66
firmware/targets/f7/furi_hal/furi_hal_mpu.c
Normal file
66
firmware/targets/f7/furi_hal/furi_hal_mpu.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <furi_hal_mpu.h>
|
||||
#include <stm32wbxx_ll_cortex.h>
|
||||
|
||||
#define FURI_HAL_MPU_ATTRIBUTES \
|
||||
(LL_MPU_ACCESS_BUFFERABLE | LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | \
|
||||
LL_MPU_TEX_LEVEL1 | LL_MPU_INSTRUCTION_ACCESS_ENABLE)
|
||||
|
||||
#define FURI_HAL_MPU_STACK_PROTECT_REGION FuriHalMPURegionSize32B
|
||||
|
||||
void furi_hal_mpu_init() {
|
||||
furi_hal_mpu_enable();
|
||||
|
||||
// NULL pointer dereference protection
|
||||
furi_hal_mpu_protect_no_access(FuriHalMpuRegionNULL, 0x00, FuriHalMPURegionSize1MB);
|
||||
}
|
||||
|
||||
void furi_hal_mpu_enable() {
|
||||
LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT);
|
||||
}
|
||||
|
||||
void furi_hal_mpu_disable() {
|
||||
LL_MPU_Disable();
|
||||
}
|
||||
|
||||
void furi_hal_mpu_protect_no_access(
|
||||
FuriHalMpuRegion region,
|
||||
uint32_t address,
|
||||
FuriHalMPURegionSize size) {
|
||||
uint32_t size_ll = size;
|
||||
size_ll = size_ll << MPU_RASR_SIZE_Pos;
|
||||
|
||||
furi_hal_mpu_disable();
|
||||
LL_MPU_ConfigRegion(
|
||||
region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_NO_ACCESS | size_ll);
|
||||
furi_hal_mpu_enable();
|
||||
}
|
||||
|
||||
void furi_hal_mpu_protect_read_only(
|
||||
FuriHalMpuRegion region,
|
||||
uint32_t address,
|
||||
FuriHalMPURegionSize size) {
|
||||
uint32_t size_ll = size;
|
||||
size_ll = size_ll << MPU_RASR_SIZE_Pos;
|
||||
|
||||
furi_hal_mpu_disable();
|
||||
LL_MPU_ConfigRegion(
|
||||
region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_PRIV_RO_URO | size_ll);
|
||||
furi_hal_mpu_enable();
|
||||
}
|
||||
|
||||
void furi_hal_mpu_protect_disable(FuriHalMpuRegion region) {
|
||||
furi_hal_mpu_disable();
|
||||
LL_MPU_DisableRegion(region);
|
||||
furi_hal_mpu_enable();
|
||||
}
|
||||
|
||||
void furi_hal_mpu_set_stack_protection(uint32_t* stack) {
|
||||
// Protection area address must be aligned to region size
|
||||
uint32_t stack_ptr = (uint32_t)stack;
|
||||
uint32_t mask = ((1 << (FURI_HAL_MPU_STACK_PROTECT_REGION + 2)) - 1);
|
||||
stack_ptr &= ~mask;
|
||||
if(stack_ptr < (uint32_t)stack) stack_ptr += (mask + 1);
|
||||
|
||||
furi_hal_mpu_protect_read_only(
|
||||
FuriHalMpuRegionStack, stack_ptr, FURI_HAL_MPU_STACK_PROTECT_REGION);
|
||||
}
|
86
firmware/targets/furi_hal_include/furi_hal_mpu.h
Normal file
86
firmware/targets/furi_hal_include/furi_hal_mpu.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @file furi_hal_light.h
|
||||
* Light control HAL API
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FuriHalMpuRegionNULL = 0x00, // region 0 used to protect null pointer dereference
|
||||
FuriHalMpuRegionStack = 0x01, // region 1 used to protect stack
|
||||
FuriHalMpuRegion2 = 0x02,
|
||||
FuriHalMpuRegion3 = 0x03,
|
||||
FuriHalMpuRegion4 = 0x04,
|
||||
FuriHalMpuRegion5 = 0x05,
|
||||
FuriHalMpuRegion6 = 0x06,
|
||||
FuriHalMpuRegion7 = 0x07,
|
||||
} FuriHalMpuRegion;
|
||||
|
||||
typedef enum {
|
||||
FuriHalMPURegionSize32B = 0x04U,
|
||||
FuriHalMPURegionSize64B = 0x05U,
|
||||
FuriHalMPURegionSize128B = 0x06U,
|
||||
FuriHalMPURegionSize256B = 0x07U,
|
||||
FuriHalMPURegionSize512B = 0x08U,
|
||||
FuriHalMPURegionSize1KB = 0x09U,
|
||||
FuriHalMPURegionSize2KB = 0x0AU,
|
||||
FuriHalMPURegionSize4KB = 0x0BU,
|
||||
FuriHalMPURegionSize8KB = 0x0CU,
|
||||
FuriHalMPURegionSize16KB = 0x0DU,
|
||||
FuriHalMPURegionSize32KB = 0x0EU,
|
||||
FuriHalMPURegionSize64KB = 0x0FU,
|
||||
FuriHalMPURegionSize128KB = 0x10U,
|
||||
FuriHalMPURegionSize256KB = 0x11U,
|
||||
FuriHalMPURegionSize512KB = 0x12U,
|
||||
FuriHalMPURegionSize1MB = 0x13U,
|
||||
FuriHalMPURegionSize2MB = 0x14U,
|
||||
FuriHalMPURegionSize4MB = 0x15U,
|
||||
FuriHalMPURegionSize8MB = 0x16U,
|
||||
FuriHalMPURegionSize16MB = 0x17U,
|
||||
FuriHalMPURegionSize32MB = 0x18U,
|
||||
FuriHalMPURegionSize64MB = 0x19U,
|
||||
FuriHalMPURegionSize128MB = 0x1AU,
|
||||
FuriHalMPURegionSize256MB = 0x1BU,
|
||||
FuriHalMPURegionSize512MB = 0x1CU,
|
||||
FuriHalMPURegionSize1GB = 0x1DU,
|
||||
FuriHalMPURegionSize2GB = 0x1EU,
|
||||
FuriHalMPURegionSize4GB = 0x1FU,
|
||||
} FuriHalMPURegionSize;
|
||||
|
||||
/**
|
||||
* @brief Initialize memory protection unit
|
||||
*/
|
||||
void furi_hal_mpu_init();
|
||||
|
||||
/**
|
||||
* @brief Enable memory protection unit
|
||||
*/
|
||||
void furi_hal_mpu_enable();
|
||||
|
||||
/**
|
||||
* @brief Disable memory protection unit
|
||||
*/
|
||||
void furi_hal_mpu_disable();
|
||||
|
||||
void furi_hal_mpu_protect_no_access(
|
||||
FuriHalMpuRegion region,
|
||||
uint32_t address,
|
||||
FuriHalMPURegionSize size);
|
||||
|
||||
void furi_hal_mpu_protect_read_only(
|
||||
FuriHalMpuRegion region,
|
||||
uint32_t address,
|
||||
FuriHalMPURegionSize size);
|
||||
|
||||
void furi_hal_mpu_protect_disable(FuriHalMpuRegion region);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -37,10 +37,8 @@ void* calloc(size_t count, size_t size) {
|
|||
}
|
||||
|
||||
char* strdup(const char* s) {
|
||||
const char* s_null = s;
|
||||
if(s_null == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// arg s marked as non-null, so we need hack to check for NULL
|
||||
furi_check(((uint32_t)s << 2) != 0);
|
||||
|
||||
size_t siz = strlen(s) + 1;
|
||||
char* y = pvPortMalloc(siz);
|
||||
|
|
|
@ -504,7 +504,7 @@ uint8_t nrf24_find_channel(
|
|||
}
|
||||
|
||||
if(autoinit) {
|
||||
FURI_LOG_I("nrf24", "initializing radio for channel %d", ch);
|
||||
FURI_LOG_D("nrf24", "initializing radio for channel %d", ch);
|
||||
nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false);
|
||||
return ch;
|
||||
}
|
||||
|
|
|
@ -140,6 +140,9 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc
|
|||
uint64_t man = 0;
|
||||
uint64_t code_found_reverse;
|
||||
int res = 0;
|
||||
if(instance->manufacture_name == 0x0) {
|
||||
instance->manufacture_name = "";
|
||||
}
|
||||
|
||||
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
||||
code_found_reverse = subghz_protocol_blocks_reverse_key(
|
||||
|
@ -559,6 +562,9 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
|||
uint32_t decrypt = 0;
|
||||
uint64_t man;
|
||||
int res = 0;
|
||||
if(mfname == 0x0) {
|
||||
mfname = "";
|
||||
}
|
||||
|
||||
if(strcmp(mfname, "") == 0) {
|
||||
for
|
||||
|
|
Loading…
Reference in a new issue