Русский / Russian English / Английский

Сейчас на форуме:
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

 eXeL@B —› Крэки, обсуждения —› Java crackme / proof of concept
Посл.ответ Сообщение

Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 20 июня 2006 17:00 New!
Цитата · Личное сообщение · #1

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

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

Рассчитано на виртуальную машину Sun, проверял с версиями от 1.4.2_08 до 1.5.0_07 включительно. Если кому-то нужна совместимость с более старой версией 1.4.x - пишите, сделаю. С 1.3.x и старше связываться не буду, ими пусть занимаются историки Должно работать в режиме как клиента, так и сервера (ключ -server).

Главный класс - ValidatorMain, ожидает два параметра: имя и ключ. Для проверки можно использовать пару Stiver и 161052, то есть вызвать

java ValidatorMain Stiver 161052

Если ключ подходит к имени, должно появиться сообщение "Validation successful!". В противном случае программа просто молча завершится.

P.S. Некоторое время пытался понять, в какой раздел форума нужно постить crackme. Нельзя ли где-нибудь (в правилах например) поместить соответствующее указание? Сейчас они примерно равномерно рассеяны почти по всем подфорумам.


{ Атач доступен только для участников форума } - java_crackme.zip



Ранг: 0.3 (гость)
Статус: Участник

Создано: 20 июня 2006 22:02 New!
Цитата · Личное сообщение · #2

BSL//ZcS 380000

ключ + сумма кодов букв имени в кубе должны делиться на 11

имхо, селфмод на жабе - вещь на практике малоприменимая.
хотя бы потому, что jit-компиляция его внятно не жрёт.

например, поставь три вызова твоего патченного метода подряд, и позапускай с ключом -XX:CompileThreshold=2 и без него.



Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 21 июня 2006 16:53 New!
Цитата · Личное сообщение · #3

BSL//ZcS

BSL//ZcS 380000
ключ + сумма кодов букв имени в кубе должны делиться на 11


Замечательно

например, поставь три вызова твоего патченного метода подряд, и позапускай с ключом -XX:CompileThreshold=2 и без него.

Если просто вызовы, то все будет нормально. Ты наверное имеешь в виду изменение байт-кода после того, как по нему прошелся JIT компилятор? Тогда нужно в структуре функции просто обнулять указатель на native code и компилятор переведет ее заново. Я это делать поленился, так как вызов всего один. Посмотри пример в аттаче, он будет давать правильный результат для любого значения CompileThreshold. По крайней мере для любого >1, с ключом -XX:CompileThreshold=1 конца компиляции я так и не дождался




{ Атач доступен только для участников форума } - test_CompileThreshold.zip



Ранг: 22.5 (новичок)
Статус: Участник

Создано: 21 июня 2006 18:33 New!
Цитата · Личное сообщение · #4

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



Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 21 июня 2006 19:59 New!
Цитата · Личное сообщение · #5

wormking
хм, а смысл использовать что-то, что может перестать работать.

Сложный вопрос, попробуй задать его читателям(и писателям) различных книг и статей типа "Undocumented Windows". Ведь тоже никакой гарантии, что в следующей версии Windows или даже после следующего Service Pack'a все точно так же работать будет.



Ранг: 0.3 (гость)
Статус: Участник

Создано: 21 июня 2006 20:20 New!
Цитата · Личное сообщение · #6

Stiver
Ты наверное имеешь в виду изменение байт-кода после того, как по нему прошелся JIT компилятор?

вообще-то, я имел в виду другое.
в самом твоём крякми модифицируемый метод после компиляции перестаёт отрабатывать как должен.

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

Тогда нужно в структуре функции просто обнулять указатель на native code и компилятор переведет ее заново.

А если этот метод заинлайнен где-нить в другом месте?

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

с ключом -XX:CompileThreshold=1 конца компиляции я так и не дождался

по-моему оно вообще так не компилирует, а намертво зацикливается. во всяком случае, по ключу -XX:+PrintCompilation оно ни одного скомпилированного метода не сообщает.



Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 22 июня 2006 18:38 New!
Цитата · Личное сообщение · #7

BSL//ZcS
в самом твоём крякми модифицируемый метод после компиляции перестаёт отрабатывать как должен.

