Лучший способ ввести функциональность в двоичный файл

Неявные классы могут использоваться для достижения чего-то похожего на то, что вы ищете.

Неявный класс с одним аргументом конструктора может использоваться как шаблон для добавления методов в определенного типа. Одним из примеров является DurationInt, который «добавляет» методы к целым числам, чтобы преобразовать их в длительности. Он импортируется в область видимости с помощью import scala.concurrent.duration._

. Упрощенная версия DurationInt может быть определена следующим образом:

implicit class DurationInt(n: Int) {
  def seconds: FiniteDuration = Duration(n, TimeUnit.SECONDS)
}

Это позволяет использовать метод секунд для всех целых чисел

2.seconds // Returns a duration object

Для функций с несколькими аргументами вы можете использовать аргумент кортежа для неявного класса:

implicit class TupleConcat(tuple: (String, String)) {
  def concat: String = tuple._1 + tuple._2
}

// enables the following syntax
("aa", "bb").concat

Обычно для неявных классов, например, для расширения AnyVal, это позволяет некоторым компиляторам оптимизаций, которые во многих случаях не позволяют создавать экземпляр неявного класса.

implicit final class DurationInt(val n: Int) extends AnyVal { /* implementation */ }
20
задан dbr 11 October 2009 в 15:45
поделиться

4 ответа

Для заинтересованных тем, что я закончил тем, что делал, вот сводка:

я посмотрел на несколько возможностей. Они попадают в исправление во время выполнения и статическое исправление двоичного файла.

Насколько исправление файла затронуто, я по существу попробовал два подхода:

  1. изменение блока в сегментах кода (__ ТЕКСТ) двоичного файла.

  2. изменение загрузки управляет в заголовке Маха.

первый метод требует там, чтобы быть свободным пространством или методами, которые можно перезаписать. Это также страдает от чрезвычайно плохой пригодности для обслуживания. Любые новые двоичные файлы потребуют руки, исправляющей их еще раз, особенно если их исходный код даже немного изменился.

второй метод должен был попытаться добавить запись LC_ LOAD_ DYLIB в заголовок Маха. Там нет многих мужественных редакторов, таким образом, это является волосатым, но я на самом деле изменил структуры так, чтобы моя запись была видима otool -l. Однако это на самом деле не работало, поскольку было dyld: bad external relocation length во времени выполнения. Я предполагаю, что должен слоняться без дела с таблицами импорта и т.д., И это - слишком много усилия разобраться без редактора.

Второй путь должен был ввести код во времени выполнения. Нет очень там, чтобы сделать это. Даже для приложений Вы управляете (т.е. дочернее приложение, которое Вы запускаете). Возможно, существует путь к fork(), и получите запущенный процесс инициализации, но я никогда не иду это.

существует SIMBL, но это требует, чтобы Вашим приложением было Какао, потому что SIMBL изобразит из себя InputManager в масштабе всей системы и выборочно загрузит пакеты. Я отклонил это, потому что моим приложением не было Какао, и кроме того, мне не нравится материал в масштабе всей системы.

Следующий был mach_, вводят и mach_star проект. Существует также более новый проект под названием PlugSuit, размещенный в Google, который, кажется, не что иное как тонкая обертка вокруг mach_inject.

Mach_inject обеспечивает API, чтобы сделать то, что подразумевает имя. Я действительно находил проблему в коде все же. На 10.5.4, mmap метод в mach_inject.c файле требует там, чтобы быть СОВМЕСТНО ИСПОЛЬЗОВАННЫМ or'd MAP_ с MAP_READ, или иначе mmap перестанет работать.

Кроме этого, все это на самом деле работает, как рекламируется. Я закончил тем, что использовал mach_ inject_ пакет, чтобы сделать то, что я намеревался сделать со статическим добавлением DYLIB к заголовку Маха: а именно, запуская новый поток на модуле init, который ведет его грязный бизнес.

Так или иначе, я сделал это Wiki. Не стесняйтесь добавлять, исправлять или обновлять информацию. Нет практически никакой информации, доступной на этом виде работы над OSX. Чем больше информации, тем лучше.

10
ответ дан 30 November 2019 в 01:16
поделиться

В MacOS X выпусков до 10,5 Вы сделали бы это использование расширения менеджера по Входу. Менеджер входа был предназначен для обработки вещей, любят вход за неримские языки, где расширение могло открыть окно, чтобы ввести соответствующие глифы и затем передать завершенный текст приложению. Приложение только должно было удостовериться, что было чисто Unicode, и не должно было волноваться о точных деталях каждого языка и региона.

менеджер по Входу был дико оскорблен для исправления всех видов несвязанной функциональности в приложения и часто дестабилизировал приложение. Это также становилось вектором атаки для троянцев, таких как "Умпа-лумпа". MacOS 10.5 сжимает ограничения на менеджеров по Входу: это не выполнит их в процессе, принадлежавшем корню или колесу, ни в процессе, который изменил его uid. Старше значащий, 10.5 не загрузит менеджер Входа в процесс на 64 бита и указал, что даже использование на 32 бита не поддерживается и будет удалено в будущем выпуске.

Поэтому, если можно жить с ограничениями, менеджер по Входу может сделать то, что Вы хотите. Будущие релизы MacOS почти наверняка представят другого (более безопасный, более ограниченный) способ сделать это, поскольку функциональность действительно необходима для входной поддержки языка.

4
ответ дан 30 November 2019 в 01:16
поделиться

Интересная проблема. Если бы я понимаю Вас правильно, требуется добавить способность удаленно вызвать функции в рабочем исполняемом файле.

, Если Вам действительно не нужно целое приложение, Вы смогли разделять основную функцию и превращать его в файл библиотеки, против которого можно связаться. Будет ваше дело выяснять, как удостовериться, что вся необходимая инициализация происходит.

Другой подход мог быть должен действовать как вирус. Введите функцию, которая обрабатывает удаленные вызовы, вероятно, в другом потоке. Необходимо будет запустить этот поток путем введения некоторого кода в основную функцию, или везде, где еще является соответствующим. Скорее всего, Вы столкнетесь с главными проблемами с инициализацией, потокобезопасностью и/или поддержанием надлежащего состояния программы.

наилучший вариант, если его доступное, состоит в том, чтобы заставить поставщика Вашего приложения выставлять сменный API, который позволяет Вам сделать это чисто и надежно поддерживаемым способом.

при движении с любым пути hack-binary это будет трудоемким и хрупким, но Вы изучите много в процессе.

0
ответ дан 30 November 2019 в 01:16
поделиться

В Windows это просто сделать, на самом деле это очень широко применяется и известно как Внедрение DLL / кода.

0
ответ дан 30 November 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: