Обратный инжиниринг, скомпилированный Perl или C?

Иметь клиента, который утверждает, что соблюдает C, сложнее реконструировать, чем sudo «скомпилированный» байт-код Perl или тому подобное. У кого-нибудь есть способ доказать или опровергнуть это?


person blunders    schedule 11.03.2011    source источник
comment
Какой компилятор вы используете для компиляции вашего Perl-кода? Если он компилируется в машинный код, то не должно быть никакой разницы, однако, если его байт-код, тогда это может быть проще.   -  person Cody    schedule 11.03.2011
comment
Сложнее на основании чего? Я уверен, что больше людей более знакомы с обращением ASM популярной архитектуры, чем с байт-кодом Perl, но это не означает, что это по своей сути сложнее.   -  person yan    schedule 11.03.2011
comment
+1 @Cody: Если можно легко скомпилировать Perl в машинный код, то да. Если нет, но байт-код прост, то байт-код.   -  person blunders    schedule 11.03.2011
comment
+1 @yan: более сложный уровень навыков, стоимость используемых методов, время выполнения и т. д.   -  person blunders    schedule 11.03.2011
comment
Я думаю, что реверсирование c намного сложнее, чем реверсирование perl в теории. Но вполне возможно, что доступные инструменты реверсирования для Perl гораздо менее развиты, что усложняет их практическую работу.   -  person CodesInChaos    schedule 12.03.2011


Ответы (6)


Я не очень хорошо разбираюсь в perl, но приведу несколько примеров того, почему реверсирование кода, скомпилированного в ассемблер, выглядит так уродливо.

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

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

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

Кроме того, есть микрооптимизации, которые могут раздражать. Например, однажды я потратил более 15 минут на реверсирование простой функции, которая когда-то была похожа на return x/1600. Потому что компилятор решил, что деление медленное, и переписал это деление на константу на несколько умножений-сложений и побитовых операций.

person CodesInChaos    schedule 11.03.2011
comment
. у вас было это: hex-rays.com/decompiler.shtml? Вероятно, потребовалась бы 1 секунда, чтобы добраться до x/1600; у этого есть свои причуды, но он настолько хорош в сценариях RE, что стоит огромных ценников, если вы выполняете RE как повседневную работу. - person chkdsk; 30.04.2011
comment
@Pra Нет, это немного превышает мой бюджет. И хотя это может решить некоторые проблемы (например, в примере с x/1600), потерю информации о типе трудно исправить. От кого-то, кто использовал этот декомпилятор несколько лет назад, я слышал, что результаты были не такими впечатляющими, но, возможно, с тех пор они стали лучше (тогда декомпилятор был довольно новым) - person CodesInChaos; 30.04.2011

Perl очень легко обратно разработать. Предпочтительный инструмент — vi, vim, emacs или блокнот.

person David Harris    schedule 11.03.2011
comment
Да, теперь, когда perlcc отсутствует в основном дистрибутиве и для некоторых больше не является вариантом. - person Matt K; 12.03.2011

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

person Colin Newell    schedule 11.03.2011

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

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

person Jerry Coffin    schedule 11.03.2011

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

Для мотивированного обратного инженера оба будут одинаковыми.

Если вы используете создатели псевдо-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.

Надеюсь, это поможет.

person chkdsk    schedule 12.03.2011
comment
кстати, [1] и [2] должны выполняться как процесс сборки, а не как процесс разработки, поэтому вы никогда не повлияете на свое исходное дерево этим шумом, иначе вы не сможете нанять кого-либо для поддержки вашего кода: P - person chkdsk; 12.03.2011
comment
+1 @PrashantGupta: Только для этого ... вам нужно сделать реверсирование более дорогим, чем писать его самостоятельно - кроме того, все дополнительные ссылки и предложения очень помогают, спасибо !! - person blunders; 12.03.2011
comment
+2 @PrashantGupta: иначе вы не сможете никого нанять для поддержки вашего кода... я рассмеялся, просто думать о редактировании кода %@*$ довольно забавно. И да, я согласен, что Perl B::C (www.perl-compiler.org) выглядит интересно. Спасибо! - person blunders; 12.03.2011

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, но, если это не действительно простая программа, редко могут воссоздать исходный код.

person Deleted Account    schedule 12.03.2011