Контрольная сумма функции в памяти - PullRequest
2 голосов
/ 01 декабря 2010

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

Ответы [ 4 ]

4 голосов
/ 02 декабря 2010

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

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

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

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

Если вы действительно хотите продолжить этот путь, я бы порекомендовал реверсировать ресурсы или выполнить шаг постобработки для вашего кода, который
а) объединяет все ваши функции вместе, вставляя переходы, соединяющие их, которые никогда не будут выполнены. Скройте ветви за непрозрачными предикатами. Это сделает разборку трудной для чтения / понимания и даже сломает некоторые дизассемблеры, выполняющие статический анализ потока, из-за получающегося огромного размера функции.
б) перенаправляет все вызовы функций через одну большую функцию ветвления. Это повлияет на производительность вашего кода, но также сделает коллограф полностью непригодным / нечитаемым.

2 голосов
/ 02 декабря 2010

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

0 голосов
/ 02 декабря 2010

Стандарт не позволяет использовать функцию в качестве аргумента оператора sizeof.Таким образом, не существует переносимого способа получить размер тела функции.Кроме того, функция не обязательно должна быть помещена в непрерывный блок памяти.Части нескольких функций могут быть перетасованы в одном месте (это то, что VS делает в сборке Release).

0 голосов
/ 02 декабря 2010

Код обычно находится в постоянной памяти, поэтому он не может измениться.

Но вы можете встроить контрольную сумму для DLL, чтобы сразу после загрузки она проверяла свое собственное изображение и прерывала работу, если DLLобраз диска был изменен.Но разве это еще не сделано ОС?

...