Ну да, стандартная возможность Arduino Pro Micro - эмуляция HID устройства. Удобно в плане безопасности - можно сгенерировать хитроумный трудноподбираемый пароль и хранить его отдельно от компьютера, не запоминая. На Хабре недавно была статья на эту тему. P. S. Какой сервер-то?
Скетча нет, надо было сразу, на вашу страницу - Выполнить заказ. ))). Не то что б он мне нужен так был. похожее Я уже тестил , долго и не удобно . Удобнее не выходя из винды софтом и сочетанием клавиш, надо мобильность есть флешка, надо скрытность на проге пароль. Рекламировать её не буду. Инфо есть в сети.
а чтобы изменить или добавить пароли - надо перепрошивать? так ли это безопасно? ведь в большинстве случаев пароли воруются не подбиранием, а всяким там фишингом и троянами.
погуглил че-то про эмуляцию хид-устройств на авр, нагуглил так называемый v-usb. http://we.easyelectronics.ru/electro-and-pc/usb-dlya-avr-chast-2-hid-class-na-v-usb.html http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/ слегка изменил скетч со второй ссылки. там эмулируется сразу клава, мышь и два геймпада, собственно выкинул геймпады, соответственно подкрутил usbconfig.h. В соотвтетствии с инструкциями из первой ссылки запихнул это в АВР-студию, вроде даже компилится. Проверить в железе пока нет возможности, а симулятор студии не симулирует ЮСБ, так что возник вопрос. Если кто шарит в этом v-usb - проконсультируйте пожалуйста. вот код: Код (C++): // please see http://frank.circleofcurrent.com/index.php?page=hid_tutorial_1 // the "usb_hid_rpt_desc.hid" file needs to be viewed with the HID Descriptor Tool from USB.org // required headers #include <avr/io.h> #include <avr/wdt.h> #include <avr/interrupt.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <string.h> // V-USB #include "usbdrv.h" PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT_ID (1) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xa1, 0x01, // COLLECTION (Application) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x85, 0x02, // REPORT_ID (2) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x03, // USAGE_MAXIMUM (Button 3) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x03, // REPORT_COUNT (3) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x05, // REPORT_SIZE (5) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x38, // USAGE (Wheel) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x06, // INPUT (Data,Var,Rel) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION }; typedef struct { uint8_t report_id; uint8_t modifier; uint8_t reserved; uint8_t keycodes[6]; } keyboard_report_t; typedef struct { uint8_t report_id; uint8_t buttons; int8_t x; int8_t y; int8_t wheel; } mouse_report_t; static uint8_t idle_rate = 500 / 4; // see HID1_11.pdf sect 7.2.4 static uint8_t protocol_version = 0; // see HID1_11.pdf sect 7.2.6 static keyboard_report_t keyboard_report; static mouse_report_t mouse_report; static keyboard_report_t keyboard_report_old; static mouse_report_t mouse_report_old; usbMsgLen_t usbFunctionSetup(uint8_t data[8]) { // see HID1_11.pdf sect 7.2 and http://vusb.wikidot.com/driver-api usbRequest_t *rq = (void *)data; if ((rq->bmRequestType & USBRQ_TYPE_MASK) != USBRQ_TYPE_CLASS) return 0; // ignore request if it's not a class specific request // see HID1_11.pdf sect 7.2 switch (rq->bRequest) { case USBRQ_HID_GET_IDLE: usbMsgPtr = &idle_rate; // send data starting from this byte return 1; // send 1 byte case USBRQ_HID_SET_IDLE: idle_rate = rq->wValue.bytes[1]; // read in idle rate return 0; // send nothing case USBRQ_HID_GET_PROTOCOL: usbMsgPtr = &protocol_version; // send data starting from this byte return 1; // send 1 byte case USBRQ_HID_SET_PROTOCOL: protocol_version = rq->wValue.bytes[1]; return 0; // send nothing case USBRQ_HID_GET_REPORT: // check for report ID then send back report if (rq->wValue.bytes[0] == 1) { usbMsgPtr = &keyboard_report; return sizeof(keyboard_report); } else if (rq->wValue.bytes[0] == 2) { usbMsgPtr = &mouse_report; return sizeof(mouse_report); } else { return 0; // no such report, send nothing } case USBRQ_HID_SET_REPORT: // no "output" or "feature" implemented, so ignore return 0; // send nothing default: // do not understand data, ignore return 0; // send nothing } } // this function is used to guarantee that the data is sent to the computer once void usbSendHidReport(uchar * data, uchar len) { while(1) { usbPoll(); if (usbInterruptIsReady()) { usbSetInterrupt(data, len); break; } } } int main() { wdt_enable(WDTO_2S); TCCR1B = _BV(CS12) | _BV(CS11); // timer is initialized, used to keep track of idle period usbInit(); // start v-usb usbDeviceDisconnect(); // enforce USB re-enumeration, do this while interrupts are disabled! _delay_ms(250); usbDeviceConnect(); sei(); // enable interrupts uint8_t to_send = 1; // boolean, true for first time while (1) { wdt_reset(); usbPoll(); // set the report IDs manually keyboard_report.report_id = 1; mouse_report.report_id = 2; /* * this area is where you should set the movement * and button values of the reports using the input * method of your choice * */ // determine whether or not the report should be sent if ((TCNT1 > ((4 * (F_CPU / 1024000)) * idle_rate) || TCNT1 > 0x7FFF) && idle_rate != 0) {// using idle rate to_send = 1; } else {// or if data has changed if (memcmp(&keyboard_report, &keyboard_report_old, sizeof(keyboard_report_t)) != 0) { to_send = 1; } else if (memcmp(&mouse_report, &mouse_report_old, sizeof(mouse_report_t)) != 0) { to_send = 1; } } usbPoll(); if (to_send != 0) { // send the data if needed usbSendHidReport(&keyboard_report, sizeof(keyboard_report_t)); usbSendHidReport(&mouse_report, sizeof(mouse_report_t)); TCNT1 = 0; // reset timer } usbPoll(); memcpy(&mouse_report_old, &mouse_report, sizeof(mouse_report_t)); memcpy(&keyboard_report_old, &keyboard_report, sizeof(keyboard_report_t)); to_send = 0; // reset flag } return 0; } правильно ли я понимаю, что для того чтобы эта приблуда например непрерывно жала клавишу "1", надо в цикл (собственно там помечено куда "* this area is where you should set.....") вставить вот такую строчку?: keyboard_report.keycodes[0]=49; если это так, то мне все еще непонятно почему в структуре клавишей именно массив из 6 ячеек? то есть как бы в этом репорте могут одновременно отправляться до 6 нажатых клавишь? нет. тут явно что-то не то. где взять правильные коды клавиш? вот тут вроде что-то есть http://www.freebsddiary.org/APC/usb_hid_usages.php получается что "1" это 30. но все равно непонятно как конкретно этим пользоваться. вроде у скан-кодов должны быть еще коды отжатия. или это касается только пс/2.
судя по тому что пишут в HIDKeyboard.h, "1" это действительно 30 (0x1E) Код (C++): // HID Values of Function Keys #define F1 0x3a #define F2 0x3b #define F3 0x3c #define F4 0x3d #define F5 0x3e #define F6 0x3f #define F7 0x40 #define F8 0x41 #define F9 0x42 #define F10 0x43 #define F11 0x44 #define F12 0x45 // HID Values of Special Keys #define ENTER 0x28 #define ESCAPE 0x29 #define BACKSPACE 0x2a #define TAB 0x2b #define SPACEBAR 0x2c #define CAPSLOCK 0x39 #define PRINTSCREEN 0x46 #define SCROLLLOCK 0x47 #define PAUSE 0x48 #define INSERT 0x49 #define HOME 0x4a #define PAGEUP 0x4b #define DELETE 0x4c #define END 0x4d #define PAGEDOWN 0x4e #define RIGHTARROW 0x4f #define LEFTARROW 0x50 #define DOWNARROW 0x51 #define UPARROW 0x52 // HID Values of Keypad Keys #define NUMLOCK 0x53 #define KEYPADSLASH 0x54 #define KEYPADSTAR 0x55 #define KEYPADMINUS 0x56 #define KEYPADPLUS 0x57 #define KEYPADENTER 0x58 #define KEYPAD1 0x59 #define KEYPAD2 0x5a #define KEYPAD3 0x5b #define KEYPAD4 0x5c #define KEYPAD5 0x5d #define KEYPAD6 0x5e #define KEYPAD7 0x5f #define KEYPAD8 0x60 #define KEYPAD9 0x61 #define KEYPAD0 0x62 #define KEYPADPERIOD 0x63 // HID Values of System Keys #define KEYBOARDAPPLICATION 0x65 #define KEYBOARDPOWER 0x66 #define VOLUMEMUTE 0x7f #define VOLUMEUP 0x80 #define VOLUMEDOWN 0x81 // Common-use modifiers #define CTRL 0x01 #define SHIFT 0x02 #define ALT 0x04 #define GUI 0x08
мой ответ Чемберлену Острову! теперь банановый на ЧистомСи™ http://forum.amperka.ru/threads/v-usb-hid-клавиатура-atmega8.13438/