|
#1
|
|||
|
|||
Хук Com winApi
Кратко говоря, стараюсь реализовать следующую задачу: программа должна отлавливать сообщения, посылаемые ком портом в стороннее приложение и немного корректировать их, далее получать ответ от приложения, и тоже, корректируя их отправлять обратно на порт.
Проблема в следующем: приложение стороннее работает напрямую с портом, без сторонних драйверов, а значит написание драйвера не вариант, (или ошибаюсь?). номер ком-порта определен заранее - 4-й и изменить я этого для программы не смогу, получается не могу стать приложением работающим с 4-м портом, а ты программу связать с собой как с 6-м например. (хоть может и в этом не прав). Я думаю, единственный выход, это ловить какие - то апишные функции в самой программе, и действовать на значения их аргументов. (правильно мыслю?) Много похожих тем есть , ул и форумы обысканы, но готового решения так и не нашёл, лишь в основном мутную воду, у меня месяц есть на реализацию, помогите кто чем может) заранее благодарен) Последний раз редактировалось reqyz, 19.03.2013 в 13:29. |
#2
|
||||
|
||||
Цитата:
Цитата:
Код:
mov dx, PORT out dx, eax Прежде, чем за такое браться, нужно представлять, как работает ввод-вывод. Что с 3 кольца НЕВОЗМОЖЕН ввод/вывод в порт напрямую (в нормальных системах), потому что это гарантирует моментальное убийство ОС любой программой, которая этого захотела. Работа все равно идет через драйвер, просто он системный. И написать драйвер для перехвата CreateFile/WriteFile/ReadFile можно. Только большой геморрой. Цитата:
Я бы делал методом стартера или внедрением DLL. Нашел бы в программе строку 'COM', 'COM4' или в этом роде, нашел ее использование и в дебаге отследил до чтения данных. Или же сразу в дебаге поставил бы бряк на CreateFileA и CreateFileW и жал F5, пока не увижу первым параметром в стеке нужную строку. Так же можно и с ReadFile поступить, если прога не насилует хард постоянными обращениями к файлам. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 19.03.2013 в 18:51. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
reqyz (20.03.2013)
|
#3
|
|||
|
|||
сейчас постараюсь что то написать по новой инфе, тема не закрыта, буду неоднократно обращаться) спасибо за помощь)
|
#4
|
|||
|
|||
думаю буду делать так:
1. встраиваем длл-кой код в чужой процесс на отлов функций 2. ловим функции приема передачи сообщений по ком порту(не знаю какие) 3. меняем их аргументы как необходимо хочется верить что этого достаточно) с первым пунктом справлюсь) во втором, какие мессаджы ловить? буду рад любой адекватной помощи) |
#5
|
||||
|
||||
1) Я бы все-таки нашел место в программе, которое можно безболезненно пропатчить, и вместо него вставил бы LoadLibrary; в DLLMain загружаемой библы поставил бы те действия, что стер из-за лоадлибрари.
2) Я ж уже написал: CreateFile, ReadFile, WriteFile, CloseHandle. Ввод-вывод в любое устройство все равно сводится к этим функциям, только обычно это обернуто в другие функции или компоненты. Бряк на CreateFileA, и ждешь, пока первым параметром не передадут строку 'COM4' или че-то в этом роде (например, '\\.\COM4\'). Потом смотрим, куда адрес возврата - получаем место, откуда ком-порт открывается. Его надо патчить, хотя бы чтобы сохранить хендл у себя (можно ессно попробовать нарыть глобальную переменную хендла, но если в проге юзалась какая-то обертка над ком-портом или много ООП - то задолбаться искать). 3) Менять аргументы не нужно. Вызовы ReadFile/WriteFile можно поменять на свои функции из DLL, описанные по соответствующему шаблону из МСДН: Код:
int __stdcall newCreateFile(char *name, DWORD access, DWORD share, void *attrs, DWORD disp, DWORD flags, DWORD temp); Меняется код очень просто - если адрес функции в константе (call ds:CreateFileA), то меняем константу. Если относительный (конструкция вида call _CreateFileA | _CreateFileA: jmp ds:CreateFileA как любит делать студия) - то меняем прямо в опкоде адрес. Адрес вычисляется в этом случае относительный, то есть <адрес_новой_функции> - <адрес команды CALL + 5>. Менять проще всего динамически в DLLMain подгружаемой библиотеки (не забудь, что DLLMain должно вернуть НЕ НОЛЬ, иначе библа выгрузится). Разумеется, чтобы менять код, надо сделать VirtualProtect и снять с нужной страницы флаг READ_ONLY. Сам код функций - любой, только в конце обязательно вызов оригинальной функции. Пример: Код:
int __stdcall newCreateFile(char *name, DWORD access, DWORD share, void *attrs, DWORD disp, DWORD flags, DWORD temp) { FILE *f = fopen("log.txt", "a"); fprintf(f, "File opened: %s", name); fclose(f); CreateFileA(name, access, share, attrs, disp, flags, temp); } Вообще, без патча CreateFile можно обойтись, если работа с портом идет из отдельного места, а не через общий интерфейс для файлов и порта. Тогда можно пропатчить конкретный вызов ReadFile и юзать хендл, приходящий туда. Однако в общем случае может понадобиться сохранение хендла порта. ЗЫЖ: есть еще один наркоманский вариант, который я один раз использовал - проходиться по стеку вызовов ReadFile вверх на какой-то уровень, и если там определенный адрес, то подменять, иначе вызывать стандартный ReadFile. Вылезал так на 3 функции вверх, обходил STL-ные операции с файлами. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 21.03.2013 в 00:33. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
reqyz (21.03.2013)
|
#6
|
|||
|
|||
При работе с Com - портом могут использоваться все эти функции, которые описаны здесь
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx |
Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
reqyz (21.03.2013)
|
#7
|
|||
|
|||
сегодня переначну алгоритм) по мере появления вопросов буду обращаться) спасибо)
|
#8
|
||||
|
||||
Мне приходит в голову поменять нафиг COM4 на какой-нить COM9 (через патч/загрузчик), и заюзать программу для виртуализации ком-портов. В итоге получаем схему вида:
COM4 (реальный девайс) <-> Наша программка, обрабатывающая команды <-> Виртуальный ком-порт <-> Драйвер виртуального ком-порта <-> Ещё один виртуальный ком-порт <-> Основная программа (пропатченная) Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#9
|
||||
|
||||
Виртуальный порт еще найти надо, и приаттачиться к драйверу виртуального порта программой. Тоже тот еще гемор.
jmp $ ; Happy End! The Cake Is A Lie. |
#10
|
||||
|
||||
а если так:
истинный СОМ4 (на машине) меняем на какой-нить другой СОМ, используем нуль-СОМ эмулятор, например такой, где выставляем один порт СОМ4, другой порт - другой СОМ на котором уже будет висеть своя программа и получать от испытуемой необходимые данные, править их и отправлять в железо, от железа также править и отправлять обратно в испытуемую программу, вернее в порт на котором она висит, а нуль-СОМ эмулятор уже будет подавать в испытуемую программу... Понять, что хочет заказчик - бесценно, ведь он платит MasterCard |
#11
|
||||
|
||||
Нужно БОЛЬШЕ ком-портов...
Можно. Так в чем-то проще. Для человека, плохо знающего асм и машкод - сильно проще. Хотя если прога будет работать не только у того, кто ее писал - я бы сделал патчем. Потому что с этими виртуальными ком-портами - как повезет. Я месяц пытался у знакомого настроить виртуальный порт. У меня все встало на комп без проблем, а там - хоть убейся, ничего не выходит. А когда я делаю патч - я знаю, что оно будет работать всегда и везде. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 22.03.2013 в 00:04. |
#12
|
||||
|
||||
ТС если так хорошо знаешь протокол обмена что налету готов корректировать, не проще написть свою прогу и делать что хочешь?
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#13
|
|||
|
|||
У меня всё окей) перехват реализовал вплоть до изменения, через отлов реад и врайт файла) если кому понадобится пример исходника, скину)
|