Конечно перестает, ведь я заменяю edtb() на Math.pow(), а при компиляции он снова берет "правильную" edtb. Поэтому при нескольких вызовах надо сбрасывать результаты компиляции. Посмотри переделанный crackme в аттаче, там я вставил 5 вызовов в цикле и они дают правильный результат для любого CompileThreshold благодаря

unsafe.putAddress(native_code, 0L);
unsafe.putAddress(invokcount, 0L);

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

А если этот метод заинлайнен где-нить в другом месте?

Точно, такое может случиться, тогда в этом месте будет вызываться старая версия. Правда это может произойти только с очень маленькими функциями (граница по умолчанию вроде около 36 байт была) или если кто-то вручную -XX:MaxInlineSize увеличит.

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

Да нет, думаю при желании можно и так написать, что везде работать будет. Размер адреса получим через Unsafe.addressSize(), порядок байт можно вычислить, если надо. Хотя вряд ли надо, все putXXX и getXXX и так работают независимо от порядка.


{ Атач доступен только для участников форума } - java_crackme_5.zip



Ранг: 0.3 (гость)
Статус: Участник

Создано: 23 июня 2006 12:29 New!
Цитата · Личное сообщение · #8

Stiver
я заменяю edtb() на Math.pow(), а при компиляции он снова берет "правильную" edtb.

примерно это я и имел в виду, когда говорил, что компиляция селфмод внятно не жрёт.

при нескольких вызовах надо сбрасывать результаты компиляции.

кстати, а куда девается память, в которой они находятся? течёт, видимо?

я вставил 5 вызовов в цикле и они дают правильный результат

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

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

это может произойти только с очень маленькими функциями (граница по умолчанию вроде около 36 байт была)

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

все putXXX и getXXX и так работают независимо от порядка

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



Ранг: 352.4 (мудрец)
Статус: Участник
retired

Создано: 23 июня 2006 18:24 New!
Цитата · Личное сообщение · #9

Stiver
~/java_crackme> java ValidatorMain Stiver 161052
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# SIGSEGV (0xb) at pc=0xfe6a7568, pid=22326, tid=1
#
# Java VM: Java HotSpot(TM) Server VM (1.5.0_04-b05 mixed mode)
# Problematic frame:
# V [libjvm.so+0x6a7568]
#
# An error report file with more information is saved as hs_err_pid22326.log
#
# If you would like to submit a bug report, please visit:
# java.sun.com/webapps/bugreport/crash.jsp
#
Abort (core dumped)



Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 24 июня 2006 10:24 · Поправил: Stiver New!
Цитата · Личное сообщение · #10

BSL//ZcS

кстати, а куда девается память, в которой они находятся? течёт, видимо?

Хм, хороший вопрос, не задумывался. Наверное действительно течет. Беда в том, что проверить сложно, но я попробую. Правда на фоне тех сотен мегабайт, которые Ява и так берет и не отдает, эта пара килобайт особо погоды не делает.

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

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

либо ксорка, либо адресная арифметика, судя по всему, отвалится

Адресная арифметика будет работать всегда, так как getAddress и остальные учитывают системный порядок байт. XOR тоже будет работать всегда, если читать и ксорить побайтово (то есть через getByte, а не getAddress), так как байт-код хранится независимо от системы в big-endian формате.

ssx

А можно уточнить операционную систему? Судя по libjvm.so какой-то Unix или Solaris?



Ранг: 352.4 (мудрец)
Статус: Участник
retired

Создано: 24 июня 2006 21:49 New!
Цитата · Личное сообщение · #11

Stiver
uname -a
SunOS xxxxxxx 5.8 Generic_117350-33 sun4u sparc SUNW,Ultra-Enterprise



Ранг: 48.3 (посетитель)
Статус: Участник

Создано: 25 июня 2006 22:54 New!
Цитата · Личное сообщение · #12

ssx
SunOS xxxxxxx 5.8 Generic_117350-33 sun4u sparc SUNW,Ultra-Enterprise

То есть Solaris 8, если я правильно понимаю. К сожалению доступа к Солярису у меня больше нет и вряд ли будет в обозримом будущем. Но под Линуксом проверю, как из отпуска вернусь


 eXeL@B —› Крэки, обсуждения —› Java crackme / proof of concept

Видеокурс ВЗЛОМ