mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-25 06:13:14 +03:00
fixes and impovements
This commit is contained in:
parent
f94517fdab
commit
bcaf898c57
@ -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;
|
||||
}
|
||||
|
@ -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"],
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
/*
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user