fixes and impovements

This commit is contained in:
MX 2022-09-11 02:09:02 +03:00
parent f94517fdab
commit bcaf898c57
No known key found for this signature in database
GPG Key ID: 6C4C311DFD4B4AB5
13 changed files with 217 additions and 115 deletions

View File

@ -6,5 +6,5 @@ App(
cdefines=["APP_FLIP_FRID"],
requires=["gui"],
stack_size=1 * 1024,
order=13,
order=15,
)

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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"],

View File

@ -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 {

View File

@ -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;
}

View File

@ -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"],

View File

@ -163,7 +163,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);

View File

@ -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;

View File

@ -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();
}
/*
@ -189,6 +189,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 +204,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 +222,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 +263,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();
@ -289,6 +294,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 +305,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;

View File

@ -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);

View File

@ -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;
}