Как написать расширение браузера в виде dll для windows, которое перехватывает максимум событий и модифицирует максимум данных, в том числе, которое модифицирует страницы и перехватывает клики мышью в реальном времени?
В современном мире, и, в частности, на хабре, очень много говорят об универсальности, о библиотеках, и об удобных функциях, предоставляемых библиотеками. У меня вопрос: я хочу написать расширение для браузера, изменяющее содержимое веб-страниц. Всех. Абсолютно всех. Без исключения. И чтобы со стороны сайтов это расширение невозможно было детектировать. А так же, перехватывающее все основные события, которые делает пользователь за браузером: все клики мышью, загрузки файлов, и т.д. А также, события, генерируемые веб-страницами, в особенности, открытие окон, запрос на использование камеры и микрофона (главным образом, чтобы сказать, что их нет), загрузку iframe'ов, ну и так далее. В общем - полное господство и, при необходимости, изменение. Ещё нужно перехватывать обращения к сокетам. Все. Абсолютно. Ещё нужно смотреть, к каким сертификатам производится обращение, как сертификаты проверяются, при необходимости говорить, что сертификат на сервере дохлый, или что, наоборот, сертификат плохой, но жить можно, как бы на http без ssl.
Браузеры: яндекс, фаерфокс, работают на windows. Права администратора, права на установку корневых сертификатов, и другие необходимые права, есть.
Писать хочу на Си (visual studio или clang) или на старых версиях delphi (3, 5, 6, 7). В школе была Delphi 7, в университете - один семестр язык Си и один семестр - программирование, Кнута изучали в основном. Библиотеку DLL написать могу, что такое stdcall, pchar, и как распарсить html, и что делать с callback'ом - представляю и могу с этим работать. В том числе, как жить с многопоточными вызовами callback'ов, про критические секции там и синхронизацию - тоже знаю. Что делать, если мою dll загрузит несколько экзешников браузера и данные нужно будет связывать - тоже знаю.
Собственно вопрос: как подключить DLL библиотеку к браузеру так, чтобы через неё проходили все события и чтобы можно было изменять данные и ходить по DOM веб-страницы?
Мне не нужно публиковать моё расширение где-то. Это, конечно, можно, но не критично и далеко не приоритетно. Мне просто нужно, чтобы всё работало, локально, чтобы это всё было прозрачно и понятно. То есть, никаких extension-market'ов, и stor'ов, только локальная dll, пропускающая через себя события и данные.
Как это сделать? Как, условно говоря, просто написать xml, положить этот xml и мою dll в папку с экзешником браузера, и чтобы потом браузер сам загружал мою dll и чтобы всё работало?
Слышала, что расширения для браузеров пишут на java script - но мне это видится извращением каким-то. Ну то есть можно понять какие-то странные расширения, которые грузятся как скрипты и что-то там делают - но мне-то надо как можно более нативно перехватывать и модифицировать данные, с которыми работает браузер. Возможно, работать со внутренними структурами данных браузера. И т.д. Мне нужно, чтобы из своей dll я могла заблокировать выполнение скриптов на странице, или переопределить результат вызова какого-либо js-обработчика. Или выборочно не загружать скрипты совсем. А не воевать с javascript-кодом на страницах. И не быть на одном уровне со скриптами, которые страницы пытаются грузить.
Также желательна возможность установить пару своих кнопок рядом с адресной строкой в браузере, чтобы говорить что-то делать моей dll.
Браузер переписать - это, мягко сказать, запредельно сложно. Да и смысл? Как то, года три назад, ещё в университете, я пыталась откомпилировать firefox - у меня не получилось. И хочется всё таки именно расширение, чтобы исполняемые файлы браузера не трогать.
То, что вы хотите в описании, ближе подходит под тестовую среду Selenium. В нем есть все инструменты, чтобы управлять окружением браузера. Но эту среду придумали, не чтобы деформировать политики безопасности браузера в угоду пользователя, а для автоматизированного тестирования веб-приложений без непосредственного заглядывания в сам браузер.
NPAPI и PPAPI, которые упоминались, нужны для воплощения тегов object и embed, и это не ваш случай, это не про перехват. Вам нужны ActiveX и XPCOM, но на них сейчас уже практически невозможно делать расширения.
Так что для вашего случая подойдёт только WebExtensions. Там обязательно писать часть кода на JavaScript. Вы можете свой перехватчик написать в виде локального веб-сервера и общаться между браузером и перехватчиком по HTTP. Ну или WebSocket. Или даже чистый сокет, расширению можно их открывать. Если ваше расширение относительно тупое, а локальный веб-сервер умный, то локальный веб-сервер на чём угодно можно писать.
Это реальная практика. Например, Контур.Эльба состоит из двух частей, из агента (HTTP-сервер) и расширения. Для всяких пенсионных и страховых фондов нужно свои расширения и агенты ставить, чтоб до ЭЦП достучаться, вот они все примерно по одному принципу сейчас делаются.
При этом нужно иметь в виду, как сделаны расширения. Браузеры сейчас работают в несколько процессов и несколько потоков. У расширения есть возможность чего-нибудь повыполнять в самом главном потоке окна браузера, где живут дополнительные кнопки панели, но такой код стремятся свести к минимуму. Ещё у расширения есть невидимая вкладка, в которой исполняется background.js, и большинство кода, по идее, переносится в неё. Но из этой вкладки напрямую нельзя достучаться до DOM вкладок с сайтами, поэтому есть отдельный механизм, как забрасывать привилегированные скрипты во вкладки с сайтами. И потом разрозненные части расширения между разными потоками и процессами должны общаться сообщениями.
Чтоб перехватить нажатие клавиши, это как раз нужно забросить в чужую вкладку скрипт. Дальше начинается вопрос, что с этим делать. Ваш гипотетический умный HTTP-сервер на localhost должен получить сигнал о перехваченной клавише, среагировать и послать ответ. Но асинхронная модель исполнения браузера не позволит получить ответ сразу. А обработчик события клавиши должен принять какое-то решение. Впитать клавишу, не пропустить её обработку дальше, или пропустить. return false или return true. Тут либо в JavaScript закодировать принятие решения, либо использовать нерекомендуемый синхронный XHR.
Даже если пробить брешь, и как-нибудь через не хочу подгрузить библиотеку, есть такая особенность. В операционных системах есть API, чтобы лишить процесс привилегий, и рабочие процессы браузеров создаются как раз такими. Безправными и слепыми. Их доступ во внешний мир сделан через трубу с основным процессом браузера, через спроецированную память и так далее. Не имея доступа к этой трубе и не зная, как ей пользоваться, вы библиотекой там ничего особо не поделаете. Устройство DOM отличается у каждого браузера и переплетено со сборкой мусора JavaScript. Если разработчики не предоставили специального, совместимого со сборкой мусора, интерфейса, как это было раньше в Firefox и Internet Explorer, там никак стабильно и переносимо не подкопаться, кроме как через JavaScript.