C, который сам проверяет * в ram * - программирование
Подтвердить что ты не робот

C, который сам проверяет * в ram *

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

Код сначала компилируется на платформу кросс-разработки, генерируя вывод .elf. Утилита используется для выделения бинарного изображения, и это изображение сжигается для мигания на целевой платформе вместе с размером изображения. Когда цель запущена, она копирует двоичный файл в правильную область ram и переходит к нему. Утилита также вычисляет контрольную сумму всех слов в эльфе, которые предназначены для бара, и это тоже сожжено во вспышке. Таким образом, мое изображение теоретически могло бы проверять собственное резидентное изображение с использованием априорного начального адреса и размера, сохраненного во флэш-памяти, и сравнить с суммой, сохраненной во флэш-памяти.

Это теория в любом случае. Проблема в том, что как только изображение начинает выполняться, в разделе .data происходит изменение в изменении переменных. К тому времени, когда сумма будет выполнена, изображение, которое было суммировано, больше не является изображением, для которого утилита рассчитала сумму.

Я исключил изменения из-за переменных, определенных моим приложением, переместив процедуру контрольной суммы перед всеми другими инициализациями в приложении (что имеет смысл b/c, зачем запускать ее, если проверка целостности завершается неудачно?), но убийца - это время выполнения C. Похоже, что есть некоторые элементы, относящиеся к malloc и литье указателей и другие вещи, которые были изменены до того, как main() будет даже введен.

Является ли вся идея самоконтроля C-кода хромой? Если бы был способ принудительно использовать приложения и CRT.data в разных разделах, я мог бы избежать трэша CRT, но можно утверждать, что если цель заключается в проверке целостности изображения перед его выполнением (большей частью), то эти инициализированные данные ЭЛТ должны быть частью этого. Есть ли способ самостоятельно сделать контрольную сумму кода в ОЗУ?

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

Дополнительная информация: цепочка инструментов - это GNU, изображение содержит .text, .rodata и .data как один загружаемый фрагмент. Нет ОС, это встроенный металл. Первичный загрузчик, по существу, memcpy мой двоичный код в баран на заданном адресе. Никаких переездов не происходит. VM не используется. Контрольная сумма нуждается только в тестировании только в init.


обновляется Найдено, что, делая это.

__attribute__((constructor)) void sumItUp(void) {
    // sum it up
    // leave result where it can be found
}

.., что я могу получить сумму, сделанную до почти всего, кроме инициализации vars malloc/sbrk с помощью CRT init и некоторых vars, принадлежащих "impure.o" и "locale.o". Теперь значение malloc/sbrk - это то, что я знаю из компоновщика проекта script. Если impure.o и locale.o могут быть смягчены, может быть в бизнесе.

Обновление Поскольку я могу контролировать точку входа (по тому, что указано во флэш-памяти для первичного загрузчика), кажется, лучшим углом атаки теперь является использование части пользовательского кода ассемблера для настройки указателей стека и sdata, вызова подпрограммы контрольной суммы и затем перейдите в "обычный" код _start.

4b9b3361

Ответ 1

Если контрольная сумма выполняется достаточно рано, вы можете использовать ТОЛЬКО переменные стека, а не писать какие-либо переменные раздела данных, т.е. делать ВСЕ, вам нужно выполнить контрольную сумму [и все предыдущие шаги, чтобы добраться до этой точки] ТОЛЬКО использовать локальные переменные для хранения вещей в [вы можете читать глобальные данные, конечно].

Я достаточно убежден, что правильный способ - доверять flash и загрузчику, чтобы загрузить то, что находится во вспышке. Если вы хотите, чтобы контрольная сумма кода была уверенна, идите и сделайте это [при условии, что это не будет изменено загрузчиком, конечно, например, загрузка во время загрузки разделяемых библиотек или перемещение самого исполняемого файла, например, случайные виртуальные адресные пространства и т.д.]. Но данные, загруженные из флешки, нельзя полагаться, как только выполнение начнется правильно.

Если у кого-то есть требование, что вы должны это сделать, пожалуйста, объясните им, что это невозможно реализовать, и что "требование, когда оно стоит", "сломано".

Ответ 2

Я предлагаю приблизиться к этому как исполняемый пакет, например upx.

В других ответах и ​​в вашем вопросе есть несколько вещей, которые из-за отсутствия лучшего термина заставляют меня нервничать.

  • Я бы не стал доверять загрузчику или чему-либо еще во флеше, который не был вынужден на меня.
  • В сети есть исходный код, который использовался для защиты одного из, как мне кажется, телефонов HTC недавно. Осмотритесь на forum.xda-developers.com и посмотрите, можете ли вы его найти и использовать для примера.
  • Я бы отбросил это требование. Производители мобильных телефонов тратят много времени на то, чтобы их изображения были заблокированы, и, в конце концов, все они избиты. Это похоже на порочный круг.

Ответ 3

Можете ли вы использовать компоновщик script, чтобы поместить impure.o и locale.o до или после всего остального, позволяя вам проверять все, кроме тех, и malloc/sbrk? Я предполагаю, что malloc и sbrk вызываются в загрузчике, который загружает ваше приложение, поэтому трэш, вызванный тем, не может быть устранен?

Это не ответ, чтобы просто сказать вам, чтобы бороться с этим требованием, но я согласен, что это, похоже, слишком задумано. Я уверен, что вы не можете вдаваться в какие-либо детали, но я предполагаю, что авторы спектаклей обеспокоены злонамеренными пользователями/хакерами, а не обычным повреждением памяти из-за космических лучей и т.д. В этом случае, если вредоносный пользователь/хакер может изменить то, что загружено в ОЗУ, они могут просто изменить вашу контрольную процедуру (которая сама работает из ОЗУ, правильно?), чтобы всегда возвращать счастливый статус, независимо от того, насколько хорошо работает контрольная сумма, которую они не запускают больше,

Даже если они обеспокоены обычным повреждением памяти, эта процедура контрольной суммы будет ловить только это, если ошибка произошла во время первоначальной копии в память, что на самом деле является наименее вероятным временем такой ошибки, просто потому, что система hasn ' t работает достаточно долго, чтобы иметь высокую вероятность события коррупции.

Ответ 4

В общем, то, что вы хотите сделать, невозможно, поскольку на многих (наиболее?) платформах загрузчик программ может "переместить" некоторые постоянные адреса программы.

Ответ 5

Можете ли вы обновить загрузчик для выполнения теста контрольной суммы на двоичном изображении резидентной памяти, прежде чем он будет скопирован в ram?