Подтвердить что ты не робот

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

Каким будет лучший способ вставки функциональности в двоичное приложение (3d-участник, закрытый источник).

Целевое приложение находится на OSX и, похоже, скомпилировано с использованием gcc 3+. Я могу видеть список функций, реализованных в двоичном формате, и отлаживать и изолировать одну конкретную функцию, которую я хотел бы удаленно вызвать.

В частности, я хотел бы назвать эту функцию - позвольте ей void zoomByFactor(x,y) - когда я получу определенные данные из сложного HIDevice.

Я могу легко модифицировать или вводить инструкции в сам файл двоичного файла (т.е. исправление не должно происходить только в ОЗУ).

Что бы вы порекомендовали как способ "красиво" сделать это?

Edit:

Мне действительно нужно полное приложение. Поэтому я не могу бросить его и использовать библиотеку. (Для тех, кто нуждается в этическом объяснении: это проприетарная часть программного обеспечения САПР, чей веб-сайт компании не обновлялся с 2006 года. Я заплатил за этот продукт (довольно много денег за то, что он есть), и у него есть проект данные, которые я не могу легко уйти от него. Продукт подходит мне как можно лучше, но я хочу использовать новый HID, который я недавно получил. Я изучил внутренности приложения, и я довольно уверен что я могу вызвать правильную функцию с соответствующими данными и заставить ее работать правильно).

Вот что я сделал до сих пор, и это довольно gheto.

Я уже модифицировал части приложения через этот процесс:

xxd -g 0 binary > binary.hex
cat binary.hex | awk 'substitute work' > modified.hex
xxd -r modified.hex > newbinary
chmod 777 newbinary

Я делаю такого рода прыжки через обручи, потому что бинарный файл имеет почти 100 мегабайт.

Суть того, что я думаю, это то, что я буду jmp где-то в главном цикле приложения, запустите поток и вернусь к основной функции.

Теперь вопросы: где я могу вставить новый код? мне нужно изменить таблицы символов? в качестве альтернативы, как я могу сделать загрузку dylib автоматически, так что единственное "взлом", которое мне нужно сделать, это вставить вызов нормально загруженного dylib в основную функцию?

4b9b3361

Ответ 1

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

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

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

  • изменение сборки в коде сегментов (__TEXT) двоичного файла.

  • изменение команд загрузки в mach.

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

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

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

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

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

Mach_inject предоставляет API для выполнения того, что подразумевает название. Однако я нашел проблему в коде. В 10.5.4 метод mmap в файле mach_inject.c требует наличия MAP_ SHARED or'd с MAP_READ, иначе mmap не будет выполнен.

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

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

Ответ 2

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

Диспетчер ввода был подвергнут жестокому обращению, чтобы исправлять всевозможные несвязанные функции в приложениях и часто дестабилизировать приложение. Он также стал атак для троянов, таких как "Oompa-Loompa". MacOS 10.5 ужесточает ограничения для менеджеров ввода: он не будет запускать их в процессе, принадлежащем root или колесу, или в процессе, который изменил его uid. Наиболее важно, что 10.5 не загрузит Input Manager в 64-битный процесс и указал, что даже 32-битное использование не поддерживается и будет удалено в будущей версии.

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

Ответ 3

Я считаю, что вы также можете использовать метод DYLD_INSERT_LIBRARIES.

Этот пост также связан с тем, что вы пытались сделать;

Ответ 4

Недавно я получил удар по инъекции/переопределению с использованием источников mach_star. Я закончил писать учебник для него, так как документация для этого материала всегда настолько отрывочна и часто устаревает.

http://soundly.me/osx-injection-override-tutorial-hello-world/

Ответ 5

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

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

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

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

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

Ответ 6

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

Существует коммерческий SDK для OSX, который позволяет это сделать: Application Enhancer (бесплатно для некоммерческого использования).