Skip to content

Commit

Permalink
v0.1.5 Added experimental USB injection (boot) mode + fixes according…
Browse files Browse the repository at this point in the history
… to changelog
  • Loading branch information
mame82 committed Sep 2, 2019
1 parent 5109d26 commit 0fd5005
Show file tree
Hide file tree
Showing 22 changed files with 355 additions and 101 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# LOGITacker v0.1.5-beta

- experimental USB injection support with `inject target USB`
- introduction of `options global bootmode` to toggle between USB injection and default behavior
- script used for USB injection on boot is set with `options inject default-script <scriptname>`, the respective script
has to be stored with the proper name using `script store <scriptname>`
- fix: script storage, scriptname buffer not trimmed down to new length if new scriptname of successive storage attempts
gets shorter
- fix: issue #8 (typos for passive enum)
- Note: As the update changes the structure for persistent options `erase_flash` has to be executed once after update

# LOGITacker v0.1.4-beta

- experimental Logitech LIGHTSPEED support (G-Series, tested with G603)
Expand Down
2 changes: 1 addition & 1 deletion apr-dongle/blank/config/sdk_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,7 @@
// <i> Note: This value is not editable in Configuration Wizard.
// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRING_SERIAL
#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("v0.1.4-beta")
#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("v0.1.5-beta")
#endif

// </e>
Expand Down
105 changes: 69 additions & 36 deletions logitacker/logitacker.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,49 @@
#include "logitacker_script_engine.h"

#define NRF_LOG_MODULE_NAME LOGITACKER

#include "nrf_log.h"

NRF_LOG_MODULE_REGISTER();

APP_TIMER_DEF(m_timer_next_tx_action);

static logitacker_processor_t * p_processor = NULL;
static logitacker_processor_t *p_processor = NULL;


typedef struct {
bool initialized;
logitacker_mode_t mainstate;
logitacker_mode_t mainstate;
} logitacker_state_t;


logitacker_state_t m_state_local;

static bool m_main_event_handler_bsp_long_pushed;

void main_event_handler_timer_next_action(void *p_context);

void main_event_handler_esb(nrf_esb_evt_t *p_event);

void main_event_handler_radio(radio_evt_t const *p_event);

static void main_event_handler_bsp(bsp_event_t ev);

/* main/master event handler */
void main_usbd_hid_keyboard_event_handler(app_usbd_class_inst_t const *p_inst, app_usbd_hid_user_event_t event) {
if (p_processor != NULL && p_processor->p_usb_hid_keyboard_event_handler != NULL)
(*p_processor->p_usb_hid_keyboard_event_handler)(p_processor, p_inst, event);
}


void main_event_handler_timer_next_action(void *p_context) {
if (p_processor != NULL && p_processor->p_timer_handler != NULL) (*p_processor->p_timer_handler)(p_processor, p_context); // call timer handler function of p_processor and hand in p_processor (self) as first arg
if (p_processor != NULL && p_processor->p_timer_handler != NULL)
(*p_processor->p_timer_handler)(p_processor,
p_context); // call timer handler function of p_processor and hand in p_processor (self) as first arg
}

