Как сделать кряк для программы
Взлом программного обеспечения
Взлом программного обеспечения (англ. software cracking) — действия, направленные на устранение защиты программного обеспечения (ПО), встроенной разработчиками для ограничения функциональных возможностей. Последнее необходимо для стимуляции покупки такого проприетарного ПО, после которой ограничения снимаются.
Крэк (также искажённое кряк и, крайне редко, крак) (англ. crack) — программа, позволяющая осуществить взлом программного обеспечения. Как правило, крэк пригоден для массового использования. По сути, крэк является воплощением одного из видов взлома, зачастую, это обычный патч. Для слова крэк используются следующие эвфемизмы: лекарство, таблетка от жадности,аспирин /
Крэкер (также искажённое крякер) (англ. cracker) — человек, который занимается созданием крэков.
Взломщик — это человек, который взламывает программу при помощи уже готового крэка или без такового.
Виды взлома
Практически любой взлом сводится к использованию одного из следующих способов:
Ввод серийного номера (регистрационного кода) (жарг. серийник) (англ. serial number, S/n) — взлом программы посредством введения правильного регистрационного ключа (или фразы), полученного нелегальным способом. Ключ может генерироваться на основе какой-либо информации (имени владельца ПО, характеристик аппаратной части компьютера, и т. п.), либо иметь фиксированное значение. Для генерации регистрационного ключа используется тот же алгоритм, что и в программе.
Регистрационный код может распространяться в ключевом файле (файле лицензии) (англ. keyfile), который обычно помещается в каталог с установленной программой.
Для массового взлома, зачастую, создаётся (и в дальнейшем используется) генератор ключей (жарг. кейген) (англ. keygen сокр. от key generator) — программа для генерации регистрационных ключей (см. выше). Данный вид взлома наиболее востребован (особенно, когда программа часто обновляется или рег. ключ генерируется на основе какой-то информации (см. выше)) и поэтому наиболее ценится. Как правило, требует бо?льшей квалификации взломщика по сравнению с другими видами взлома, но не всегда.
Использование загрузчика (жарг. лоадер) (англ. loader) — способ обходить некоторые виды защиты ПО, заключающиеся в использовании внешних (навесных) систем защиты. Состоит в изменении определённых фрагментов программы в оперативной памяти сразу после её загрузки в эту память, но перед её запуском (то есть перед выполнением кода в точке входа).
Применение (бинарного) патча (часто жарг. крэк или кряк от англ. crack) (англ. byte patch) — способ, похожий на «загрузчик», но модификация производится статически в файлах программы. Как правило, это один из самых простых и быстрых способов взлома ПО.
Использование взломанной версии файла(ов) (англ. cracked) — способ заключается в подмене оригинальных файлов программы файлами, которые уже взломаны.
Использование эмулятора ключа (англ. key emulator) — способ используется для обмана защит, построенных на использовании в качестве защиты электронного ключа (как правило, подключаемого к LPT или USB порту компьютера). Заключается в снятии дампа внутренней памяти ключа. Файл с содержимым этой памяти подаётся на вход специальной программе — эмулятору, которая подключает свой драйвер-фильтр в стек драйверов и обманывает защищённую программу, эмулируя работу с аппаратным ключом. В случаях наличия в программе обращений к ключу для аппаратного шифрования участка памяти этот метод используется в связке с методом Бинарный патч. Современные аппаратные ключи настолько сложны, что, при грамотном их применении, возможно создать защиту, фактически не поддающуюся взлому.
При взломе сложных защит, а также при необходимости достичь максимального эффекта, применяется комбинация вышеперечисленных способов. В редких случаях, это происходит при недостаточной квалифицированности взломщика.
Этот список не является исчерпывающим, а лишь обозначает наиболее встречаемые способы взлома.
Вид взлома, в большинстве случаев, обусловлен видом защиты. Для некоторых защит возможно использовать различные виды взлома, для других — способ может быть единственным. Но есть и такие способы организации защиты, взломать которые невозможно
Принципы взлома
Как правило, в основе работы крэкера лежит исследование ассемблерного кода, полученного из машинных инструкций с помощью специально предназначенной для этого программы-дизассемблера. В зависимости от выбранного способа взлома, результат исследования может использоваться, например, для построения генератора ключей или для внесения необходимых изменений в исполняемый файл. Последний способ в большинстве случаев наиболее лёгкий, так как не требует изучения алгоритма проверки правильности ключа: зачастую взлом сводится к поиску проверки нескольких условий (наподобии «ВведённоеЧисло равно ЭталонномуЧислу?») и замене такого условия на безусловный переход (goto, jmp), или, реже, на противоположное (то есть для данного примера на «ВведённоеЧисло не равно ЭталонномуЧислу?»).
Кроме того, внесение изменений в исполняемый файл (патч) может производиться с целью отключения нежелательных действий со стороны программы (например, напоминание о необходимости регистрации), сокращения функциональности программы. В этих случаях, часто, соответствующие команды процессору заменяются на байты со значением 90h (в шестнадцатеричной системе счисления), что соответствует ассемблерной команде nop (No Operation), то есть «пустой команде», не выполняющей никаких действий. Если таких команд много, то применяется безусловный переход (перепрыгивание ненужного кода). Возможно также расширение возможностей программы написанием дополнительного кода, но, как правило, это слишком трудоёмкий процесс, не оправдывающий временных затрат.
Между тем, патч возможен, как правило, в том случае, когда исполняемый файл программы не защищён специальными «пакерами» и «протекторами» — программами, скрывающими реальный код исполняемого файла. Для последнего типа программ зачастую используется самая интеллектуальная часть обратной разработки (англ. reverse engineering) — исследование кода программы при помощи отладчика и создание генератора ключей, но возможны и другие решения, например, создание загрузчика (см. выше).
Правовые аспекты деятельности
В подавляющем большинстве стран деятельность по взлому программ считается противозаконной (в том числе в России; однако, статус крэков как вредоносного ПО пока не определен). Но дело в том, что факт взлома очень трудно доказать: пользовательское соглашение, как правило, запрещает дизассемблирование программы, а закон — создание и распространение результата работы. Однако, дизассемблированный текст продукта по окончании работы легко уничтожить, а результат работы — распространить по защищенным каналам и выложить на сервере, хостящемся в стране с более либеральными законами. Используемые же в работе программные продукты, утилиты и различные заготовки не считаются вредоносным ПО (хотя и на них закон пытается наложить руку — см. DMCA). В распространении крэкерам помогают и файлообменные сети, поскольку в большинстве из них крайне трудно найти оригинальный источник файла, а уничтожить все его копии и вовсе невозможно.
Глава 28 Уголовного кодекса РФ устанавливает наказания за компьютерные преступления. В соответствии со ст. 272 за крекинг можно получить лишение свободы до 2 лет. При предварительном сговоре группы лиц — до 5 лет. В России практика наказаний за взлом программного обеспечения существует в очень сыром и пока в теоретическом виде. Это вызвано тем что понятие «интеллектуальная собственность» пока ещё точно не определено российским законодательством. Также сам факт крекерства очень тяжело доказать, поскольку тот же антивирус Касперского вносит изменения в файлы при их лечении от вирусов и его действия так же можно классифицировать по ст. 272 УК РФ. Из известных в нашей стране случаев наказания за компьютерные преступления можно выделить пожалуй лишь создание вредоносных программ. Поэтому многие люди в том числе и правообладатели пытаются представить крекеров как создателей вирусов, но на самом деле это в корне неверно.
Если хоть раз мечтал написать crack или keygen
Дня 3 назад заглянул на сайт crackmes.one попробовать силы во взломе защит. Просто наугад взялся за «hitTman’s Kolay One!»: просто по оценке Difficulty: 2.0 и Quality: 4.0. Не примитивно, но и не слишком сложно.
Оказалось, форма ввода пароля с подсказкой: текст кнопки «submit password» после нажатия меняется на число. Если попробовать разные символы пароля, заметно, что для одних и тех же символов число не меняется. Очевидно, пароль подается в хеш-функцию, а ее результат попадает на кнопку. Пробуя пары символов, легко узнать что число на кнопке — сумма чисел для символов пароля.
Логично, что программа сравнивает хеш с эталоном прежде чем выдает сообщение «Try harder!». Ищем в сообщение строках бинарника. Повезло: оно даже не зашифровано и на него единственная ссылка в коде.
Очевидно, рядом же и эталон хеша: 12Eh. Легко проверить: из известных хешей символов составить пароль, например «AaAaAaAaAaAaAaAaAaAaAaAaAaAaAa//» и предложить программе, на что она выдает «Great Job».
Автор просил: «find a Valid pass!», но это оказалось просто, да и верный пароль — не один. Куда интересней написать генератор ключей. Пригодится таблица хеш-значений для всего алфавита. Руками вводить символы пароля и записывать на бумаге их хеши долго и скучно, ведь можно заставить программу саму перебрать алфавит.
У OllyDbg есть коллега — Immunity Debugger, он умеет выполнять скрипты на Python. Отыщем хеш-функцию и заставим ее обработать алфавит.
В обработчике ButtonClick (sub_45385C) прямо перед сравнением хеша с эталоном находится вызов sub_4537C4. Похоже, это и есть хеш-функция: она принимает строку пароля и возвращает хеш в EAX. Привычных push для передачи параметров не видно, вероятно, они передаются через регистры. Если так, то var_C содержит указатель на строку-пароль.
Выше вызов sub_432A4C принимает два аргумента: адрес var_C и еще какой-то указатель по смещению от EBX. Ищем что записано в EBX: выше по коду ButtonClick в него записывается содержимое EAX, но прежде нет записей в EAX, значит там тоже находится параметр процедуры. Заглянув в документацию по Delphi видим, что обработчику ButtonClick передается адрес TObject sender. Можно догадаться, что второй аргумент sub_432A4C — это адрес поля ввода на форме, с которого она читает пароль.
Таких вызовов в ButtonClick два: если запустить программу в отладчике, увидим, что sub_00432A4C действительно записывает указатель на строку-пароль в переменную-аргумент.
Если дальше выполнять ButtonClick пошагово в отладчике, можно заметить, что в переменной на стеке появится и текст кнопки — число. Легко догадаться, что sub_407CE0 — это int to string, [ebx+2FCh] — это указатель на кнопку, а sub_00432A7C — это setButtonText.
Теперь подменим пароль перед хешированием: ставим breakpoint по адресу 0x004538B3 — прямо перед вызовом hashFn она же sub_4537C4. Вводим пароль 1234 и средствами отладчика отредактируем содержимое памяти var_C — введем букву A и символ конца строки \0. Сейчас хеш-функция должна вернуть в EAX значение 0x13 (19). Шагаем вперед и. Первая неудача: в EAX — 0x56 (86). Долго думал, пробовал, грешил на Юникод или еще какие скрытые хитрости программы. Оказалось, программа где-то запоминает длину строки и Вместо хеша «A\0» вычисляет хеш «A\034». Хеш \0 равен 0, поэтому если ввести пароль A34 получим хеш 0x56. Значит введем один символ пароля и повторим правки в отладчике — теперь получилось!
Теперь нужно повторить действия для всего алфавита:
- остановиться перед вызовом hashFn
- сменить символ пароля на следующий по алфавиту
- остановиться после вызова hashFn и запомнить хеш символа
- вернуть программу к вызову hashFn
Вот скрипт на Python, который это сделает:
import immlib imm = immlib.Debugger() def main(args): table = <> # break после hashFn imm.setBreakpoint(0x004538B8) mem_password = imm.getRegs()["EAX"] # цикл по печатным символам ASCII for c in range(0x20, 0x7F): b = bytearray() b.append(c) b.append(b'\x00') if imm.writeMemory(mem_password, bytes(b)) '".format(chr(c))) return "ERROR" imm.run() # запоминаем хеш table[c] = imm.getRegs()["EAX"] # Возвращаемся к вызову hashFn imm.setReg("EIP", 0x004538B3) # снова передали указатель на строку-пароль в EAX imm.setReg("EAX", mem_password) imm.run() # запишем результаты в файл with open("C:/a.csv", "w") as out: for c in table: out.write(" ".format(chr(c))) out.write("0x\n".format(table[c])) return "Kolay done"
Как вариант можно вводить пароль 1234 и вызывать imm.writeLong(mem_password, с), чтобы записать байт символа и три нуля следом.
Алфавитом овладели, правило хеширования пароля знаем. Как генерировать пароли?
Наивное решение: перебор всех ключей и проверка каждого. Вот код, что найдет все ключи длины 2:
const string alphabet = //. const unordered_map weights = //. const int N = 2; const int S = 0x12E; string key; void generateKeys(ostream& out) < if (N > else < for (char c : alphabet) < const int w = weights.at(c); if (sum + w > > >
Работает, но захлебывается уже на ключах длиной больше 5.
От перестановки мест слагаемых сумма не меняется, так что код можно улучшить: пусть он перебирает сочетания.
bool nextCombination(vector& nums, int n) < const int k = nums.size(); for (int i = k - 1; 0 return true; > > return false; > bool TestKey(const vector& nums) < int sum = 0; for (int i : nums) < sum += weights.at(alphabet[i]); >return S == sum; > string MakeKey(const vector& nums) < string key; for (int i : nums) < key.push_back(alphabet[i]); >return key; > void generateKeys(ostream& out) < vectornums(N); for (int i = 0; i < N; ++i) < nums[i] = i; >do < if (TestKey(nums)) < ++cnt; out > while (nextCombination(nums, alphabet.size())); >
Теперь можно дождаться, пока он найдет все сочетания длины 7.
А если хочется ключи длиннее? Можно останавливаться на первом найденном ключе — авось повезет. Время, когда перебор наткнется на первый верный ключ непредсказуемо. Я так и не дождался, пока программа найдет первый верный ключ длины 20.
Можно ли найти лучшее решение, чем перебор всех сочетаний? Например, если известен один верный ключ, как перейти к следующему?
vx -> ?
Аналогия: чтобы получить следующее число, добавляем 1 к младшему разряду и, если необходимо, выполняем перенос:
18, 19, 20, .
Можно заменять символы пароля так, чтобы его хеш не менялся. Беда в том, что для ‘x’ нет равноценной замены.
0x01 001: %)+/5;=CGIOSYaegkmq 0x08 008: 1 0x0c 00c: y 0x0d 00d: # 0x0f 00f: ! 0x11 011: '7 0x13 013: AM 0x14 014: " 0x15 015: 3[ 0x16 016: & 0x17 017: 9U 0x19 019: _w 0x1a 01a: . 0x1b 01b: E 0x1d 01d: s 0x1f 01f: > 0x20 020: : 0x21 021: -W 0x22 022: > 0x23 023: ] 0x28 028: ,JQ 0x29 029: ?o 0x2b 02b: 2 0x2c 02c: R 0x2d 02d: < 0x2e 02e: 4V 0x31 031: K 0x32 032: (^ 0x36 036: * 0x37 037: $ 0x38 038: j 0x39 039: c 0x3a 03a: D 0x3e 03e: v 0x3f 03f: @ 0x40 040: 8Lz 0x41 041: u 0x42 042: 6 0x49 049: b 0x4a 04a: F 0x4c 04c: 0\ 0x4e 04e: B 0x57 057: i 0x5a 05a: N 0x5c 05c: X 0x5e 05e: t 0x64 064: | 0x6a 06a: Phn 0x6c 06c: < 0x72 072: f 0x75 075: d 0x7b 07b: H 0x7e 07e: r 0x88 088: p 0x8c 08c: T 0x90 090: Z 0x9c 09c: ` 0xac 0ac: l 0xba 0ba: ~ 0xf0 0f0: x
Возьмем другой ключ из 3х символов: Zr%. Заменяя % можно пройтись по нескольким ключам:
Zr% -> Zr) -> Zr+ -> . -> Zrq
Попробуем найти замену для rq. Пришлось обойти все пары символов алфавита и вычислить их хеши.
Zrq -> Zt- -> ZtW -> Zuv
Что делать дальше - непонятно. Сменить Z на другой символ? У Z нет равноценных замен, придется перебором снова найти первый подходящий ключ.
Так и не придумал алгоритм перехода от одного известного ключа к следующему: если есть идеи, пишите в комментариях.
Что если вместо перебора всех сочетаний склеивать пары ключей и складывать их хеши? По сложности алгоритм оказался не лучше перебора: время работы быстро растет с увеличением алфавита и длины ключа, к тому же программа падает из-за нехватки памяти. Можно ее чуть сэкономить, но количество пар на каждом шаге все равно растет слишком быстро при алфавите в 95 букв.
// Длина ключа N - степень двойки void generateKeys(ostream& out) < for (int n = 1; n < N; n next_weights; for (auto i = weights.begin(); i != weights.end(); ++i) < for (auto j = next(i); j != weights.end(); ++j) < const string& s1 = i->first; int w1 = i->second; const string& s2 = j->first; int w2 = j->second; int len = s1.length() + s2.length(); if (len == n * 2) < string s3(len, 0); int w3 = w1 + w2; merge(s1.begin(), s1.end(), s2.begin(), s2.end(), s3.begin()); if (len < N) < next_weights[s3] = w3; >if (N == len && S == w3) < out > > > weights.swap(next_weights); > >
Как крякнуть программу ?
Здравствуйте дорогие друзья! Вот я бы хотел узнать как взломать чужую программу! В данном случае это апдейтер-выложу его скрин. Этот апдейтер чит для игры а точнее Warface этот чит не бесплатный так как он приват и что бы этот чит работал нужно активировать ключ этой программы ключ каждого ПК разный и для каждого компа его надо активировать но активация как я уже сказал платная! Вообщем мне бы хотелось узнать можно ли взломать эти ключи или сам чит-апдейтер? Подскажите дорогие друзья можно ли взламывать эти ключи? Данная программа просто пример есть еще сотни таких программ но в данном случае мне надо эту прогу крякнуть! Да и еще если взломать ключи возможно подскажите что учить какую программу использовать что писать на каком языке и. т. г. ну вы поняли! а вот и скрин программы!
Голосование за лучший ответ
Дохрена ты просишь что тебе рассказать. Это надо тут весь учебник по программированию выложить, что ли? ( и не один) Если не знаешь хотя бы элементарных вещей, то лезть в такие дела не имеет смысла.
Можно. Надо изучить основы программирования, ассемблер и дизассемблирование и способы защиты программ. Через два года усердной работы по вечерам сможешь взламывать- ну, не всякую программу, но многие. Естественно, при исходном наличии некоторых способностей к программированию.
Бери дизассемблер и анализируй исходный код.
Если как следует поднатаскаешься в этом деле, сможешь пойти работать в антивирусную компанию, там тебе будут попадаться очень интересные задачки. Но в основном, конечно, всякий шлак авторства безымянной школоты.
Вот был он приватным а ты все испортил
Реально обойти проверку сверки ключа программы с сервером ключей, либо повытаскивать dll (я думаю они более нужны тебе) в общем нужен дизассемблер и вперед отлаживать программу и изучать ее) без знания программирования можешь пойти и купить себе лицензию только) программа называется "RandomHack" Собственно ее автор, так другие читы добавляет в нее)))
Взлом программ для чайников
Disclaimer: всё ниженаписанное написано исключительно с просветительскими и исследовательскими целями, а также понимания механизмов защиты от взлома. Автор ни в коем случае не рекомендует использовать данную информацию для взлома программ.
В данной статье я хочу рассказать про три с половиной основных способа взлома программ на .NET, цель, которую я преследую — помочь разработчикам лучше понять механизмы защиты своих программ, т.е. выяснить наиболее очевидные угрозы и предпринять соответствующие меры (или не принимать).
Я не буду углубляться в детали и использовать сложные инструменты для взлома. Всё будет расписано «для чайников», т.е. все инструменты будут простыми, легкодоступными и бесплатными. А основным будет Reflector, декомпилятор программ под .NET
В качестве подопытного кролика я выбрал Expresso — анализатор регулярных выражений. Данная программа бесплатная, в лицензии вроде бы ничего не указано про взлом, но при этом без регистрации она будет работать всего 60 дней. Другими словами, вред от взлома данной программы минимальный, к тому же внутреннее её устройство очень уж хорошо подходит для тренировки. Буду надеяться, что автор данной программы не обидится на меня.
Для начала краткий ликбез по структуре .NET программы, для тех кто не знаком с разработкой под данный Framework: весь код, написанный на любом .NET языке (C#, Visual Basic, F#, Delphi.NET) компилируется в особый Intermediate Language, называемый обычно IL или MSIL. Это что-то типа ассемблера, только весьма умного и обладающего весьма мощными инструкциями. И это, в принципе, такой же равноправный язык как и C#, только синтаксис похуже (а возможности больше). Кроме того, в программе на .NET активно используются метаданные, т.е. вся информация о классах, метода, пропертях, атрибутах и всём остальном сохранена в исполняемом файле.
Т.е. на самом деле, декомпиляция программы не очень верное понятие в данном случае. Она и так вся в открытом виде лежит, а инструменты в виде Reflector'а занимаются тем, что приводят конструкции MSIL к соответствующим конструкциям C# или другого языка, повышая читабельность кода.
Перейдём, собственно, к взлому.
0. Обнуление триала
Собственно, это даже не взлом, а полулегальный способ продлить срок использования неактивированной программы. Заключается он в том, что находится место, где хранится дата первого запуска и меняется/уничтожается. После этого всё можно пользоваться программой до следующего срока.
Посмотрим на нашего подопытного рефлектором. Немного погуляв по коду, находим интересную строчку в конструкторе MainForm:
Открываем редактор реестра, идём в HKEY_CURRENT_USER\Software\Ultrapico\Expresso и видим следующие ключи:
Удаляем их и получаем ещё 60 дней работы.
Данный вариант, конечно, прост и очевиден, но если он даже был бы сложнее — потребовалось бы чуть больше времени провести в рефлекторе, чтобы выяснить все места, куда пишется информация и зачистить их.
Совет разработчикам, которые будут пытаться записать данные в потаённое место: пишите аккуратнее, а то всё может обернуться проблемами обычным пользователям, у которых почему-то не окажется данного места, или не хватит на него прав.
1. Написание keygen'а
Самый ужасный для разработчика вариант, и самый приятный для конечного злобного пользователя. Программа считает себя лицензионной, никаких страшных телодвижений не нужно делать.
Открываем рефлектор и ищем код на предмет классов содержащих License или Registration, видим:
При вводе имени и кода по имени вычисляется некий хеш, который и сравнивается с кодом.
Данный хеш использует DES и всякие префиксы
Байты конвертятся в строку с помощью данного метода.
Теперь всё выяснилось, открываем IDE и копируем все необходимые куски кода (или сами реализовываем). Осталось только выяснить, какие значения у Prefix, Suffix и параметры реализации MyDES. Я их приводить не буду, это уже технические детали.
В результате генерируем ключ на любое имя и видим:
Защита от кейгенов проста и очевида: использовать в каком либо виде ассиметричное шифрование. Т.е. сделать так, чтобы без знания приватного ключа сгенерировать код было бы невозможно, а данный ключ находится только в одном месте — у автора программы.
2. Использование враппера
Проверка корректности лицензии, достаточно хлопотное дело, и небыстрое. Поэтому разработчики программ обычно проверяют лицензию один раз, и дальше используют полученный флажок — валидна/невалидна (как вариант насколько валидна, если допускается несколько типов лицензии, отличающихся возможностями). Тут можно на этом сыграть, использовав следующий алгоритм:
- Указать программе, что лицензия уже проверена
- Указать программе, что лицензия корректна
С запуском ничего интересного, а в проверке видно, что если уже программа зарегистрирована, то она считает, что всё хорошо и не делает дальнейшую работы по выяснению корректности лицензии.
Воспользуемся этим. Сделаем новый проект, добавим Reference на Expresso.exe и запустим его через себя:
Смотрим, что получилось:
Ну кто бы сомневался.
В данном случае всё оказалось просто, но если бы автор программы заменил публичные свойства на приватные, то всего-лишь пришлось бы использовать Reflection для доступа и всё бы свелось к исходной задаче.
Думаю понятно, как можно пробовать защититься от этого — проверять лицензию периодически, смотреть окружение из которого запущена программа, сделать невозможным установку нужной переменной.
Но все эти защиты приведут к тому, что злоумышленник будет использовать
3. Физический взлом программы
Тут уже всё серьёзно. Программа целиком декомилируется в MSIL а из него уже собирается обратно (помните, я писал, что MSIL это такой же язык как и C#?). Для декомпиляции нам понадобится утилита из SDK под названием ildasm, а для компиляции компилятор из .NET Framework ilasm.
Запускаем ildasm, открываем Expresso.exe и сохраняем дамп в .il файл. Находим уже рассмотренный метод IsRegistered и добавляем немножко своего кода (без меток):
Потом берём ilasm и собираем всё назад (не забыв подключить ресурсы).
Что делает данный код: устанавливает нужное имя для регистрации (не обязательно), и возвращает статус, что всё хорошо.
Чтобы было понятнее, так это выглядит в рефлекторе, в C#
Т.е. вполне очевидно, что теперь всё будет хорошо:
Немного про код в MSIL: это стековая машина, у которой нет регистров, все операции имеют вид: засунуть в стек нужное количество параметров, выполнить функцию, которая заберёт нужное количество параметров и положит результат. Ну и обратно: установить значение переменной тем, что лежит в стеке. Чтобы лучше понять работу всего этого рекомендую простой приём: пишите маленькую программу на привычном языке, компилируете, смотрите что получилось в MSILe и разбираетесь в конструкциях языка.
При этом некоторые вещи в MSIL можно сделать очень красиво, например поменять две переменные местами — 4 симпатичных строчки (на C# меньше, но некрасиво).
Чем жертвует злоумышленник: подписью программы, теперь она уже не автора, а его. В некоторых случаях это проблема, если в программе используется множество библиотек. Тогда злобному хакеру придётся разбирать их все и собирать их заново, но если он с этим справится, то у него будет «своя» версия программы подписанная его ключом.
Защиты от всего этого безобразия собственно немного: проводить обфускацию или выносить часть логики/проверки защиты в нативный код.
Заключение
Думаю я рассказал, как просто всё можно разломать на .NET, если создатель не приложил усилий для защиты своей программы. А вы уж решайте, стоит ли делать защиту и тратить на это время и ресурсы. А может просто сделать web-систему, или же бесплатную ограниченную версию. Решать разработчикам.
- Информационная безопасность
- .NET
- Софт