diff --git a/applications/arkanoid/application.fam b/applications/arkanoid/application.fam index 6c4600b4b..fc7aeee4a 100644 --- a/applications/arkanoid/application.fam +++ b/applications/arkanoid/application.fam @@ -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, ) diff --git a/applications/flipfrid/application.fam b/applications/flipfrid/application.fam index 4bcb38139..c8d960ec5 100644 --- a/applications/flipfrid/application.fam +++ b/applications/flipfrid/application.fam @@ -6,5 +6,5 @@ App( cdefines=["APP_FLIP_FRID"], requires=["gui"], stack_size=1 * 1024, - order=13, + order=15, ) diff --git a/applications/mousejacker/mousejacker.c b/applications/mousejacker/mousejacker.c index d651496f7..92f26003a 100644 --- a/applications/mousejacker/mousejacker.c +++ b/applications/mousejacker/mousejacker.c @@ -9,7 +9,6 @@ #include #include #include -#include #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; } \ No newline at end of file diff --git a/applications/mousejacker/mousejacker_ducky.c b/applications/mousejacker/mousejacker_ducky.c index 56fff941e..f323a93da 100644 --- a/applications/mousejacker/mousejacker_ducky.c +++ b/applications/mousejacker/mousejacker_ducky.c @@ -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 } \ No newline at end of file diff --git a/applications/mousejacker/mousejacker_ducky.h b/applications/mousejacker/mousejacker_ducky.h index 07f61cbc5..a70a771e8 100644 --- a/applications/mousejacker/mousejacker_ducky.h +++ b/applications/mousejacker/mousejacker_ducky.h @@ -8,6 +8,7 @@ #include #include #include +#include #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 } diff --git a/applications/playlist/application.fam b/applications/playlist/application.fam index df750d2c4..27c3e96f4 100644 --- a/applications/playlist/application.fam +++ b/applications/playlist/application.fam @@ -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"], diff --git a/applications/playlist/playlist.c b/applications/playlist/playlist.c index 246774598..806940607 100644 --- a/applications/playlist/playlist.c +++ b/applications/playlist/playlist.c @@ -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 { diff --git a/applications/playlist/playlist_file.c b/applications/playlist/playlist_file.c index 3f7e28180..2faf02a3c 100644 --- a/applications/playlist/playlist_file.c +++ b/applications/playlist/playlist_file.c @@ -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; } diff --git a/applications/spectrum_analyzer/application.fam b/applications/spectrum_analyzer/application.fam index 2b60f928a..563e3d614 100644 --- a/applications/spectrum_analyzer/application.fam +++ b/applications/spectrum_analyzer/application.fam @@ -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, ) diff --git a/applications/subbrute/application.fam b/applications/subbrute/application.fam index 2608cba8f..51b429162 100644 --- a/applications/subbrute/application.fam +++ b/applications/subbrute/application.fam @@ -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"], diff --git a/applications/subbrute/scene/subbrute_scene_entrypoint.c b/applications/subbrute/scene/subbrute_scene_entrypoint.c index 130ba0012..267c1d82f 100644 --- a/applications/subbrute/scene/subbrute_scene_entrypoint.c +++ b/applications/subbrute/scene/subbrute_scene_entrypoint.c @@ -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); diff --git a/applications/subbrute/scene/subbrute_scene_load_file.c b/applications/subbrute/scene/subbrute_scene_load_file.c index 0f6d953f7..064e6facc 100644 --- a/applications/subbrute/scene/subbrute_scene_load_file.c +++ b/applications/subbrute/scene/subbrute_scene_load_file.c @@ -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; diff --git a/applications/subbrute/scene/subbrute_scene_run_attack.c b/applications/subbrute/scene/subbrute_scene_run_attack.c index 89d8c291c..4b4507882 100644 --- a/applications/subbrute/scene/subbrute_scene_run_attack.c +++ b/applications/subbrute/scene/subbrute_scene_run_attack.c @@ -2,7 +2,7 @@ #include #include -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; diff --git a/applications/subbrute/subbrute.c b/applications/subbrute/subbrute.c index bf5c2295d..e8f447c5e 100644 --- a/applications/subbrute/subbrute.c +++ b/applications/subbrute/subbrute.c @@ -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); diff --git a/fbt_options.py b/fbt_options.py index ab70ae8ae..c94d18da0 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -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", ], } diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index 1df5fce78..ab2dc14ef 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -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) diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index dc3b1637e..662ada619 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -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) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index fa595921a..038ae9489 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -6,6 +6,7 @@ #include #include #include +#include #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"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_mpu.c b/firmware/targets/f7/furi_hal/furi_hal_mpu.c new file mode 100644 index 000000000..ea6cd55be --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_mpu.c @@ -0,0 +1,66 @@ +#include +#include + +#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); +} \ No newline at end of file diff --git a/firmware/targets/furi_hal_include/furi_hal_mpu.h b/firmware/targets/furi_hal_include/furi_hal_mpu.h new file mode 100644 index 000000000..5dddadeb6 --- /dev/null +++ b/firmware/targets/furi_hal_include/furi_hal_mpu.h @@ -0,0 +1,86 @@ +/** + * @file furi_hal_light.h + * Light control HAL API + */ + +#pragma once + +#include +#include + +#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 diff --git a/furi/core/memmgr.c b/furi/core/memmgr.c index 6bad14027..dba1a7074 100644 --- a/furi/core/memmgr.c +++ b/furi/core/memmgr.c @@ -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); diff --git a/lib/drivers/nrf24.c b/lib/drivers/nrf24.c index e70acad65..2905072d3 100644 --- a/lib/drivers/nrf24.c +++ b/lib/drivers/nrf24.c @@ -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; } diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index a0953b1df..ab1626a6f 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -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