void main_event_handler_esb(nrf_esb_evt_t *p_event) {
switch (p_event->evt_id)
{
switch (p_event->evt_id) {
case NRF_ESB_EVENT_TX_SUCCESS:
NRF_LOG_DEBUG("ESB EVENT HANDLER MAIN TX_SUCCESS");
break;
Expand All @@ -74,40 +86,39 @@ void main_event_handler_esb(nrf_esb_evt_t *p_event) {
break;
}

if (p_processor != NULL && p_processor->p_esb_handler != NULL) (*p_processor->p_esb_handler)(p_processor, p_event); // call ESB handler function of p_processor and hand in p_processor (self) as first arg
if (p_processor != NULL && p_processor->p_esb_handler != NULL)
(*p_processor->p_esb_handler)(p_processor,
p_event); // call ESB handler function of p_processor and hand in p_processor (self) as first arg
}

void main_event_handler_radio(radio_evt_t const *p_event) {
//helper_log_priority("UNIFYING_event_handler");
switch (p_event->evt_id)
{
case RADIO_EVENT_NO_RX_TIMEOUT:
{
switch (p_event->evt_id) {
case RADIO_EVENT_NO_RX_TIMEOUT: {
NRF_LOG_DEBUG("RADIO EVENT HANDLER MAIN: RX TIMEOUT");
break;
}
case RADIO_EVENT_CHANNEL_CHANGED_FIRST_INDEX:
{
case RADIO_EVENT_CHANNEL_CHANGED_FIRST_INDEX: {
NRF_LOG_DEBUG("RADIO EVENT HANDLER MAIN: CHANNEL CHANGED FIRST INDEX");
break;
}
case RADIO_EVENT_CHANNEL_CHANGED:
{
NRF_LOG_DEBUG("RADIO EVENT HANDLER MAIN: CHANNEL CHANGED (index %d, channel freq %d)", p_event->channel_index, p_event->channel);
case RADIO_EVENT_CHANNEL_CHANGED: {
NRF_LOG_DEBUG("RADIO EVENT HANDLER MAIN: CHANNEL CHANGED (index %d, channel freq %d)",
p_event->channel_index, p_event->channel);
break;
}
}

if (p_processor != NULL && p_processor->p_radio_handler != NULL) (*p_processor->p_radio_handler)(p_processor, p_event); // call ESB handler function of p_processor and hand in p_processor (self) as first arg
if (p_processor != NULL && p_processor->p_radio_handler != NULL)
(*p_processor->p_radio_handler)(p_processor,
p_event); // call ESB handler function of p_processor and hand in p_processor (self) as first arg
}

static void main_event_handler_bsp(bsp_event_t ev)
{
static void main_event_handler_bsp(bsp_event_t ev) {
// runs in interrupt mode
//helper_log_priority("bsp_event_callback");
//uint32_t ret;
switch ((unsigned int)ev)
{
switch ((unsigned int) ev) {
case CONCAT_2(BSP_EVENT_KEY_, BTN_TRIGGER_ACTION):
//Toggle radio back to promiscous mode
NRF_LOG_INFO("ACTION button pushed");
Expand All @@ -131,11 +142,12 @@ static void main_event_handler_bsp(bsp_event_t ev)
break; // no implementation needed
}

if (p_processor != NULL && p_processor->p_bsp_handler != NULL) (*p_processor->p_bsp_handler)(p_processor, ev); // call BSP handler function of p_processor and hand in p_processor (self) as first arg
if (p_processor != NULL && p_processor->p_bsp_handler != NULL)
(*p_processor->p_bsp_handler)(p_processor,
ev); // call BSP handler function of p_processor and hand in p_processor (self) as first arg
}



// Transfers execution to active_enum_process_sub_event
void logitacker_enter_mode_passive_enum(uint8_t *rf_address) {
if (p_processor != NULL && p_processor->p_deinit_func != NULL) (*p_processor->p_deinit_func)(p_processor);
Expand Down Expand Up @@ -178,6 +190,7 @@ void logitacker_enter_mode_active_enum(uint8_t *rf_address) {
}

static uint8_t temp_dev_id = 1;

void logitacker_enter_mode_pair_device(uint8_t const *rf_address) {
if (p_processor != NULL && p_processor->p_deinit_func != NULL) (*p_processor->p_deinit_func)(p_processor);

Expand All @@ -187,17 +200,18 @@ void logitacker_enter_mode_pair_device(uint8_t const *rf_address) {
.device_usability_info = LOGITACKER_DEVICE_USABILITY_INFO_PS_LOCATION_ON_THE_TOP_EDGE,
.device_nonce = {0xde, 0xad, 0xbe, 0xef},
.device_report_types = LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD |
LOGITACKER_DEVICE_REPORT_TYPES_POWER_KEYS |
LOGITACKER_DEVICE_REPORT_TYPES_MULTIMEDIA |
// LOGITACKER_DEVICE_REPORT_TYPES_MEDIA_CENTER |
LOGITACKER_DEVICE_REPORT_TYPES_MOUSE |
// LOGITACKER_DEVICE_REPORT_TYPES_SHORT_HIDPP |
// LOGITACKER_DEVICE_REPORT_TYPES_LONG_HIDPP |
LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD_LED,
.device_serial = { 0x2d, 0x9a, 0x9f, temp_dev_id++ },
.device_caps = LOGITACKER_DEVICE_CAPS_UNIFYING_COMPATIBLE | LOGITACKER_DEVICE_CAPS_LINK_ENCRYPTION, // use link encryption, to account for MouseJack patched firmwares
LOGITACKER_DEVICE_REPORT_TYPES_POWER_KEYS |
LOGITACKER_DEVICE_REPORT_TYPES_MULTIMEDIA |
// LOGITACKER_DEVICE_REPORT_TYPES_MEDIA_CENTER |
LOGITACKER_DEVICE_REPORT_TYPES_MOUSE |
// LOGITACKER_DEVICE_REPORT_TYPES_SHORT_HIDPP |
// LOGITACKER_DEVICE_REPORT_TYPES_LONG_HIDPP |
LOGITACKER_DEVICE_REPORT_TYPES_KEYBOARD_LED,
.device_serial = {0x2d, 0x9a, 0x9f, temp_dev_id++},
.device_caps = LOGITACKER_DEVICE_CAPS_UNIFYING_COMPATIBLE |
LOGITACKER_DEVICE_CAPS_LINK_ENCRYPTION, // use link encryption, to account for MouseJack patched firmwares
.device_type = LOGITACKER_DEVICE_UNIFYING_TYPE_KEYBOARD, // use keyboard, for latest receiver firmwares character keys [a-zA-Z] are blacklisted for non-keyboard devices
.device_wpid = { 0x13, 0x37 }, // random
.device_wpid = {0x13, 0x37}, // random
};
memcpy(pi.device_name, dev_name, pi.device_name_len);

Expand Down Expand Up @@ -246,14 +260,15 @@ void logitacker_injection_start_execution(bool execute) {
}
}

void clocks_start( void )
{
void clocks_start(void) {
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;

while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
}

uint8_t rf_addr_usb[5] = {0};

uint32_t logitacker_init() {
sprintf(g_logitacker_cli_name, "LOGITacker $ ");
logitacker_flash_init();
Expand All @@ -271,9 +286,27 @@ uint32_t logitacker_init() {
logitacker_radio_init(main_event_handler_esb, main_event_handler_radio);

// load default injection script
if (strlen(g_logitacker_global_config.default_script) > 0) logitacker_script_engine_load_script_from_flash(g_logitacker_global_config.default_script);
if (strlen(g_logitacker_global_config.default_script) > 0)
logitacker_script_engine_load_script_from_flash(g_logitacker_global_config.default_script);

logitacker_enter_mode_discovery();
switch (g_logitacker_global_config.bootmode) {
case OPTION_LOGITACKER_BOOTMODE_DISCOVER: {
logitacker_enter_mode_discovery();
}
break;
case OPTION_LOGITACKER_BOOTMODE_USB_INJECT: {
//enter inject mode for address 00:00:00:00:00 == USB
logitacker_enter_mode_injection(rf_addr_usb);
logitacker_injection_start_execution(true);
//execute injection
}
break;
default: {
logitacker_enter_mode_discovery(); //default for now
}
break;

}


return NRF_SUCCESS;
Expand Down
6 changes: 5 additions & 1 deletion logitacker/logitacker.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ extern "C" {
#endif


#include <libraries/usbd/app_usbd_types.h>
#include <libraries/usbd/class/hid/app_usbd_hid.h>
#include "stdint.h"
#include "nrf_cli.h"
#include "nrf_esb_illegalmod.h"
#include "logitacker_keyboard_map.h"

#define VERSION_STRING "v0.1.4-beta"
#define VERSION_STRING "v0.1.5-beta"

//#define PAIRING_REQ_MARKER_BYTE 0xee // byte used as device ID in pairing requests
#define ACTIVE_ENUM_INNER_LOOP_MAX 20 //how many CAPS presses / key releases get send
Expand Down Expand Up @@ -64,6 +66,8 @@ void logitacker_enter_mode_injection(uint8_t const *rf_address);

void logitacker_injection_start_execution(bool execute);

void main_usbd_hid_keyboard_event_handler(app_usbd_class_inst_t const *p_inst, app_usbd_hid_user_event_t event); //for pass-through in logitacker_usb.c

#ifdef __cplusplus
}
#endif
Expand Down
71 changes: 57 additions & 14 deletions logitacker/logitacker_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,25 @@ static void dynamic_device_addr_list_ram_with_all(size_t idx, nrf_cli_static_ent
}
}

static void dynamic_device_addr_list_ram_with_usb(size_t idx, nrf_cli_static_entry_t *p_static)
{
// Must be sorted alphabetically to ensure correct CLI completion.
p_static->handler = NULL;
p_static->p_subcmd = NULL;
p_static->p_help = "Connect with address.";


if (idx == 0) {
device_address_str_list_update(); // update list if idx 0 is requested
memcpy(m_device_addr_str_list[0], "USB\x00", 4);
p_static->p_syntax = m_device_addr_str_list[0];
} else if (idx < m_device_addr_str_list_len) {
p_static->p_syntax = m_device_addr_str_list[idx];
} else {
p_static->p_syntax = NULL;
}
}

// dynamic creation of command addresses
static void dynamic_device_addr_list_ram(size_t idx, nrf_cli_static_entry_t *p_static)
{
Expand Down Expand Up @@ -503,22 +522,27 @@ static void cmd_inject(nrf_cli_t const * p_cli, size_t argc, char **argv) {

static void cmd_inject_target(nrf_cli_t const * p_cli, size_t argc, char **argv)
{
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "inject target %s\r\n", argv[1]);

if (argc > 1)
{
nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_DEFAULT, "parameter count %d\r\n", argc);
//nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_DEFAULT, "parameter count %d\r\n", argc);

//parse arg 1 as address
uint8_t addr[5];
if (helper_hex_str_to_addr(addr, 5, argv[1]) != NRF_SUCCESS) {
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "invalid address parameter, format has to be xx:xx:xx:xx:xx\r\n");
return;
}

char tmp_addr_str[16];
helper_addr_to_hex_str(tmp_addr_str, 5, addr);
nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_GREEN, "Trying to send keystrokes using address %s\r\n", tmp_addr_str);

if (strcmp(argv[1], "USB") == 0) {
memset(addr,0x00,5);
nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_GREEN, "Trying to send keystrokes to USB keyboard interface\r\n");
} else {
if (helper_hex_str_to_addr(addr, 5, argv[1]) != NRF_SUCCESS) {
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "invalid address parameter, format has to be xx:xx:xx:xx:xx\r\n");
return;
}

char tmp_addr_str[16];
helper_addr_to_hex_str(tmp_addr_str, 5, addr);
nrf_cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_GREEN, "Trying to send keystrokes using address %s\r\n", tmp_addr_str);
}

//logitacker_keyboard_map_test();
logitacker_enter_mode_injection(addr);
Expand Down Expand Up @@ -650,6 +674,16 @@ static void cmd_option_global_workmode_lightspeed(nrf_cli_t const *p_cli, size_t
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "working mode set to LIGHTSPEED compatible\r\n");
}

static void cmd_option_global_bootmode_discover(nrf_cli_t const *p_cli, size_t argc, char **argv) {
g_logitacker_global_config.bootmode = OPTION_LOGITACKER_BOOTMODE_DISCOVER;
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "boot mode set to 'discover'\r\n");
}

static void cmd_option_global_bootmode_usbinject(nrf_cli_t const *p_cli, size_t argc, char **argv) {
g_logitacker_global_config.bootmode = OPTION_LOGITACKER_BOOTMODE_USB_INJECT;
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "boot mode set to 'usb inject'\r\n");
}

static void cmd_options_inject_lang(nrf_cli_t const *p_cli, size_t argc, char **argv) {
if (argc == 2)
{
Expand Down Expand Up @@ -1287,7 +1321,7 @@ NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_script)
NRF_CLI_CMD_REGISTER(script, &m_sub_script, "scripting for injection", cmd_inject);

//level 2
NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_inject_target_addr, dynamic_device_addr_list_ram);
NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_inject_target_addr, dynamic_device_addr_list_ram_with_usb);

// level 1
NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_inject)
Expand Down Expand Up @@ -1366,7 +1400,7 @@ NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_discover_onhit)
{
NRF_CLI_CMD(continue, NULL, "stay in discover mode.", cmd_discover_onhit_continue),
NRF_CLI_CMD(active-enum, NULL, "enter active enumeration mode", cmd_discover_onhit_activeenum),
NRF_CLI_CMD(passive-enum, NULL, "enter active enumeration mode", cmd_discover_onhit_passiveenum),
NRF_CLI_CMD(passive-enum, NULL, "enter passive enumeration mode", cmd_discover_onhit_passiveenum),
NRF_CLI_CMD(auto-inject, NULL, "enter injection mode and execute injection", cmd_discover_onhit_autoinject),
NRF_CLI_SUBCMD_SET_END
};
Expand Down Expand Up @@ -1409,7 +1443,7 @@ NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_inject_onsuccess)
{
NRF_CLI_CMD(continue, NULL, "stay in inject mode.", cmd_inject_onsuccess_continue),
NRF_CLI_CMD(active-enum, NULL, "enter active enumeration", cmd_inject_onsuccess_activeenum),
NRF_CLI_CMD(passive-enum, NULL, "enter active enumeration", cmd_inject_onsuccess_passiveenum),
NRF_CLI_CMD(passive-enum, NULL, "enter passive enumeration", cmd_inject_onsuccess_passiveenum),
NRF_CLI_CMD(discover, NULL, "enter discover mode", cmd_inject_onsuccess_discover),
NRF_CLI_SUBCMD_SET_END
};
Expand All @@ -1418,7 +1452,7 @@ NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_inject_onfail)
{
NRF_CLI_CMD(continue, NULL, "stay in inject mode.", cmd_inject_onfail_continue),
NRF_CLI_CMD(active-enum, NULL, "enter active enumeration", cmd_inject_onfail_activeenum),
NRF_CLI_CMD(passive-enum, NULL, "enter active enumeration", cmd_inject_onfail_passiveenum),
NRF_CLI_CMD(passive-enum, NULL, "enter passive enumeration", cmd_inject_onfail_passiveenum),
NRF_CLI_CMD(discover, NULL, "enter discover mode", cmd_inject_onfail_discover),
NRF_CLI_SUBCMD_SET_END
};
Expand Down Expand Up @@ -1448,10 +1482,19 @@ NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_global_workmode)
NRF_CLI_SUBCMD_SET_END
};

// options global workmode
NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_global_bootmode)
{
NRF_CLI_CMD(discover, NULL, "Boot in 'discover' mode.", cmd_option_global_bootmode_discover),
NRF_CLI_CMD(usbinject, NULL, "Boot in 'USB key stroke injection' mode.", cmd_option_global_bootmode_usbinject),
NRF_CLI_SUBCMD_SET_END
};

// options global
NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_options_global)
{
NRF_CLI_CMD(workmode, &m_sub_options_global_workmode, "LOGITacker working mode", cmd_help),
NRF_CLI_CMD(bootmode, &m_sub_options_global_bootmode, "LOGITacker boot mode", cmd_help),

NRF_CLI_SUBCMD_SET_END
};
Expand Down
Loading

0 comments on commit 0fd5005

Please sign in to comment.