diff --git a/Upstream/Inc/build_config.h b/Upstream/Inc/build_config.h index cd5c7cf..d1dc3a3 100644 --- a/Upstream/Inc/build_config.h +++ b/Upstream/Inc/build_config.h @@ -27,39 +27,49 @@ #ifdef CONFIG_KEYBOARD_BOT_DETECT_ENABLED //----------------------------------------------------------- //Adjust this threshold first to tune keyboard bot detection. Lower values = more sensitive - #define KEYBOARD_BOTDETECT_LOCKOUT_BIN_THRESHOLD 4 + #define KEYBOARD_BOTDETECT_LOCKOUT_BIN_THRESHOLD 4 //4 is a good setting for the paranoid. 5 is good for the average user who doesn't want to encounter a rare false-positive. //----------------------------------------------------------- - #define KEYBOARD_BOTDETECT_FAST_BIN_WIDTH_MS 10 //10ms per bin - #define KEYBOARD_BOTDETECT_SLOW_BIN_WIDTH_MS 20 //20ms per bin - #define KEYBOARD_BOTDETECT_FAST_BIN_COUNT 30 //30 bins at 10ms = 300ms fast coverage - #define KEYBOARD_BOTDETECT_SLOW_BIN_COUNT 50 //50 bins at 20ms = 1 sec slow coverage, wrapped - - #define KEYBOARD_BOTDETECT_FAST_BIN_DRAIN_DIVIDER 2 - #define KEYBOARD_BOTDETECT_SLOW_BIN_DRAIN_DIVIDER 4 + #define KEYBOARD_BOTDETECT_FAST_BIN_WIDTH_MS 10 //10ms per bin + #define KEYBOARD_BOTDETECT_SLOW_BIN_WIDTH_MS 20 //20ms per bin + #define KEYBOARD_BOTDETECT_FAST_BIN_COUNT 30 //30 bins at 10ms = 300ms fast coverage + #define KEYBOARD_BOTDETECT_SLOW_BIN_COUNT 50 //50 bins at 20ms = 1 sec slow coverage, wrapped + #define KEYBOARD_BOTDETECT_FAST_BIN_DRAIN_DIVIDER 2 + #define KEYBOARD_BOTDETECT_SLOW_BIN_DRAIN_DIVIDER 4 #endif + //Configure mouse bot detection here: #ifdef CONFIG_MOUSE_BOT_DETECT_ENABLED + #define MOUSE_BOTDETECT_VELOCITY_MULTIPLIER 10 + #define MOUSE_BOTDETECT_MOVEMENT_STOP_PERIODS 5 + //----------------------------------------------------------- - //Adjust this threshold first to tune mouse bot detection. Lower values = more sensitive - #define MOUSE_BOTDETECT_LOCKOUT_CONSTANT_ACCEL_COUNT 10 - //??????? + //Adjust these thresholds first to tune mouse bot detection. Lower values = more sensitive + #define MOUSE_BOTDETECT_JUMP_VELOCITY_THRESHOLD (20 * MOUSE_BOTDETECT_VELOCITY_MULTIPLIER) + #define MOUSE_BOTDETECT_LOCKOUT_CONSTANT_ACCEL_COUNT 20 //20 is ok for most mice. But some weird mice generate longer sequences. + #define MOUSE_BOTDETECT_LOCKOUT_JIGGLE_BIN_THRESHOLD 4 //----------------------------------------------------------- - #define MOUSE_BOTDETECT_VELOCITY_MULTIPLIER 10 - #define MOUSE_BOTDETECT_VELOCITY_HISTORY_SIZE 12 - #define MOUSE_BOTDETECT_VELOCITY_MATCH_BASE 256 - #define MOUSE_BOTDETECT_VELOCITY_MATCH_ERROR 6 + //Jump detection stuff + #define MOUSE_BOTDETECT_JUMP_MINIMUM_TIME 4 - #define MOUSE_BOTDETECT_MOVEMENT_STOP_PERIODS 5 - #define MOUSE_BOTDETECT_MOVEMENT_VELOCITY_THRESHOLD (10 * MOUSE_BOTDETECT_VELOCITY_MULTIPLIER) + //Constant acceleration detection stuff + #define MOUSE_BOTDETECT_VELOCITY_HISTORY_SIZE 12 + #define MOUSE_BOTDETECT_VELOCITY_MATCH_BASE 256 + #define MOUSE_BOTDETECT_VELOCITY_MATCH_ERROR 6 + + //Jiggle detection stuff + #define MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS 20 //20ms per bin + #define MOUSE_BOTDETECT_JIGGLE_BIN_COUNT 50 //50 bins at 20ms = 1 sec coverage, wrapped + #define MOUSE_BOTDETECT_JIGGLE_BIN_DIVIDER 4 #endif + //Configuration common to all bot detectors #if defined CONFIG_KEYBOARD_BOT_DETECT_ENABLED || defined CONFIG_MOUSE_BOT_DETECT_ENABLED - #define BOTDETECT_TEMPORARY_LOCKOUT_TIME_MS 4000 - #define BOTDETECT_TEMPORARY_LOCKOUT_FLASH_TIME_MS 60000 //Flash fault LED for 60 seconds after temporary lockout + #define BOTDETECT_TEMPORARY_LOCKOUT_TIME_MS 4000 //Lock keyboard/mouse for 4 seconds as a first warning + #define BOTDETECT_TEMPORARY_LOCKOUT_FLASH_TIME_MS 60000 //Flash fault LED for 60 seconds after warning lockout #endif diff --git a/Upstream/Src/upstream_hid_botdetect.c b/Upstream/Src/upstream_hid_botdetect.c index 0ab15ea..edd727a 100644 --- a/Upstream/Src/upstream_hid_botdetect.c +++ b/Upstream/Src/upstream_hid_botdetect.c @@ -55,19 +55,23 @@ volatile LockoutStateTypeDef LockoutState = LOCKOUT_STATE_INACTIVE; //Variables specific to mouse bot detection: #if defined (CONFIG_MOUSE_ENABLED) && defined (CONFIG_MOUSE_BOT_DETECT_ENABLED) - uint32_t LastMouseMoveTime = 0; - //Jump detection stuff + uint32_t LastMouseMoveTime = 0; uint32_t LastMouseMoveBeginTime; uint8_t MouseIsMoving = 0; //Constant acceleration detection stuff uint16_t MouseVelocityHistory[MOUSE_BOTDETECT_VELOCITY_HISTORY_SIZE] = {0}; - int32_t PreviousSmoothedAcceleration = 0; - uint8_t ConstantAccelerationCounter = 0; + int32_t PreviousSmoothedAcceleration = 0; + uint8_t ConstantAccelerationCounter = 0; + + //Jiggle detection stuff + uint8_t MouseStopIntervalBinDrainDivideCount = 0; + uint8_t MouseStopIntervalBinArray[MOUSE_BOTDETECT_JIGGLE_BIN_COUNT] = {0}; //Debug: uint8_t ConstantAccelerationCounterMax = 0; + uint8_t MouseStopIntervalBinArrayPeak = 0; static void Upstream_HID_BotDetectMouse_DoLockout(void); #endif @@ -387,6 +391,7 @@ void Upstream_HID_BotDetectMouse(uint8_t* mouseInData) { uint32_t i; uint32_t now = HAL_GetTick(); + uint32_t moveDelay; uint32_t velocity; int8_t mouseX; int8_t mouseY; @@ -402,15 +407,46 @@ void Upstream_HID_BotDetectMouse(uint8_t* mouseInData) mouseY = mouseInData[2]; velocity = (sqrtf(((int32_t)mouseX * mouseX) + ((int32_t)mouseY * mouseY))) * MOUSE_BOTDETECT_VELOCITY_MULTIPLIER; //Multiply floating-point sqrt result to avoid integer rounding errors + moveDelay = now - LastMouseMoveTime; - //Jump detection - if (MouseIsMoving) + //Did the mouse stop moving? + if (moveDelay > ((MOUSE_BOTDETECT_MOVEMENT_STOP_PERIODS * HID_FS_BINTERVAL) - (HID_FS_BINTERVAL / 2))) { - if ((now - LastMouseMoveTime) > ((MOUSE_BOTDETECT_MOVEMENT_STOP_PERIODS * HID_FS_BINTERVAL) - (HID_FS_BINTERVAL / 2))) //Did the mouse stop moving? + //Jiggle detection + if (velocity != 0) + { + //Add stopped time to jiggle bins + moveDelay = moveDelay % (MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS * MOUSE_BOTDETECT_JIGGLE_BIN_COUNT); //Wrap stopped time into the array + MouseStopIntervalBinArray[(moveDelay / MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS)]++; + if (MouseStopIntervalBinArray[(moveDelay / MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS)] > MOUSE_BOTDETECT_LOCKOUT_JIGGLE_BIN_THRESHOLD) + { + Upstream_HID_BotDetectMouse_DoLockout(); + } + + //Debug: + if (MouseStopIntervalBinArray[(moveDelay / MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS)] > MouseStopIntervalBinArrayPeak) + { + MouseStopIntervalBinArrayPeak = MouseStopIntervalBinArray[(moveDelay / MOUSE_BOTDETECT_JIGGLE_BIN_WIDTH_MS)]; + } + + //Drain jiggle bins at specified rate + MouseStopIntervalBinDrainDivideCount++; + if (MouseStopIntervalBinDrainDivideCount >= MOUSE_BOTDETECT_JIGGLE_BIN_DIVIDER) + { + MouseStopIntervalBinDrainDivideCount = 0; + for (i = 0; i < MOUSE_BOTDETECT_JIGGLE_BIN_COUNT; i++) + { + if (MouseStopIntervalBinArray[i] > 0) MouseStopIntervalBinArray[i]--; + } + } + } + + //Jump detection + if (MouseIsMoving) { MouseIsMoving = 0; - if ((LastMouseMoveTime - LastMouseMoveBeginTime) < ((MOUSE_BOTDETECT_MOVEMENT_STOP_PERIODS * HID_FS_BINTERVAL) - (HID_FS_BINTERVAL / 2))) + if ((LastMouseMoveTime - LastMouseMoveBeginTime) < ((MOUSE_BOTDETECT_JUMP_MINIMUM_TIME * HID_FS_BINTERVAL) - (HID_FS_BINTERVAL / 2))) { Upstream_HID_BotDetectMouse_DoLockout(); } @@ -422,13 +458,13 @@ void Upstream_HID_BotDetectMouse(uint8_t* mouseInData) { //Jump detection LastMouseMoveTime = now; - if ((MouseIsMoving == 0) && (velocity > MOUSE_BOTDETECT_MOVEMENT_VELOCITY_THRESHOLD)) + if ((MouseIsMoving == 0) && (velocity > MOUSE_BOTDETECT_JUMP_VELOCITY_THRESHOLD)) { MouseIsMoving = 1; LastMouseMoveBeginTime = now; } - //Look for periods of constant acceleration + //Constant acceleration detection for (i = (MOUSE_BOTDETECT_VELOCITY_HISTORY_SIZE - 1); i > 0; i--) //Shuffle down history data { MouseVelocityHistory[i] = MouseVelocityHistory[i - 1]; @@ -457,10 +493,10 @@ void Upstream_HID_BotDetectMouse(uint8_t* mouseInData) ((PreviousSmoothedAcceleration - smoothedAccelerationMatchError) <= newSmoothedAcceleration)) { ConstantAccelerationCounter++; -// if (ConstantAccelerationCounter > MOUSE_BOTDETECT_TEMPORARY_LOCKOUT_VELOCITY_THRESHOLD) -// { -// Upstream_HID_BotDetectMouse_DoLockout(); -// } + if (ConstantAccelerationCounter > MOUSE_BOTDETECT_LOCKOUT_CONSTANT_ACCEL_COUNT) + { + Upstream_HID_BotDetectMouse_DoLockout(); + } //Debug: if (ConstantAccelerationCounter > ConstantAccelerationCounterMax) ConstantAccelerationCounterMax = ConstantAccelerationCounter; @@ -512,6 +548,11 @@ static void Upstream_HID_BotDetectMouse_DoLockout(void) } ConstantAccelerationCounter = 0; + for (i = 0; i < MOUSE_BOTDETECT_JIGGLE_BIN_COUNT; i++) + { + MouseStopIntervalBinArray[i] = 0; + } + TemporaryLockoutTimeMs = 0; LockoutState = LOCKOUT_STATE_TEMPORARY_ACTIVE; LED_SetState(LED_STATUS_FLASH_BOTDETECT);