Иметь клиента, который утверждает, что соблюдает C, сложнее реконструировать, чем sudo «скомпилированный» байт-код Perl или тому подобное. У кого-нибудь есть способ доказать или опровергнуть это?
Обратный инжиниринг, скомпилированный Perl или C?
Ответы (6)
Я не очень хорошо разбираюсь в perl, но приведу несколько примеров того, почему реверсирование кода, скомпилированного в ассемблер, выглядит так уродливо.
Самое неприятное в реверсивном проектировании кода C заключается в том, что при компиляции удаляется вся информация о типах. Это полное отсутствие имен и типов - очень худшая часть IMO.
В языке с динамической типизацией компилятору необходимо сохранить гораздо больше информации об этом. В частности, имена полей/методов/..., так как обычно это строки, для которых невозможно найти каждое применение.
Есть много других некрасивых вещей. Например, оптимизация всей программы с использованием разных регистров для передачи параметров каждый раз. Функции встроены, так что простая функция появляется во многих местах, часто в несколько иной форме из-за оптимизации.
Одни и те же регистры и байты в стеке повторно используются другим содержимым внутри функции. Становится особенно уродливым с массивами в стеке. Поскольку у вас нет возможности узнать, насколько велик массив и где он заканчивается.
Кроме того, есть микрооптимизации, которые могут раздражать. Например, однажды я потратил более 15 минут на реверсирование простой функции, которая когда-то была похожа на return x/1600
. Потому что компилятор решил, что деление медленное, и переписал это деление на константу на несколько умножений-сложений и побитовых операций.
Perl очень легко обратно разработать. Предпочтительный инструмент — vi, vim, emacs или блокнот.
Это поднимает вопрос о том, почему они беспокоятся о реверс-инжиниринге. Превратить машинный код обратно во что-то похожее на исходный код сложнее, чем в обычный байт-код, но для большинства гнусных действий это не имеет значения. Если кто-то хочет скопировать ваши секреты или нарушить вашу безопасность, он может сделать достаточно, не превращая его обратно в идеальное представление вашего исходного кода.
Обратный инжиниринг кода для виртуальной машины обычно проще. Виртуальная машина обычно предназначена для того, чтобы быть легкой мишенью для языка. Это означает, что он обычно достаточно легко и напрямую представляет конструкции этого языка.
Однако, если вы имеете дело с виртуальной машиной, которая не была разработана для этого конкретного языка (например, Perl, скомпилированный в JVM), это часто отбрасывало бы вас гораздо ближе к работе с кодом, сгенерированным для реального оборудования, т. е. вы должны делать все необходимое, чтобы ориентироваться на предопределенную архитектуру, вместо того, чтобы проектировать цель так, чтобы она соответствовала исходному коду.
Хорошо, за эти годы было достаточно дискуссий по этому поводу; и в основном результаты никогда не бывают окончательными ... в основном потому, что это не имеет значения.
Для мотивированного обратного инженера оба будут одинаковыми.
Если вы используете создатели псевдо-exe, такие как perl2exe, то его будет легче «декомпилировать», чем скомпилированный C, поскольку perl2exe вообще не компилирует perl, он просто немного «скрыт» (см. http://www.net-security.org/vuln.php?id=2464; это действительно старый , но концепция, вероятно, все та же (я не исследовал, поэтому не знаю наверняка, но надеюсь, вы поняли мою точку зрения))
Я бы посоветовал обратить внимание на язык, который лучше всего подходит для работы, чтобы обслуживание и развитие фактического продукта можно было выполнять разумно и устойчиво.
Помните, что вы _не_можете_ остановить мотивированного противника, вам нужно сделать реверс дороже, чем писать его самим.
Эти 4 должны сделать это трудным (но опять же не невозможным)...
[1] Вставьте шумовой код (случайные места, случайный код), который выполняет бессмысленную математику и сложное взаимодействие со структурой данных (если все сделано правильно, это будет большой головной болью, если цель состоит в том, чтобы изменить код, а не функциональность).
[2] Сцепите несколько (разных) обфускаторов кода в исходном коде как часть процесса сборки.
[3] Примените ключ защиты программного обеспечения, который предотвратит выполнение кода, если аппаратное обеспечение отсутствует, это будет означать, что физический доступ к данным ключа необходим, прежде чем остальная часть реверсирования может иметь место: http://en.wikipedia.org/wiki/Software_protection_dongle
[4] Всегда есть защитники (например, Themida http://www.oreans.com/themida.php) вы можете получить, который сможет защитить .exe после его сборки (независимо от того, как он был скомпилирован).
... Это должно доставить реверсеру достаточно головной боли.
Но помните, что все это также будет стоить денег, поэтому вы всегда должны взвешивать, чего вы пытаетесь достичь, а затем смотреть на свои варианты.
Вкратце: оба метода одинаково небезопасны. Если вы не используете не компилирующий perl-to-exe maker, в этом случае выигрывает собственный скомпилированный EXE.
Надеюсь, это поможет.
C труднее декомпилировать, чем код Perl, скомпилированный байтами. Любой код Perl, который был скомпилирован побайтно, можно декомпилировать. Байт-компилированный код не является машинным кодом, как в скомпилированных программах на C. Некоторые другие предложили использовать методы запутывания кода. Это просто уловки, чтобы сделать код труднее для чтения, и они не повлияют на сложность декомпиляции исходного кода Perl. Декомпилированный исходный код может быть труднее читать, но существует множество доступных инструментов деобфускации Perl и даже модуль Perl:
http://metacpan.org/pod/B%3a%3aDeobfuscate
Программы упаковки Perl, такие как Par, PerlAPP или Perl2exe, также не обеспечивают защиту исходного кода. В какой-то момент исходный код должен быть извлечен, чтобы Perl мог выполнить сценарий. Даже упаковщики, такие как PerlAPP и Perl2exe, которые пытаются использовать некоторые методы шифрования в исходном коде, могут быть побеждены с помощью отладчика:
http://www.perlmonks.org/?displaytype=print;node_id=779752;replies=1
Это предотвратит случайный просмотр вашего Perl-кода, но даже упаковщик должен распаковать скрипт, прежде чем его можно будет запустить. Любой, кто определился, может получить исходный код.
Декомпиляция C — это совсем другой зверь. После компиляции это теперь машинный код. Вы либо получаете код сборки с большинством декомпиляторов C, либо некоторые из коммерческих декомпиляторов C берут код сборки и пытаются сгенерировать эквивалентный код C, но, если это не действительно простая программа, редко могут воссоздать исходный код.