Перейти на [ главную страницу, гостевую книгу, форум ] или остаться... |
Сайт CRACKL@B всегда рад разместить на своих страницах любые ваши наработки в области крэка (кроме самих крэков). Присылайте свои статьи, программные разработки, исходники, советы и другие полезности по адресу bad_guy@mail333.com, достойные работы будут занимать достойное место на страницах CRACKL@B !
Этот документ создан для Offline изучения. Прошу не размещать данный документ на вашем сайте или домашей странице. Материалы, входящие в состав документа разрешается размещать только при согласии автора каждого конкретного документа. Конечно, вы можете наплевать на все эти просьбы, но мы вам этого никогда не простим :-E
Предлагаю вашему вниманию статьи крэкеров-профессионалов и любителей, отсортированные по дате добавления. Поле ТЕМАТИКА расшифровано в самом низу. Поле КОМУ - кем вы себя считаете ? новичком или крэкером - не важно - читайте все подряд - полезно в любом случае !
Статьи лучших авторов
Название | Автор | Кому | Тематика | Добавлено |
Bad_guy | крэкеру | Z#@ | 28.07.2003 | |
Bad_guy | крэкеру | ZF# | 26.07.2003 | |
MozgC | новичку | K@ | 08.07.2003 | |
-=SouL=- | новичку | L | 08.07.2003 | |
MozgC | новичку | F#@ | 22.06.2003 | |
Wersion | крэкеру | UP# | 06.06.2003 | |
Bad_guy | новичку | # | 16.03.2003 | |
freeExec | крэкеру | P# | 07.03.2003 | |
Bad_guy | новичку | #@ | 06.02.2003 | |
Bad_guy | новичку | Z | 29.01.2003 | |
От простого к сложному: три способа взлома на основе Audio MP3 Maker 1.12. | Fess | новичку | PFK@ | 09.01.2003 |
Fess | новичку | #@ | 09.01.2003 | |
Fess | новичку | #@ | 09.01.2003 | |
Hex | крэкеру | U# | 07.01.2003 | |
Встраивание своего кода в чужие проги с целью "краканья на лету" ... | Vallkor | новичку | P#@ | 06.01.2003 |
Vallkor/Fess | новичку | #@ | 06.01.2003 | |
Bad_guy | новичку | F | 14.10.2002 | |
Bad_guy | новичку | P# | 24.09.2002 | |
Bad_guy | крэкеру | Z@ | 29.08.2002 | |
Мой алгоритм действий при взломе ShareWare программы, защищённой паролем. | Bad_guy | новичку | # | ??.??.2002 |
Bad_guy | новичку | F | ??.??.2002 | |
Bad_guy | новичку | # | ??.??.2002 | |
Как отучить игры от проверки CD-ROM (на примере игры Hellfire). | ??? | крэкеру | P#@ | ??.??.2002 |
ED!SON [UCF] | новичку | FP#@ | ??.??.2002 | |
??? | новичку | K#@ | ??.??.2002 |
Как вы уже могли заметить в списке статей присутствует поле ТЕМАТИКА, в котором зашифрована тема каждой из статей, присвоенная Bad_guy'ем. Вот расшифровка этого поля:
U - ручная распаковка упаковщика или протектора
P - взлом пропатчиванием
L - взлом лоадером
F - взлом нахождением правильного ключа
K - создание кейгена
E - ошибка в защите
Z - противодействие крэкеру (защита)
# - оригинальная идея/статья
@ - награда "CRACKL@B: Отличная статья !"
Посетители могут советовать мне присвоить статье эту награду.
Если тематика комбинированная, то поле содержит несколько символов тематики, к примеру распаковка и пропатчивание, в данном случае выглядит, как: UP.
Все статьи размещены на сайте http://cracklab.narod.ru/doc/ с личного разрешения авторов !
Данный CHM-документ создан 30 августа 2003 года
Подборка статей и дизайн: Bad_guy <bad_guy@mail333.com>
Выражаю благодарность всем авторам: Hex, Fess, Vallkor, Wersion, freeExec, MozgC, ED!SON, -= SouL =-
Передаю приветы: [RU].Ban0K!, .::D.e.M.o.N.i.X::., -= ALEX =-, FEUERRADER, MoonShiner, dragon, Runtime_err0r, Broken Sword, EGOiST, Fox Mulder & for YOU !
Respect to my little town - St.Petersburg.
Статью написал: Bad_guy
Статья создана: 28.07.03
Однажды я придумал одну интересную защиту и решил реализовать её в виде CrackMe, дабы проверить её на прочность, что ж - это было сделано и этот крэкми вы можете скачать и попробовать сломать прямо сейчас, не читая до конца эту статью, а иначе будет неинтересно. СКАЧАТЬ (140 Кб)
1. Защита от String Reference взлома.
2. Использование самомодифицирующегося кода.
3. Немножко самодельной криптографии (хэш).
4. Использование регистрационного кода в качестве адреса процедуры.
Давайте по порядку разберёмся с каждым из этих пунктов, что они нам дают и зачем.
О таком способе взлома своих программ программисты обычно никогда не задумываются. А суть взлома здесь в следующем: в скомпилированной программе содержатся строки типа "Registered", "UNREGISTERED", в общем все, которые программист "вбил" в исходники. Начинающих крэкеров учат ломать проги таким способом: дизассемблируем программу с помощью WinDASM, нажимаем кнопочку String Reference и ищем вот такие подозрительные строки, потом кликаем по подорительной строчке и смотрим откуда она вызывается, смотрим выше, находим jne,jnz,jz или je и меняем на противоположную команду, после чего программа становится зарегистрированной.
Как здесь от этого я избавился: сначала написал всю программу, затем скопировал все строковые константы в отдельный текстовый файл, вот такие там были строки:
lKeoOIwjk34uGFqi
*
Name:
Serial#:
Register
About
! Unregistered !
REGISTERED
Ошибочка, видимо ключ поддельный.
До взлома ещё очень далеко.
До взлома ещё далеко.
Поднапрягись !
А ключик то поддельный !
Ты ещё ничего не сделал !
А потом берём и пишем простую программку:
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
var f,f1: textfile;
s,s1: string;
i: integer;
begin
assignfile(f,'name.txt');
reset(f);
assignfile(f1,'name2.txt');
rewrite(f1);
while not eof(f) do
begin
readln(f,s); s1 := '';
for i:= 1 to length(s) do
s1 := s1+'cr('+Inttostr(integer(s[i]))+')+';
writeln(f1,s1);
end;
closefile(f);
closefile(f1);
end.
затем берём получивишийся файл name2.txt и из него вставляем вместо строковых констант в исходники новые строки:
cr(78)+cr(97)+cr(109)+cr(101)+cr(58); - Так выглядит слово "Name:" и так далее.
И ещё вставляем в код программы процедуру cr:
function cr(bb: byte):string;
begin
cr := chr(bb);
end;
Вот так легко избавится от String Reference крэкеров-новичков.
C СМК всё сложнее, тут нам надо будет вмешиваться в скомпилированный файл:
у меня была процедура:
procedure Reg;
var il2: longint;
begin
{расшифровщик кода}
asm
push eax
push edx
push ecx
mov edx, 10 // длина полезного кода (в байтах / 4) (1)
mov eax,ilong
mov il2,eax
add il2,40 //указатель на начало полезного кода (2)
@im:
mov ecx, [il2]
mov eax, [ecx]
xor eax, $96969696
mov [ecx], eax
add il2, 4
dec edx
jnz @im
pop ecx
pop edx
pop eax
end;
{полезный код}
form1.Status.Color := clGreen;
form1.Status.Caption := cr(82)+cr(69)+cr(71)+cr(73)+cr(83)+cr(84)+cr(69)+cr(82)+cr(69)+cr(68);
end;
Константы (1) и (2) пришлось подправить вручную в скомпилированном файле. Также кусок полезного кода был сложен по модулю 2 (xor) с константой 96h, затем я поменял атрибуты секции .code исполняемого файла с помощью программы LordPE на E0000020, чтобы код мог самомодифицироваться, то есть был бы доступен на запись. (...мало кто это поймёт с десятого раза...)
Вспомним криптографию и сделаем небольшую простенькую хэш функцию:
Function Md5(ms: string):int64;
var mt,ms2: string; imt: int64; imt1: integer;
w: array [0..7] of byte absolute imt;
begin
mt := cr(108)+cr(75)+cr(101)+cr(111)+cr(79)+cr(73)+cr(119)+cr(106)+cr(107)+cr(51)+cr(52)+cr(117)+cr(71)+cr(70)+cr(113)+cr(105);
ms2 := '';
ms2 := ms + cr(42);
imt := $1AFD2FDE3ABC4975;
for imt1 := 1 to length(mt) do
begin
w[imt1 mod 8] := (w[imt1 mod 8]*integer(ms2[(imt1 mod length(ms2))+1])) mod 256;
end;
md5 := imt;
end;
Не подумайте, что это правда алгоритм MD5 - это простенькая самоделка созданная для возможности реализации электронной подписи и контрольной суммы, а она будет полезна для проверок формата регистрационного кода.
О таком способе я писал уже в своей статье "Ещё одна защита ваших shareware программ и как её снять", но теперь могу сказать, что в той статье много смешных для опытного крэкера вещей, хотя сам принцип никуда не делся.
Вкратце: Для использование регистрационного кода в качестве адреса процедуры надо чтобы регистрационный код так или иначе нёс в себе константу - адрес процедуры, к тому же придётся залезть в отладчик, а ещё пропатчить скомпилированный исполняемый файл, дабы убрать вызов процедуры вида
Call 0040213D
и заменить на вызов вида
mov eax, Regaddr
Call eax
где Regaddr это тоже самое число 0040213D, но передаваемое в регистрационном коде. Помнится, что пару лет назад все в своих статья писали, что "на вашем компьютере адрес может быть и другой", но мой опыт в крэкерстве и знания формата PE позволяют мне сделать вывод, что адрес этот на всех компьютерах будет абсолютно одинаков, а даже если это и не так, то есть хитрые функции, которые позволяют узнать содержимое EIP (текущий логический адрес в исполняющемся коде), и тем самым подкорректировать значение RegAddr.
Теперь подробно. В данном крэкми было сделано всё так:
procedure TForm1.Button1Click(Sender: TObject);
var snm : string; inm: integer;
begin
if length(Edit2.Text) = 20 then
begin
snm := InttoHex(md5(Edit1.Text),16);
for inm := 1 to length(Edit2.Text) do
begin
if not(Edit2.Text[inm] in ['0'..'9','A'..'F']) then
begin Showmessage('До взлома ещё очень далеко.'); exit; end;
end;
if copy(snm,1,8) <> copy(Edit2.Text,1,8) then
begin Showmessage('До взлома ещё далеко.'); exit; end;
if Copy(InttoHex(md5(Copy(Edit2.Text,1,16)),16),4,4) <> copy(Edit2.Text,17,4) then
begin Showmessage('Поднапрягись !'); exit; end;
ilong := StrToInt('$'+Copy(Edit2.Text,1,8));
ilong := ilong xor StrToInt('$'+Copy(Edit2.Text,9,8));
//Проверим правильность адреса.
if Copy(InttoHex(md5(IntToHEX(ilong,8)),16),5,8) <> IntToHEx($E8484694,8) then
begin Showmessage('А ключик то поддельный !'); ilong := 0; exit; end;
ilong := ilong xor $5CD37EA6;
end
else
Showmessage('Ты ещё ничего не сделал !');
end;
Переменная ilong после всех проверок будет содержать адрес процедуры, если был введён правильный код, если нет, то ноль.
Теперь подробно расскажу алгоритм этой процедуры.
Edit1.Text - туда вводится имя пользователя (ИП)
Edit2.Text - сюда регистрационный код (РК).
Сначала сравниваем длину РК - она должна быть 20 символов. Вычисляем хэш ИП. Затем проверяем, чтобы РК содержал только HEX символьные числа ('0'..'9','A'..'F'). Первые восемь символов РК сравниваем с 8 символами хэша ИП. Вычисляем контрольную сумму первых 16 символов РК и сравниваем ее с 4 последними символами РК. Если все предыдущие проверки прошли успешно, то ксорим первые восемь символов РК, с последующими 8 символами, то есть не символы, а числа, полученные на основе перевода из строкового в числовой формат и помещаем их в переменную, которая и будет являться хранителем адреса процедуры (ilong).
Мы дошли до места отмеченного в коде, как
//Проверим правильность адреса.
Всё, что было до этого в данной процедуре, является ерундой и тренировкой для крэкера-новичка, а теперь уже серьёзные вещи пойдут.
Copy(InttoHex(md5(IntToHEX(ilong,8)),16),5,8) - этот код считает хэш получившегося в ilong адреса и возращает его в виде 8-символьной строки. А этот код IntToHEx($E8484694,8) возвращает также 8-символьную строку, но с хэшем правильного кода. Прошу обратить внимание на то, что это ничего не даёт крэкеру, потому как хэш - необратимая функция. Однако здесь есть небольшая слабость защиты. Однако её никто не заметил. Но я всё же расскажу о ней:
Если взять переменную $E8484694 и процедуру md5, то можно написать небольшой брутфорсер, то есть меняя ilong подвергать её хэшированию и сравнивать с константой. Вы скажете, что это долго и так далее... нет, вы ошибаетесь. Дело в том, что адресное простраство исполняемого кода - не велико, ну к примеру от 401000 до 44A26C в моём случае, а это - всего лишь 300'000 комбинаций, что брутфорсится очень быстро. Так что я поступил весьма легкомысленно в этом месте кода.
Вернёмся к коду и увидим, что при положительном результате проверок он заканчивается следующей строкой, значение которой я поясню ниже.
ilong := ilong xor $5CD37EA6;
И что же дальше... А дальше надо было бы вызвать процедуру регистрации подобным образом:
mov eax, ilong
Call eax
но я решил ещё раз поиздеваться над своими коллегами и поставил для этого аж целый таймер, который работал со скважностью 512 миллисекунд.
procedure TForm1.Timer2Timer(Sender: TObject);
begin
Test(ilong);
end;
Теперь посмотрим процедуру Test:
procedure Test(kk: longint);
begin
if kk = 0 then exit;
try
asm
mov eax,kk // Неявный вызов процедуры Reg;
call eax //
end;
except ilong := 0; ShowMessage('Ошибочка, видимо ключ поддельный.');
end;
end;
Если адрес нулевой - то выходим из процедуры, а если ненулевой, то пытаемся сделать вызов процедуры, находящейся по этому адресу. Если же крэкер решил обмануть программу и подсунуть другой адрес, то он обломается, потому как программа попадёт на случайный код или вообще не в адресное пространство программы (это опасно, но ведь скока проверок было... так что крэкер рискует сам своими компом) и, естественно, полезет окно с ошибкой, которое мы поймаем с помощью блока try...except и выдадим в except свой обработчик ошибки вместо стандартного окошка.
Честно говоря поначалу нужно писать не так:
asm
mov eax,kk // Неявный вызов процедуры Reg;
call eax //
end;
а вот так:
Reg;
asm
mov eax,kk // Неявный вызов процедуры Reg;
call eax //
end;
Reg откомпилировалось у меня как Call 00449F34 и я заменил это на NOP команды с помощью отладчика и HEX редактора, а число 00449F34 запомнил.
Строка
ilong := ilong xor $5CD37EA6;
в коде процедуры Button1Click позволяет за счёт ксоринья с константой подгонять код до нужного нам 00449F34 без перекомпиляции, которая может нарушить адрес функции. Это делается опять же путём правки этой константы в HEX-редакторе.
Также был поставлен ещё один таймер, который должен был мешать крэкеру прерываться по hmemcpy. Но он работает у меня с интервалом 666 миллисекунд, а это, как я потом понял, слишком большой интервал и можно успеть прерваться по реальному вызову. Но это скорее что-то типа дополнительного прибамбаса, который вообще-то просто обойти в любом случае, особенно учитывая, что сейчас модным стало использование дизассемблеров WinDASM, IDA и прочих, которые дают крэкеру адрес полезного кода.
procedure TForm1.Timer1Timer(Sender: TObject);
var stm: string; itm : integer;
begin
stm := Edit1.Text; // вызов hmemcpy
for itm := 1 to length(stm) do stm[itm] := cr(42)[1]; // затираем строку звездочками
end;
Есть ещё одна хитрость, которая была замечена начинающими крэкерами. Дело в том, что после всех необходимых правок в скомпилированном файле, я его решил еще и запаковать компрессором UPX. Но у меня есть ещё и GUI оболочка для него UPXShell называется. И эта программка позволяет сделать так, чтобы запакованный с помощью UPX файл нельзя было распаковать командой
upx -d crackme.exe
Однако мне стало интересно, как же это достигается. А достигается это просто: после запаковки UPX файл содержит код 555058210С который выглядит в блокноте, как "UPX!.", а программка UPXShell заменяет последний байт в этом коде на FF, то есть получается 55505821FF и в блокноте "UPX!я". После этого программу не распаковать UPX'ом, но если вручную поменять этот байт обратно на 0C, то всё восстановится и программа распакуется.
Пока эту защиту реально смогли взломать 2 человека и ещё третий не до конца аккуратно разобрался, хотя и дошел до функции регистрации. Не буду говорить, что это им далось легко - потребовалась фантазия и нестандартный подход к взлому, именно поэтому не каждый, кто называет себя крэкером и может запускать игрушки "без диска", сможет взломать данную защиту.
Возможно, вам будет интересно почитать обсуждение взлома данного крэкми, которое проводилось на форуме CRACKL@B, поэтому не поленюсь привести его здесь:
ТЕМА: Взломай CRACKL@B CrackMe #1 | |
Bad_guy | Написан первый крэкми "CRACKL@B CrackMe #1" - http://cracklab.narod.ru/dload/clab1.rar Предлагаю всем попробовать сломать этот крэкми, а у кого получится срочно сообщите мне ! Думаю, вам будет интересно посидеть над взломом этой защиты. Особенно мне интересно, что смогут сделать с этой защитой (если конечно станут ломать) такие люди, как freeExec, Hex, Moonshiner, Fess, Perch (ну и все остальные, кто там... звиняйте, кого забыл). |
MozgC | Да ниче не смогут сделать =) |
MoonShiner | Yes!!!! Меня поставили в один ряд с такими монстрами:) ЗЫ Кстати, нужна ли статья по распакове нового аспра который в ISOCommander 14? Там много новых интересных штучек:) |
freeExec | Можно просто фичи перечислить |
MozgC | Не надо фичи просто перечислять. Нужна статья конечно, что глупости спрашиваешь =)
И убери эту идиотскую подпись =) |
MoonShiner | Фичи там веселые... 1) SuperBpm и патч ntdll.dll не проходят, аспр их как то палит или хз, что еще, лень было разбираться. Короче, когда они активизированы, прога просто не пойдет. 2) Новый (может только для меня) метод спирания байтов. К примеру спертая команда "push ebp" там эмулится как "mov [esp],ebp sub esp,1B add esp,17", и все это разбавлено кучей полиморфного бреда и самого рабочего кода аспра. 3) Немного изменен механизм эмуляции некоторых АПИ-функций. Ну и еще всякая разная несущетсвенная шняга...
ЗЫ Че то Bad_guy там намутил, у меня уж крыша едет:( |
MozgC | Блин, Мунш, молодец, а метод спирания байтов дейтствительно новый, нигде такого еще не видел. Ты скажи как ты антиотладочные приемы то обошел ? |
MoonShiner | Я по ним по F8 и F10 просто не гулял:)
|
MozgC | А можно поподробне чуть-чуть а то я изведусь пока статьи дождусь =) |
dragon | Я писал статью про этот аспр, у Bad_guy’я валяется. Обещал на сайт выложить, да чего-то не выложил... |
MozgC | Ты когда успел ? =) Я думал этот АСПР только пару неделек назад в инете появился...
А Bad_guy тебя наебал =)) |
dragon | Он уже давно появился, месяц назад, а может и ещё раньше. А насчёт Bad_guy не понял, ему же выгоднее чтобы статей на сайте больше было. |
MozgC | да я пошутил, попробуй ему написать еще раз |
MoonShiner | Нифига не поддельный ключик!!! Bad_guy, сам ты поддельный! |
MozgC | Лех, ты про че ? |
Bad_guy | Какой-то заговор вокруг меня затевается, я еле догадался о чем это MoonShiner говорил, что я поддельный. А ведь он единственный кто тут по теме топика высказался, а кто про что (и про Аспр любимый и про остальное...). 2 MoonShiner: Если мой крэкми говорит, чта ключ поддельный, значит он поддельный, понимаишш. А статью почему бы нет - размещу, только она должна быть на _русском_ языке (подчеркиваю). 2 MozgC: Не надо так шутить... и скоро выложу твою статью. 2 Dragon: Взлом alcohol 120% уже готова для публикации - завтра-послезавтра будет большое обновление - 10-12 статей разных авторов, что мне пришло за последний месяц. 2 freeExec & all: ну так как у вас дела с моим крэкмисом ???? Ежели никто не справится придется до Hex’a стучаться. |
freeExec | До конца месяца не колись. Счас просто со временем напряг :( |
MozgC | "А статью почему бы нет - размещу, только она должна быть на _русском_ языке (подчеркиваю)."
Вот в этот то вся и проблема... Муншайнер то у нас только на древне-индийском пишет =))))))))))))))) |
MoonShiner | Тааак... Не ходил ночью сюда и уже всякие камни в мой огород. На нормальном я языке пишу, это только некоторым людям описалово давай на уровне букваря:) А freeExec прав - подожди хоть пару недель, щас косяки со временем... |
dragon | Я тоже поддельный ключик нашёл - D0C8345C901234565708, на своё имя. Осталось только настоящий найти... |
Bad_guy | Для dragon: Поддельный - это недоделанный настоящий. Только вот в этом то и главная хитрость... 2 All: Кстати, гружу сейчас 12 новых статей на CRACKL@B/DOC |
dragon | Да, конечно, попробуй этот адрес подбери... Единственное, что я знаю про эту процедуру, то, что она должна подменить адрес в стеке с 44A242 на какой-то другой, а вот какой, хрен знает. Так что это даже двойная защита. |
Bad_guy | Да уж, это не Аспротект какой-нибудь сраненький, а Бэдгайпротект. Только я вот непонял почему эта процедура должна адрес в стеке поменять - она только делает вот что: расшифровывает свой код и изменяет статус зарегистрированности программы (пишет в статусе, что она зарегистрирована и меняет цвет с красного на зелёный). А вот где она находится - в этом и есть вся суть защиты (я лично найти это место не смогу, потеряв бумажку, где у меня это записано). А первые 8 символов в регистрационном коде кто угодно найдёт - это не проблема. |
MozgC | "Да уж, это не Аспротект какой-нибудь сраненький, а Бэдгайпротект."
Это будет Бэдгай протект когда можно будет запустить файлик,и он запротектит программку, причем каждый раз с разными адресами/и другими данными =) |
Bad_guy | Для MozgC: да знаю я всё, только тогда я уже буду вам не коллегой, а противником... |
MozgC | BGProtect 2.3x [SuperMegaNew Strain] =))) |
MoonShiner | Народ, а мож нам Bad_guy’a замочить, пока не поздно, чтобы в будущем нам жизнь не портил? |
MozgC | да не, он вроде написал что не собирается сторону менять =) |
Bad_guy | Для MozgC: BGProtect 2.3x [SuperMegaNew Strain] - а что, мне нравится Для MoonShiner: Вы сначала с Солодовниковым разберитесь. Да, кстати, сижу тут разбираюсь, как архиваторы делать... намёк понят ???
Пора составить Аспротекту конкуренцию, а то очень хотса стипендию побольше получать |
freeExec | Врятли у тебя получится архив запаролить не одним паролем. Намёк понял? |
Bad_guy | Конечно, велосипед мне уже не изобрести. И узнав один ключ можно наделать своих для любого имени. Это уже давно известно и в ASProtect и в продуктах Elcomsoft. |
ТЕМА: CrackME от Bad_guy’я ВЗЛОМАН!!! | |
dragon | Проверяйте, имя dragon, код D0C8345C9917A3000E4B.
В общем я нашёл эту процедуру, которая регистрирует прогу. Я уже всё перебрал, но наконец, мне взбрело в голову поискать в листинге IDA редкие инструкции. Вот ищу, по алфавиту, и мне в глаза бросилась aaa по адресу 449F7C. Начало этой процедуры - 449F34. В ней же я увидел xor eax, 96969696h, т.е. стало понятно, что эта процедура что-то расшифровывает. Я сунул в 44D880 этот адрес, и всё, типа зарегил. По алгоритму проверки подобрал код. Короче, код подбирается так - первые 8 символов подсматриваются, затем ксорим 5CD3407D с адресом 449F34, получаем 5C97DF49, затем этот результат ксорим с перевёрнутыми первыми 8 символами(у меня 5C34C8D0), и ставим этот результат в середину, причём тоже наоборот. Последние 4 символа тоже подсматриваются. Вот и весь CrackMe |
MoonShiner | Блин, опередили меня:((( MoonShiner 44A6686670392C664D86 Тока я че то не понял, почему он хоть цвет надписи и меняет, но все равно пишет, что ключик поддельный:( 2dragon А ты молодчина:)) Я то как кретин сидел в ИДЕ и почти весь код просматривал насчет закриптованности и подозрительных инструкций рядом. И наконец нашел... Скажи, почему ты стал искать подозрительные инструкции? С чем это связано?
|
dragon | Ну в описании же написано, что код полиморфный, обычно в листинге видны идиотсткие команды, типа aaa, aam, aas, cli, in, out, lock XXX, и.т.д. Вот я стал их искать, и с первой попытки нашёл aaa. Вот так. А код цвет меняет, но пишет, что ключ поддельный, потому что не от того адреса наверное расчитывал. Рассчитый по моей методике, и он будет точно правильный. |
Bad_guy | Браво, dragon !!! Действительно, у меня на бумажке написан код 449F34 - это адрес процедуры. Но, не думайте, что всё так просто, я ведь могу и не xor eax, 96969696 делать, а xor eax, КЛЮЧ или того пуще криптографический алгоритм взять: DES, Blowfish. Так что это был лишь шанс для взлома. Хотя это всё и не умаляет достижения dragon’a. |
Bad_guy | >Проверяйте, имя dragon, код D0C8345C9917A3000E4B. На всякий случай проверил - всё сходится с моим кейгеном ! |
Bad_guy | А у Moоnshiner’a код неправильный ! Регистрационному имени MoonShiner не соответствует.
2 dragon: интересно, сколько раз ты комп себе вешал моим крэкмисом. Я так, пока отлаживал - раз 8-10 перегружался. |
MozgC | А Муншайнер че не молодец ? =)) |
Hex | Похоже только я пошел научным путем :) А не поиском хз чего :) Я шел по коду Button1Click и увидел вот это UPX1:0044AAE5 xor esi, eax UPX1:0044AAE7 mov ds:dword_0_44D880, esi и это UPX1:0044AD5A xor ds:dword_0_44D880, 5CD3407Dh сразу навело на мысль о том что 44D880 - это переменная содержащая адрес процедуры расшифровки. Банальный просмотр XREF на этот адрес привел к: UPX1:00449F59 mov eax, ds:dword_0_44D880 UPX1:00449F5F mov [ebp+var_4], eax UPX1:00449F62 add [ebp+var_4], 48h UPX1:00449F66 mov ecx, [ebp+var_4] UPX1:00449F69 mov eax, [ecx] UPX1:00449F6B xor eax, 96969696h и т.д.
Ну дальше вы знаете. Код искать в лом, ибо и так все ясно. P.S. Если бы не эта мелочь, то я тоже бы сидел и искал "редковстречающиеся инструкции" :) |
MoonShiner | Как так? У меня меняет надпись на зеленую и говорит, что порегена. Правда табличку все равно выдает, что ключ поддельный:) Но мне влом дальше ковыряться, хоть там и не долго...
Убравший идиотскую подпись |
MozgC | Да это наверно косяк bad_guy’я, что табличка цвет меняет и прога гаворит что зарегена =) |
Bad_guy | Чтож, Hex и есть Hex. А MoonShiner, писал, что рад, что его записали в один ряд с ... - немножко больше аккуратности и терпения и ты оправдаешь этот статус. 2 MozgC: нет, не косяк, просто видимо Moonshiner немножко промахнулся с входом в процедуру (попозже входит).
В заключение могу сказать, что вообще я догадывался об обоих осуществлённых способах взлома и маленькие лазейки были оставленны мной намеренно. Что касается метода Hex’а -просто я поторопился. Хотел сделать массивчик, который бы содержал N копий той переменной и чтоб он читался по таймеру и писался тоже, в общем путать исследователя.
А вот, как только я применю ...xor eax, КЛЮЧ... - все обломаются. Буду знать на будущее.
Кстати, уже начал работу не над BGProtect, а пока над BGPack 1.0. Так что, возможно через год ситуация поменяется. Когдя я хорошо разберусь в PE, архивировании, Debug API и подобном.
Всем спасибо за внимание !
|
MozgC | "А MoonShiner, писал, что рад, что его записали в один ряд с ... - немножко больше аккуратности и терпения и ты оправдаешь этот статус."
Вот это ты зря, я не думаю, что MoonShiner в этом списке рыжий. Во всяком случае не думаю, что он хуже чем тот же dragon, fess, perch в этом деле. Думаю даже наоборот, так как часто с ним общаюсь и представляю его общий уровень. А 1 крякмис не дает судить об уровне. |
MozgC | 2Bad_guy Будешь мне 5% прибыли отбашлять за придуманное название =) |
freeExec | Bad_guy пишет: А вот, как только я применю ...xor eax, КЛЮЧ... - все обломаются. Буду знать на будущее. UPX1:00449F6B xor eax, 96969696h тут что не ключ, а всякие крипторы не позволяют расшифровывать разными ключами, вот их самый минус |
MoonShiner | И вы туда же:) все мне за лень и раздолбайство втыки делают:) |
dragon | Короче так, MoonShiner, вот твой код - 44A668660D79FF3AAB0F
Кто-то там писал, что 10 раз перезагружался. Странно, я не разу, наверное у тебя там Windows не NT-шный стоит. Ставь XP и не будешь перезагружаться.
xor eax, КЛЮЧ - какая разница? Если адрес правильный, то и ключ будет правильный, если его дополнительно в код не вделать. Но тогда он будет всё время одинаковый, хотя подобрать его будет нелегко.
И ещё, может хватит наконец разбираться, кто хуже ломает, а кто лучше? Все хорошо ломают! |
Bad_guy | 2 MozgC: Хорошо хоть не 50% К тому же я не собираюсь релиз сей проги на CRACKL@B’e устраивать - кому нужен пакер от крэкера Bad_guy’я ?. Им подавай Stefan Fleischmann, А.С.,... Так что и имя будет другое и название.
На тему xor eax, ключ: это тоже условно говоря - я же говорил про DES, RC5. А прятать буду не адрес процедуры в регистрационный ключ, а пароль зашифрованного участка - вот и всё. Ну, действительно, пароль этот будет единственный, но ведь для того, чтобы его найти понадобится либо умный брутфорс, либо купить программу. А если в каждой версии программы этот пароль будет меняться и если прогу выпускать по законам shareware (не менее 1 новой версии в месяц) - о чем тогда говорить ?
Про Moonshiner’a: люблю делать выводы, хотя, наверное, и не имею на это права.
А вообще, такая защита, которая была мной тут осуществлена обломает 90% крэкеров: вы же забываете, что Hex и dragon и MoonShiner - их единицы, а Bad_guy’ев и MozgC’ов много. Так что реальную прогу с такой защитой сломают где-то не менее, чем через полгода после релиза (если не кричать, что защита в ней навороченная и вообще не говорить про защиту). |
Bad_guy | А вот ваша любимая процедура как сначала в Delphi выглядела:
procedure Reg; var il2: longint; begin asm push eax push edx push ecx mov edx, 10 mov eax,ilong // это для Hex’а mov il2,eax add il2,40 @im: mov ecx, [il2] mov eax, [ecx] xor eax, $96969696 mov [ecx], eax add il2, 4 dec edx jnz @im pop ecx pop edx pop eax end; form1.Status.Color := clGreen; form1.Status.Caption := cr(82)+cr(69)+cr(71)+cr(73)+cr(83)+cr(84)+cr(69)+ cr(82)+cr(69)+cr(68); end; |
В Общем, все из проделанных способов взлома были возможны либо по моей оплошности и недоделке (в случае метода Hex'a) , либо исходя из оставленной лазейки (самомодифицирующийся код был слабо зашифрован), а также, в основном из-за того, что я давал достаточно конкретные намёки на то, как сделана защита.
В принципе, даже использование регистрационного кода в качестве адреса не даёт большой гарантии стойкости защиты. Поэтому вижу только один весьма надёжный трюк - зашифровать самомодифицирующийся код, доступный только в зарегистрированном варианте программы, используя надёжные криптографические алгоритмы, такие как: RC6, DES, Blowfish. Таким образом можно свести вероятность взлома программы практически к нулю. Хотя, лично я думаю, что нет надобности в такой стойкости защиты какой бы то ни было программы.
Пока я писал эту статью я понял, что почти не существует таких программистов, которые справятся с созданием такой защиты... так что, по-видимому это "академичная" защита, которую в реальности делать никто не станет.
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy
Статья создана: 26.07.03
Ещё одна оригинальная статья от меня ждёт своих читателей, но на этот раз это будет не о крэкерстве, а о высокоуровневом языке программирования Delphi. Давайте рассмотрим генератор случайных чисел, который частенько мельком называют генератором псевдослучайных чисел, не поясняя всей глубокой сути этой приставки "псевдо". На самом же деле, когда речь заходит о компьютерах, процессорах и вычислительных системах о "случайности" можно забыть, потому как все процессы происходящие в компьютере являются результатом строгих математико-логических операций, происходющих в процессоре и других вспомогательных микросхемах компьютера (контроллер прерываний, таймер, сопроцессор,...).
Есть в Delphi две интересные функции: Randomize и Random, а также переменная RandSeed. Надеюсь, что вы знаете об их использовании. Но, наверняка, редко используете переменную RandSeed (dword), а вот с ней то я и захотел разобраться, а также решил поделиться своим опытом с вами.
Поскольку я всё-таки крэкер, давайте пойдём крэкерским путём - возьмём готовую программу и поглядим как она работает - я взял "Генератор случайных паролей", написанный Цованяном Романом Сейрановичем. Но сначала я посмотрел как же Randomize рандомайзит, на основе чего ? Оказывается, на основе GetSystemTime, которая возвращает текущую дату и точное время (с миллисекундами) но не у нас, а по Гринвичу, для меня это было - на 4 часа меньше, чем на часах. Затем я поглядел алгоритм функции Randomize - он выглядит в Delphi5 следующим образом:
var St: systemtime;
GetSystemTime(St);
RandSeed := ((St.wHour*$3c + St.wMinute)*$3c + St.wSecond)*$3e8+St.wMilliseconds;
Как видите, всё очень просто. А сама функция Random уже использует только переменную RandSeed, берёт на основе неё случайное число, а потом меняет RandSeed, причём строго математически, то есть если при каждом запуске программы заносить в RandSeed одинаковую переменную, то набор "случайных" чисел, полученных с помощью Random при том же диапазоне будет такой же.
Я решил провести небольшой опыт по взлому пароля, сгенерированного с помощью программы "Генератор случайных паролей". Запустил программу, взял длинный не взламываемый перебором пароль и запаковал с этим паролем в ZIP архив какой-то файл. На следующий день я "захотел" взломать этот архив и сделал следующим образом - посмотрел время создания архива и понял, что пароль был сгенерирован где-то в течение 2-3 минут до создания архива, и написал я небольшую программку, которая эмулировала Randomize, но я использовал не GetSystemTime, чтобы заполнить структуру St: Systemtime, а сам заполянял её с шагом одна миллисекунда и начиная от 3 минут до создания архива, не забывая также, что час взят по Гринвичу. Кроме того, я подглядел алгоритм создания пароля в программе "Генератор случайных паролей". То есть, я создал лист паролей. Для каждой миллисекунды я сделал не один пароль, а несколько (я "забыл" длину пароля, но помнил, что она где-то от 4 до 16 символов). То есть у меня получился внушительный лист паролей на почти 30 мегабайт. Затем я взял программку Advanced ZIP Password Recovery и поручил ей мой запароленный архив и дал в помощь свой 30 мегабайтный "словарик", через 3 секунды пароль был найден, надо же...
Теперь давайте прикинем: если мы не знаем время генерации ключа, но знаем, что некто любит генерировать "трудновзламываемые" пароли с помощью "Генератора случайных паролей", то что мы будем делать ? Теперь посчитаем сколько миллисекунд в сутках 1000*60*60*24 = 86'400'000. Допустим, что пароль длинной от 4 до 20 символов, то есть каждую миллисекунду мы получим по 17 паролей, значит за сутки у нас будет 86400000*17 = 1'468'800'000 - всего то полтора миллиарда паролей. А программка Advanced ZIP Password Recovery перебирает, на моём не слишком крутом компьютере, по 520000 паролей в секунду. Значит любой пароль, сгенерированный в любой день, в любое время с помощью программы "Генератор случайных паролей" будет найден за 1468800000/520000 = 2824 секунды, то есть примерно за 50 минут. Единственной проблемой является, то что Advanced ZIP Password Recovery не поддерживает внешний плагин, который бы "давал" пароли для перебора, поэтому придётся создавать гигабайтные словари паролей, что не очень удобно, но весьма реально.
Таким образом создавать "Генератор случайных паролей" на основе стандартных функций Delphi весьма глупо. "А как тогда не глупо ?" - спросите вы. Вообще, сейчас серьёзные организации пароли любят генерировать на основе белого шума. Нам же до этого шума далеко - брать нам его негде. А вот пользователя, сидящего за компьютером мы вполне можем использовать, а именно его замечательный человеческий фактор - аналоговую случайную функцию: запустим программу и заметим время, а потом, когда пользователь нажмёт "Генерировать пароль" - заметим время ещё раз - вот и одна случайность, можно также "последить" за траекторией мыши - вот вам вторая случайность. Теперь ещё можно поиcпользовать всякие хитрые функции GetDiskFreeSpace, также можно использовать хэш функции для замедления процесса создания листа паролей, то есть если ваша функция Randomize будет работать хотя бы 100 миллисекунд - уже потребуется 100 суток, чтобы создать весь лист паролей. Но тут ведь ещё одна проблема RandSeed - dword, то есть 32 бита, а это 2^32 = 4294967296. Поделим ка мы его на количество миллисекунд в сутках 4294967296/86'400'000 = 50, то есть потребуется 50*50 = 2500 минут в нашем случае, чтобы найти пароль от любого RandSeed, значит надо брать в качестве RandSeed переменную длинее 32 бит, мне приходит на ум лишь Int64 - вот тогда ваш пароль уже никто не взломает за разумное время.
Вы скажете: что за фигня - зачем крэкеру это знать ? Может, и не надо, но по-моему уважающему себя крэкеру, а также "продвинутому" программисту полезно знать о вот таком нестандартном подходе к обыденным вещам, понять суть происходящего, познать основы криптоанализа и глубину возможностей крэкерства и недостатков высокоуровневого программирования, а не только снимать аспр, да и то через раз...
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Перейти на главную страницу, индексную страницу, гостевую страницу.
Автор: MozgC <MozgCnoSpam@avtograd.ru>
Данный материал публикуется только для ознакомления читателя с основами отладки, и автор не несет никакой ответственности за его применение в корыстных целях.
ЦЕЛЬ : BlueFace (Final Release)
Сложность : Легко, для новичков
Инструменты :
SoftIce 4.05 для Win9x. или
SoftIce 4.05 для Windows XP. или
SoftIce выдранный из Driver Studio 2.7 для Windows XP/2000
(Для пользователей WinXP рекомендую SoftIce из DS 2.7)
W32Dasm
И еще раз всем привет! На этот раз будем исследовать "сложнейший" алгоритм генерации кода в уже знакомой нам программе BlueFace. Вам ОБЯЗАТЕЛЬНО надо прочитать мою первую статью, где я описывал, как просто узнать правильный код для регистрации программы. Там я также давал некоторые необходимые основы для новичков, приводил ссылки на статьи/учебники по ассемблеру и т.д. Вообщем, если вы собрались читать эту статью, не читая первой, и тем более у вас совсем нет опыта в исследовании програм, то я даже не советую, а командую вам прочитать мою первую статью по исследованию данной программы. Статья находится тут ! Почему я решил написать это дополнение к статье? Ну вообще на почту пришло около 20 писем, с комментариями и отзывами о статье, среди которых были просьбы написать продолжение, где описать процедуру генерации кода и также написание своего генератора правильных кодов (такие генераторы попросту называют кейгены). Почти все отзывы были очень положительные, спасибо всем, кто черкнул мне хотя бы пару строк - было приятно читать. Этой статьей надеюсь не разочаровать вас и постараюсь, как и в первой статье, написать и разжевать так, чтобы было понятно АБСОЛЮТНО всем. Кстати, пока писал, только что вспомнил, что если вы уже зарегестрировали программу BlueFace, пользуясь инструкциями из первой статьи, то, чтобы программа была снова незарегестрированной (а нам этой понадобится для дальнейших исследований), просто переустановите программу, с заменой всех файлов. Вы уже знакомы с моими длинными и нудными введениями =) Что ж, давайте начнем, ближе к делу.
Как я уже говорил в первой статье, очень часто бывает так, что код или серийный номер не всегда постоянны, а зависят от каких либо параметров, т.е. генерируются в зависимости от этих параметров. Как узнать? Ну во-первых, это видно при осмотре программы в отладчике, - это придет с опытом, но в основном почти всегда это можно понять и без осмотра. Вот как можно ориентироваться :
1) Для регистрации вас просят ввести ваше имя, возможно еще какую-то информацию, и регистрационный код.
2) В окне регистрации программа выводит что-то похожее на имя компьютера, или просто набор символов или ваше имя (ну не просто же так она их выводит). В общем случае программа выводит серийный номер и даже пишет, что это серийный номер.
3) В случае пункта 1 или 2 программа возможно просит отослать эту информацию (ваше имя, или серийный номер и т.д.) авторам вместе с деньгами, после чего вам вышлют регистрационный код =)
4) После переустановки, либо при установке на другом компьютере программа пишет другой серийный номер, либо регистрационный код, который работал на одном компьютере - не работает на другом (ну или соотвественно код, который работал сначала - не подходит после переустановки).
Вот это основные случаи. Это конечно не обязательно значит, что код не постоянен, а генерируется, но все-таки дает очень большую вероятность =) Откройте теперь окно регистрации программы (из первой статьи вы должны знать как это сделать, а я специально ничего не повторяю, чтобы точно знать, что вы прочитали первую статью =) и попытайтесь определить под какой пункт попадает наш случай !? Рад за тех, кто догадался, а для тех кто в танке объясню : видите там в поле serial number идет набор символов, так вот serial number - это серийный номер =). Теперь смотрим на пункт 2 - подходит ? Подходит! Также при более тесных экспериментах над программой вы сразу заметите, что на других компьютерах, а также после простой переустановки программы, в окне serial number уже другой серийный номер, и, соотвественно, старый код не подходит. Смотрим пункт 4. Подходит? Подходит ! Совпало 2 пункта из 4. Это говорит о большой вероятности того, что программа использует набор символов в окне serial number для генерации по нему правильного кода и потом сверяет этот сгенерированный код с введенным нами. В первой статье мы нашли то место, где происходит сравнение сгенерированного кода с введенным нами и просто подсмотрели код. В общеобразовательных целях, чтобы набраться опыта, а также чтобы например не смотреть код каждый раз с помощью отладчика, давайте разберем алгоритм генерации регистрационного кода и напишем кейген. Кейген будем писать на Delphi, т.к. я считаю, что Delphi - наиболее распространенный язык программирования среди начинающих и среди программистов среднего уровня. Тем, у кого Delphi не установлен, кто не собирается его устанавливать, кто не умеет программировать на Pascale/Delphi и т.д. предлагаю просто дочитать статью до конца с целью приобретения начального опыта, который пригодится в будущем. Иначе, какого фига, извините, вы вообще начали статью читать ? =)
Итак, разобрались с тем, что наша подопытная программа использует строку в поле Serial Number для генерации регистрационного кода. В принципе нам даже не надо знать, откуда она берет эту строку, но я об этом упомяну. Теперь давайте перейдем к практике.
Давайте вспомним, где вообще находится процедура генерации регистрационного кода и проверки его с тем кодом, который вводим мы. Из первой части вы, возможно, помните (ну если не помните - ничего страшного, или можете вкратце просмотреть еще раз первую статью), что по адресу 407279 вызывалась эта самая процедура генерации/проверки. Давайте посмотрим. Загрузите в дизассемблере (лучше в уже знакомом W32Dasm) исследуемую программу BlueFace. По адресу 407279 происходит вызов процедуры генерации/проверки кода:
:00407279 E8621D0000 call 00408FE0
Как видно из этой строчки, процедура находится по адресу 408FE0. В принципе, листинг этой процедуры я приводил в первой статье. Но для удобства приведу его еще раз :
:00408FE0 6AFF push FFFFFFFF
:00408FE2 6883FA4000 push 0040FA83
:00408FE7 64A100000000 mov eax, dword ptr fs:[00000000]
:00408FED 50 push eax
:00408FEE 64892500000000 mov dword ptr fs:[00000000], esp
:00408FF5 81EC08010000 sub esp, 00000108
:00408FFB 56 push esi
:00408FFC 8B84241C010000 mov eax, dword ptr [esp+0000011C]
:00409003 C784241401000000000000 mov dword ptr [esp+00000114], 00000000
:0040900E 50 push eax
* Reference To: MSVCRT.atol, Ord:023Eh
|
:0040900F FF1504144100 Call dword ptr [00411404]
:00409015 83C404 add esp, 00000004
:00409018 8D4C2408 lea ecx, dword ptr [esp+08]
:0040901C 8D54240C lea edx, dword ptr [esp+0C]
:00409020 8BF0 mov esi, eax
:00409022 51 push ecx
:00409023 52 push edx
:00409024 C744241000010000 mov [esp+10], 00000100
* Reference To: KERNEL32.GetComputerNameA, Ord:00CEh
|
:0040902C FF1568104100 Call dword ptr [00411068]
:00409032 8D44240C lea eax, dword ptr [esp+0C]
:00409036 8D4C2404 lea ecx, dword ptr [esp+04]
:0040903A 50 push eax
* Reference To: MFC42.MFC42:NoName0040, Ord:0219h
|
:0040903B E818510000 Call 0040E158
:00409040 8B4C2404 mov ecx, dword ptr [esp+04]
:00409044 8B15AC704100 mov edx, dword ptr [004170AC]
:0040904A C684241401000000 mov byte ptr [esp+00000114], 00
:00409052 8B41F8 mov eax, dword ptr [ecx-08]
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01]
:00409059 40 inc eax
:0040905A 0FAFC8 imul ecx, eax
:0040905D 3BF1 cmp esi, ecx
:0040905F 5E pop esi
:00409060 8D4C2400 lea ecx, dword ptr [esp]
:00409064 7536 jne 0040909C
* Reference To: MFC42.MFC42:NoName0024, Ord:0320h
|
:00409066 E893500000 Call 0040E0FE
:0040906B 8D8C2418010000 lea ecx, dword ptr [esp+00000118]
:00409072 C7842410010000FFFFFFFF mov dword ptr [esp+00000110], FFFFFFFF
* Reference To: MFC42.MFC42:NoName0024, Ord:0320h
|
:0040907D E87C500000 Call 0040E0FE
:00409082 B801000000 mov eax, 00000001
:00409087 8B8C2408010000 mov ecx, dword ptr [esp+00000108]
:0040908E 64890D00000000 mov dword ptr fs:[00000000], ecx
:00409095 81C414010000 add esp, 00000114
:0040909B C3 ret
Давайте пойдем с конца, я думаю так будет легче, потому что будем смотреть только на интересующие нас строки, чтобы не забивать мозги лишними командами. Я как всегда стараюсь вас успокоить, - по себе знаю, что когда новички видят такой большой код, просто могут даже бросить читать статью. Еще раз говорю : 3/4 этого кода нас не интересуют ! Будем разбирать только ключевые строки/команды. Итак, начинаем с конца. Как вы должны помнить из первой статьи, в строке:
:0040905D 3BF1 cmp esi, ecx
сверяется введенный нами код, который содержится в esi, с правильным кодом, который содержится в ecx. Значит код генерируется и по ходу генерации (если это можно назвать генерацией, потом смеяться будете) заносится в ecx. Посмотрим, что делается с ecx до этого сравнения.
:00409052 8B41F8 mov eax, dword ptr [ecx-08] ; В eax помещается значение
(dword - двойное слово = 4 байта), которое хранится по адресу ecx-8
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01] ; эту строчку объясню
отдельно
:00409059 40 inc eax ; eax увеличивается на 1
:0040905A 0FAFC8 imul ecx, eax ; Значение ecx умножается на eax и
результат помещается в ecx
Сначала объясню про команду lea. С ее помощью в регистр загружается так называемый эффективный адрес (смещение). Например если нам надо засунуть в ecx смещение массива mas для последующей работы с ним, то нужно написать так: lea ecx, mas. Это для общего развития. Более подробную информацию можете посмотреть в справочниках и учебниках по ассемблеру (ссылку на рассылку Калашникова я давал вначале первой статьи). Иногда (редко, но в нашем случае это так) с помощью команды lea в регистр просто помещается значение других регистров. Например команда lea eax, dword ptr [ebx+ecx] аналогична команде mov eax, ebx+ecx . Запомните это. Тогда такая форма записи не будет в будущем вводить вас в смущение. В общем случае lea что-то, dword ptr [что-то другое] помещает что-то другое в что-то =), т.е. приравнивает их значения. Надеюсь я вас не запутал. Вернемся к нашему примеру. После всего вышесказанного понятно, что lea ecx, dword ptr [edx+eax+01] помещает edx+eax+01 в ecx, т.е. после выполнения команды ecx = edx+eax+1 . Осталось разобраться, что у нас в eax и в edx. Начнем с edx. Для этого надо встать в отладчике на одну из вышеприведенных четырех команд. Для примера возьмем нашу любимую строчку
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01]
Вообще, прочитав мою первую статью, вы уже должны знать, как это сделать. Но для танкистов вкратце объясню. Открываем окно отладчика (CTRL+D), и теперь нам надо сделать нашу подопытную программу BlueFace текущим процессом, чтобы можно было устанавливать брейкпоинты на любые адреса программы. Для этого в отладчике пишем "addr blueface" (без кавычек) и жмем Enter. (Кстати, каждый раз, когда вы будете выходить из отладчика, а потом опять захотите поставить брейкпоинт на другой адрес, необходимо будет перед установкой брейкпоинта опять выделить процесс с помощью команды "addr blueface" и после этого ставить брейкпоинт. И еще не забывайте удалять уже ненужные брейкпоинты с помощью команды "bc *" - удалить все установленные брейкпоинты). Теперь, можно ставить брейкпоинт на адрес 409055 (это адрес команды lea ecx, dword ptr [edx+eax+01]), пишем "bpx 409055" и опять жмем Enter. Нажимаем F5 для продолжения. Теперь заходим в окно регистрации программы и пишем там любой код (я обычно пишу 1234321), после чего нажимам ОК. Срабатывает брейкпоинт по адресу 409055 и мы находимся на строке
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01]
Вспоминаем, что мы хотели. А хотели мы посмотреть, что хранится в edx. Пишем в отладчике "? edx" и как всегда жмем Enter. Самые внимательные возможно заметят, что они уже где-то видели это значение (смотрите в десятичной записи числа). Для остальных подскажу, что это последняя часть строки, записанной в поле serial number в окне регистрации. Кстати строка Serial number будет у всех выглядеть по разному. Также в ней может быть одно или несколько тире. Значит в edx записывается эта последняя часть строки. В принципе нам неважно знать откуда она берется или генерируется. Ведь для генерирования правильного кода, мы будем просто брать эту часть и все. Осталось узнать, что у нас в eax и подвести итоги!
Те из вас, кто в крэкинге не полные новички, возможно уже про себя подумали, почему это я ничего не говорю про вызов функции GetComputerNameA по адресу 40902C. Ладно, так и быть, расскажу =) Функция GetComputerName - принимает входными значениями адрес строки, в которую поместится имя компьютера и адрес, по которому находится значение максимальной длины строки - имени компьютера. После выполнения функции, в соответствующие адреса кладется имя компьютера и длина имени клмпьютера (эта длина кладется по адресу, в котором раньше указывалась максимальная длина строки - имени компьютера). Как вы должны знать из первой статьи, входные параметры передаются функциям для последующей работы с ними через стек. Смотрим :
:00409022 51 push ecx ; Кладем в стек адрес, по которому хранится значение
максимально допустимой длины строки, отведенной для сохранения в ней имени компьютера
:00409023 52 push edx ; Кладем в стек адрес, по которому сохранится имя
компьютера
:00409024 C744241000010000 mov [esp+10], 00000100 ; записываем, что макс.
длина имени компьютера может быть равна 100h в шестнадцатеричном (или 256 в десятичном)
исчислении
* Reference To: KERNEL32.GetComputerNameA, Ord:00CEh
|
:0040902C FF1568104100 Call dword ptr [00411068] ; Вызывается
функция GetComputerName
Теперь, если вы посмотрите память по соотвествующим адресам (которые сохранялись в стек перед вызовом функции) в отладчике (извиняюсь, но вы уже должны уметь это делать, я не могу объяснять одно и то же по 10 раз), то увидите, что в них сохранились длина имени компьютера и само имя компьютера (так и быть, скажу, что чтобы посмотреть это, вам сначала надо было записать адреса, хранящиеся в ecx и edx, когда они помещались в стек. И потом после выполнения функции GetComputerNameA в отладчике написать команду "dd XXXXXXXX", где XXXXXXXX - соотвествующий адрес, после чего выведется область памяти, начиная с указанного адреса). Посмотрите внимательно на имя компьютера! (Для этого наберите "dd XXXXXXXX", ХХХХХХХХ - адрес который был в edx при сохранении в стек, т.е. выолнении команды push edx. И посмотрите справа от выведенной области памяти) Ничего не напоминает? Да, да, да, это первая часть поля serial number в окне регистрации. Значит в поле serial number записывается имя компьютера, потом ставится тире, и потом тот номер, который мы до этого видели в edx, помните? Ладно, смотрим дальше и видим, что вызывается еще какая-то функция:
:0040903A 50 push eax ; Помещается в стек параметр, передаваемый
функции
* Reference To: MFC42.MFC42:NoName0040, Ord:0219h
|
:0040903B E818510000 Call 0040E158 ; Ну и вызывается сама функция
Сейчас надо будет узнать, что же это за функция, и что ей передается. В отладчике посмотрите, что хранится по адресу eax (этот адрес передается функции). Для этого вам надо каким-либо образом (еще раз повторяю, вы это уже должны знать, а если не поняли - советую заново перечитать первую статью) попасть в отладчике на адрес 40903A, набрать "dd eax", и нажать Enter. "dd eax" - команда отладчику вывести на экран кусок памяти начиная с адреса, который хранится в eax. Вы увидите (справа, где показывается этот кусок памяти, в виде ASCII-символов), что по этому адресу хранится имя вашего компьютера, которое получили с помощью функции GetComputerNameA. Значит имя компьютера передается функции. Зачем? Давайте посмотрим. Для этого в отладчике, когда дойдете до команды вызова функции (call 0040E158), нажмите F8 для входа внутрь этой функции. На экране появится куча команд JMP на различные адреса, и вы тоже окажетесь на одной из таких команд. На всякий случай упомяну (вообще-то я просил вас уже иметь начальные минимальные знания ассемблера), что команда JMP XXXXXXXX делает переход на адрес XXXXXXXXX, т.е. следующая команда, которая будет выполняться, будет по адресу XXXXXXXX. Нажимаем F8 или F10 и попадаем в некую процедуру, смотрим ниже и видим:
CALL [Kernel32!lstrlen]
Это означает, что вызывается функция lstrlen из библиотеки kernel32. Функция lstrlen предназначена для измерения длины строки, которая передается этой функции. А адрес какой строки перед этим помещался в стек? Адрес строки, содержащей имя компьютера! Значит эта процедура, в которую мы зашли, находит длину имени компьютера! Кстати, давайте сосчитаем длину имени компьютера. Она у всех может быть разной, как и имя компьютера. У меня получилось 15 символов (в шестнадцатеричной форме = 0F). Сосчитали? Хорошо, значит тут зачем-то вычисляется длина имени компьютера. Ок, идем дальше. Давайте все же посмотрим, что у нас в eax. Нам ведь это нужно знать, чтобы понять алгоритм генерации регистрационного кода!? Поставим брейкпоинт на адрес 409055 ("bpx 409055"), чтобы прерваться на уже знакомой нами строке
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01]
Почему именно на этой строке? Да потому что перед этой командой (смотрите листинг процедуры вначале) в eax помещается какое-то значение, вот мы прервемся и посмотрим, что поместилось в eax. После того, как вы попали на эту строчку в отладчике наберите "? eax" и жмите Enter (о том, что надо жать Enter после всех команд отладчику, я больше не буду упоминать). Что мы увидели ? Лично я увидел вот что (у вас скорее всего будет другое значение, но это не важно, вы поймете) :
:? eax 0000000F 0000000015
Ничего не напоминает? Самые сообразительные, я уверен, догадались, что это длина имени компьютера! Теперь когда мы знаем все, что нам необходимо, давайте подведем итоги и определимся с алгоритмом генерации регистрационного кода. Смотрим еще раз вот этот участок программы:
:00409052 8B41F8 mov eax, dword ptr [ecx-08] ; В eax, как мы только что
узнали, помещается длина имени компьютера
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01] ; В ecx помещается
сумма - число, хранящееся в edx (edx = последняя часть в поле serial number, после последнего
тире, или просто после тире, если у вас только одно тире в Serial number =) + длина имени
компьютера + 1
:00409059 40 inc eax ; eax (длина имени компьютера) увеличивается на 1
:0040905A 0FAFC8 imul ecx, eax ; Полученная перед этим сумма умножается
на eax (т.е. на длину имени компьютера + 1) и результат помещается в ecx
:0040905D 3BF1 cmp esi, ecx ; Сравнивается введенный нами код (в esi)
с только что сгенерированным правильным кодом (в ecx)
Итак, подводим итоги! Правильный регистрационный код генерируется по такому алгоритму:
1) Из поля serial number в регистрационном окне берется число - последняя часть строки, после второго тире.
2) К этому числу прибавляется длина имени компьютера + 1 (имя компьютера записано в первой части поля serial number, до второго тире)
3) Полученное число умножается на длину имени компьютера + 1.
Все! Вот и весь алгоритм! Можете вручную проверить! Для тех, кто не дай бог не понял, приведу пример, как это было в моем случае. В поле serial number у меня была строка:
VAZ-DN7WUNSYNWE-31586016
Первая часть "VAZ-DN7WUNSYNWE" - это имя компьютера, ее длина 15. Вторая часть "31586016". К 31586016 прибавляем 15 и еще 1, получаем 31586032. Теперь это число умножаем на (15+1), получаем 505376512 - это и есть правильный регистрационный код в моем случае! У вас он естественно будет другим (как я уже говорил, имя компьютера как и вся строка serial number, у вас будет другим. Например, у вас может быть такой серийный номер - "SuperHacker-1366613"). Ну и как? Сложно? Приступим к написанию кейгена!
Ну Delphi я вас не собираюсь учить, только вкратце скажу, что надо сделать, с небольшими комментариями. Запускам Delphi, создаем новый проект, кладем на форму компонеты Edit, Label и Button. Очищаем свойства text компонента Edit и caption компонента Label. Два раза кликаем по созданной нами кнопке и попадаем в пустую пока процедуру, которая будет выполняться при нажатии этой кнопки. Вот как должна выглядеть эта процедура в готовом варианте:
procedure TForm1.Button1Click(Sender: TObject);
var
ComputerName, chislo : string; ; инициализация
переменных
i,j : integer;
regnumber : longint;
begin
i:=length(Edit1.Text);
while Edit1.Text[i]<>'-' do i:=i-1; ; Цикл c конца
строки, пока не наткнемся на тире
j:=i; ; Cохраняем номер символа-тире в строке в переменной j
для последующих действий
ComputerName:=copy(Edit1.Text,1,j-1); ; Копируем в
переменную ComputerName часть
строки, содержащейся в Edit1.Text, начиная с первого символа и до тире
(j - позиция тире в строке)
chislo:=copy(Edit1.Text,j+1,length(Edit1.Text)-j); ;
Аналогично, копируем в переменную
chislo часть строки, содержащейся в Edit1.Text, начиная со следующего после тире
символа (его номер - j+1). Кол-во копируемых символов задается выражением
length(Edit1.Text)-j - так мы получим длину второй части серийного номера
regnumber:=(StrToInt(chislo)+ ; Вычисляем регистрационный
код по известному алгоритму
length(ComputerName)+1)*
(length(ComputerName)+1);
Label1.Caption:=IntToStr(regnumber); ; Регистрационный код
выводится на экран с помощью
компонента Label
end; ; Конец процедуры
Теперь компилируйте этот проект, вводите serial number в Edit, нажимайте на кнопку и получайте свой регистрационный код! Можете по своему усмотрению оформить все красиво, моя задача была просто вкратце объяснить вам, как написать кейген, если известен алгоритм его генерации. Те, кто умеет хоть чуть-чуть программировать на Delphi, поймут все с легкостью. На всякий случай упомяну, что функция StrToInt преобразовывает строку в число, а функция IntToStr, наоборот, преобразовывает число в строку.
Ну, надеюсь, со своей задачей я справился! Если вы так не считаете - шлите мне свои комментарии (email вверху и внизу страницы) - я все учту в будущих статьях.
В своих первых двух статьях я попытался разжевать процесс исследования, регистрации, написания кейгена до того, чтобы было понятно каждое слово, чтобы новичок, который первый раз садится за работу с отладчиком, приобрел основы этого дела, и чтобы у него не осталось никаких вопросов. Этими статьями я хотел дать вам резкий толчок вперед, потому что по себе знаю, сколько времени может быть потрачено впустую, читая непонятные статьи, проводя дни в поисках необходимой информации и т.д., по себе знаю как все сначала кажется непонятным и трудным. Надеюсь мои статью дали вам такой толчок. Если нет - извините, сильнее разжевать уже нельзя, в этом случае читайте дополнительную литературу для приобретения необходимых основ. Я планирую продолжать писать статьи по крэкингу, постепенно увеличивая уровень сложности - нельзя стоять на месте. Поэтому настоятельно вам рекомендую разобраться со всеми возможно оставшимися непонятными моментами, так как если вы что-то не поняли сейчас - в следующих статьях будет труднее.
Как и в первой статье, выражаю благодарность freeExec'у и MoonShiner'у - они действительно уделяют мне много времени - всегда помогают и объясняют, когда мне что-то непонятно. Также спасибо тем, кто тестировал, комментировал и помогал что-то подправить в этой статье перед тем как она вышла, и всем тем, кто присылал мне комментарии и отзывы по почте.
Отзывы и комментарии уже по этой статье тоже можете послать на MozgCnoSpam@avtograd.ru
Всем счастливо! MozgC (c) 2003
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: -=SouL=- <art_a@bk.ru>
Tools:
SoftIce - 4.05 и выше
KWdsm - v10
Любой Шестнадцетеричный редактор
Прога:
Персональный органайзер с привлекательным интерфейсом. В состав входит адресная книга, напоминатель, список задач, заметки и календарь событий. Без регистрации работает 30 days + дописывает "UNREGISTERED". Взять можна здесь
Начнем... Медсестра скальпель...
Зарегистрировать можна двумя способами:
:0047C93A 8D8D98FEFFFF lea ecx, dword ptr [ebp+FFFFFE98]
:0047C940 FF856CFEFFFF inc dword ptr [ebp+FFFFFE6C]
* Possible StringData Ref from Data Obj ->"C-Organizer Pro - Evaluation version "
->"[days left:"
:0047C946 B8BD706A00 mov eax, 006A70BD
Посмотрим чуть выше откуда она вызывается:
:0047C67D 59 pop ecx
:0047C67E 84C9 test cl, cl
:0047C680 0F84A9030000 je 0047CA2F //если зарегины то прыгаем
:0047C686 66C78560FEFFFF5003 mov word ptr [ebp+FFFFFE60], 0350
* Possible StringData Ref from Data Obj ->"\Software\Sup00f\ClassID"
:0047C68F BA88706A00 mov edx, 006A7088
И так вы видите все сами. Меняем je 0047CA2F на jmp 0047CA2F. Запускаем программу и вот те на сразу же закрылась. Я в этом месте маленька помучался, а потом вспомнил про ShowWindow. Ставим бряк: bpx ShowWindow и снова запускаем прогу. Прерываемся при вызове этоя функции. Трассируем до RET проходим его по F10 и попадаем вот сюда:
:005F701D 6683B8CA02000000 cmp word ptr [eax+000002CA], 0000
:005F7025 7410 je 005F7037
:005F7027 8BD8 mov ebx, eax
:005F7029 8BD0 mov edx, eax
:005F702B 8B83CC020000 mov eax, dword ptr [ebx+000002CC]
:005F7031 FF93C8020000 call dword ptr [ebx+000002C8]
:005F7037 5B pop ebx //мы здесь
:005F7038 C3 ret
По адрессу 005F701D проверка целостности файла. Меняем je 005F7037 на jmp 005F7037. Вот и все теперь можете делать с прогай что угодно - в рамках разумного!!! Все остальные ограничение убераются аналогично. Так что дерзайте.
А теперь Loader.
Можна было написать Loader на Pascale, но я воспользовался такой замечательной программой R!SC's Process Patcher v1.5.1. Создаем файл Loader_C-orgPro.rpp с таким содержимым:
;Loader_C-orgPro.rpp
O=Loader_C-orgPro.exe: ; loader to create
F=C-OrganizerPro.exe:
P=5f7025/74,10/eb,10: ;рубим проверку на целостность
P=47c680/0f,84,a9,03,00,00/e9,aa,03,00,00,00:
P=4588ad/74,3c/eb,3c:
P=4f19f7/74,7c/eb,7c:
$
Компилируем его программой Patcher v1.5.1. После кампилировки появится файл Loader_C-orgPro.exe, копируем его в директорию где установлена прога(нераспакованая), запускаем его и радуемся ЖИЗНИ!!!
P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!
-=SouL=-
art_a@bk.ru
http:/mobyle-hack.boom.ru
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: MozgC <MozgCnoSpam@avtograd.ru>
Данный материал публикуется только для ознакомления читателя с основами отладки, и автор не несет никакой ответственности за его применение в корыстных целях.
ЦЕЛЬ : BlueFace (Final Release)
Сложность : Легко, для новичков
Инструменты :
SoftIce 4.05 для Win9x. или
SoftIce 4.05 для Windows XP. или
SoftIce выдранный из Driver Studio 2.7 для Windows XP/2000
(Для пользователей WinXP рекомендую SoftIce из DS 2.7)
W32Dasm
Всем, привет! Это моя первая статья по исследованию программы с целью ее бесплатной регистрации. Т.е. конечно моей целью, да, думаю, и вашей не была именно регистрация, но я решил с помощью этого примера помочь вам в освоении основ исследования (взлома, настройки под себя - как хотите) программ, ну а ваша цель - получить хоть какой-то начальный опыт по этому делу. Статья рассчитана на людей, начиная с тех, кто буквально только-что скачал и установил себе отладчик, но не имеет опыта работы с ним в этой области, и заканчивая теми, кто может уже и взломал пару-тройку-пятерку программок, но не более. Хотя конечно эту статью могут прочитать и те, у кого чуть больше опыта. Однако опытным крэкерам я сразу предлагаю нажать крестик вверху, справа =) ибо им будет неинтересно. Нельзя сказать, что программа ломается очень-очень-очень легко. Скажем так... просто легко. Но я, во-первых, не захотел использовать для статьи специальные программки для взлома (crackme), а решил использовать НАСТОЯЩУЮ программу, которая требует 18$ за регистрацию ! Во-вторых, я постараюсь РАЗЖЕВАТЬ вам процесс исследования программы и нахождения правильного кода, так что думаю проблем возникнуть не должно.
Этой статьей я хотел исправить одну большую ошибку многих крэкеров, которые пишут аналогичные статьи. Они забывают, что пишут для начинающих, которые например представления не имеют как найти место в программе где происходит сравнение пароля и что потом делать. Получилось у меня или нет вы можете сказать мне, написав письмо на MozgCnoSpam@avtograd.ru . Кстати напомню, что необходимо, чтобы у вас было минимальное знание ассемблера. Ибо без этого ничего путного не получится, вы просто не разберетесь во всех этих командах. Я конечно в принципе могу прокомментировать каждую строчку приводимых здесь отрывков кода программы, но все равно научить ассемблеру я вас не смогу. Если знания ассемблера у вас на 0, то предлагаю скачать архив рассылки "Ассемблер? Это просто! Учимся программировать под MS-DOS", автор - Калашников Олег. Скачать архив можно здесь. Почитайте как минимум первые 9 выпусков. Там все написано просто и понятно. Еще могу посоветовать очень маленькую статейку Ассемблер для крэкеров . Она мне не очень нравится, но возможно там вы сможете хоть что-то узнать, если уровень вашего знания ассемблера никакой. Кстати предупрежу, что комментарии ассемблерных строк, а также большие пояснения в скобках, чтобы не запутаться, я буду выделять красным цветом. Статья рассчитана на просмотр в разрешении 1024x768. Ну ладно, хватит для начала, а то больно сильно отвлекся. Вам еще не надоела моя болтовня? Нет? Ну тогда читайте дальше!
Итак кроме отладчика (в списке инструментов я написал SoftIce, но в принципе это может быть любой отладчик, например OllyDbg, TRW2000 и т.д., главное, чтобы вы имели основы работы с ним. В статье я буду ориентироваться на то, что вы пользуетесь SoftIce) вам необходим дизассемблер W32Dasm (вообще-то он является еще и отладчиком, но как отладчик он мне не нравится, пользуюсь им только для дизассемблирования файлов), ссылку на который я дал в самом верху страницы. В принципе можно обойтись и без него, но с ним намного легче!
С чего начать? Есть много вариантов. В статьях обычно пишут так, как будто все получилось сразу легко и просто. На самом же деле так не бывает. Ну только если с самыми простыми программами. На деле перебираются все основные способы, пока какой-то способ не срабатывает. Скажу честно, что тот способ, который я вам сейчас буду рассказывать был в моем списке под номером 2. Сначала я попробовал немножко по-другому, но там было запутанно. И я решил попробовать этим способом. Через 2 минуты я уже увидел, что так легче, еще через минуту вкратце его проверил и через 5 минут, уже узнав настоящий пароль, решил написать данную статью. Ну я это к тому говорю, чтобы вы не отчаивались если у вас не будет получаться с первого раза. У нас тоже не с первого! Все методом перебора основных вариантов. Первый способ, который у меня не получился, я рассказывать не буду. Во всяком случае не в этой статье. Считайте, что мы его проделали, ничего не вышло и вы спрашиваете у меня другой способ =) У вас возникает возмущенный вопрос: "Как же мы научимся этому делу, если нам даже первый способ не рассказывают !?". Отвечу : Просто второй способ мой, который я вам щас и буду описывать зачастую более результативный. И пусть в вашем списке он будет под номером 1. Вот и все.
Этот другой способ состоит вот в чем : Зачастую текстовые строки, которые выводятся во время работы программы так и хранятся полностью внутри программы. Для того, чтобы например вывести табличку (маленькое окошко, обычно это стандартное окошко с кнопкой ОК, и называется оно MessageBox, вызывается с помощью функции MessageBoxA . Это я вам на будущее) с надписью, нам нужно сначала загрузить адрес этой надписи в стек. Стек - это специально отведенная область памяти для хранения промежуточных данных. Перед вызовом функции вывода окошка с каким-либо сообщением, в стек помещается адрес, по которому в памяти хранится это сообщение. Щас я вас наведу на мысль. Многие дизассемблеры (в том числе и наш W32Dasm) анализируют, и сразу показывают если происходит обращение к строке. Это сделано для того, чтобы облегчить нам поиск. Идем дальше. Например, когда мы вводим любой пароль (скорее всего неправильный =), то нам показывается окошко, в котором сообщается, что мы ввели неправильный пароль. Но как я уже сказал программа сначала загружает в стек адрес строки-сообщения о неправильном пароле. Если посмотреть этот участок кода в дизассемблере, то он нам покажет, что там-то там-то происходит обращение к строке такой-то, а потом вызывается функция, которая показывает на экране окошко с этим сообщением. Так вот когда мы нашли в дизассемблере это место (просто сделаем поиск отрывка из сообщения о выводе неправильного пароля) то рядом если прокрутить несколько экранов вверх или вниз мы обычно находим обращение к строке, в которой написано, что пароль правильный, или что мы зарегестрированы. В 80-90% РЯДОМ сверху от этого места есть проверка правильности пароля и потом происходит условный переход или на вывод окошка с сообщением о неправильном пароле, или, если сравнение прошло успешно, т.е если введенный пароль равен правильному паролю, переход на вывод окошка с сообщением о правильности введенной информации. И программа становится зарегестрирована. Наша цель - с помощью отладчика посмотреть правильный пароль во время сравнения его с введенным паролем. Вот и все! На этом теория заканчивается. Переходим к практике.
Устанавливаем и загружаем нашу программу - BlueFace. Внизу в system tray появится иконка программы. Кликаем правой кнопкой и выбираем Register BlueFace... -> Enter your code... Вводим любой пароль и нажимаем ОК. Видим сообщение "You entered invalid key code!" . Теперь нам надо найти, где в программе выводится это сообщение, ну а выше, скорее всего, будет процедура проверки кода. Помните я вам только что объяснял, что чтобы вывести окошко с сообщением надо сначала адрес этого сообщения поместить в стек ? Так вот мы щас в W32Dasm'е сделаем поиск например слова "invalid" (ну просто часть сообщения нашего, можно например ввести "entered") и попадем на место вывода сообщения о неправильном номере. Загружаем W32Dasm. Если вы первый раз сейчас решили воспользоваться W32Dasm'ом, то вам надо настроить шрифты. Для этого этого идем в меню Disassembler -> Font... -> Select Font и выбираем шрифт Courier, жирный, размер 8. Теперь делаем Disassembler -> Font... -> Save Default Font. Все, теперь со шрифтами все будет в порядке. Сейчас загружаем в W32Dasm'е нашу программу - BlueFace.exe . Видим на экране дизассемблированный вариант нашей программы. Т.е. программа строится из последовательных ассемблерных команд, которые мы сейчас и видим на экране. В меню Search выбираем Find text, вводим "invalid" и делаем поиск. Попадаем на строку
* Possible StringData Ref from Data Obj ->"You entered invalid key code!"
Т.е. нам дизассемблер говорит, что в следующей команде происходит обращение к строке "You entered invalid key code!". Смотрим следующую строку
:00407371 6814654100 push 00416514
:00407371 - это адрес по которому в памяти будет находиться данная команда.
6814654100 - это запись команды в шестнадцатеричном виде. (так будет выгляеть эта команда в exe файле, если просматривать его с помощью шестнадцатеричного редактора)
push 00416514 - это сама команда, которая помещает в стек число - адрес 00416514, по которому хранится наша строка.
Если подумать логически, то после этого должен идти вызов функции, которая выводит на экран наше сообщение. Просто так практически всегда : загружается адрес строки в стек и вызывается процедура вывода окошка. Это запомните. Как вызывается какая-либо функция ? Да с помощью команды call . Смотрим ниже и видим
:00407376 E8DD6D0000 Call 0040E158
Точно. Вызывается функция вывода на экран сообщения о неправильном коде. Откуда я узнал, что это именно эта функция ? Ну я же уже сказал, что это просто надо запомнить. Это стандарт. В 80% программ, в которых не реализовано ничего для затруднения нахождения правильного кода, это так. После загрузки адреса строки в стек, вызывется ф-ия вывода этой строки в окошке. Ну не может быть больше ничего другого. Так всегда. А 0040E158 это адрес этой функции в памяти. Но нам он не важен.
Теперь, как я говорил ранее, нам надо найти обращение к строке о правильном введенном номере или об успешной регистрации, что в принципе одно и то же. Т.е. нам надо найти строку, где бы было написано что-то о том, что код правильный или что регистрация успешна, или спасибо за регистрацию и т.д. Давайте пролистаем пару экранов вниз. Сначала делайте это, а потом продолжите читать дальше. Не надо волноваться =) Я знаю что там ничего нет. Давайте теперь возвратимся и пролистаем пару экранов вверх. Сделайте. Вы наверно сразу обратили внимание на строку:
* Possible StringData Ref from Data Obj ->"Thank you for registration!"
Это ничто иное как вывод строки о правильном пароле и успешной регистрации! Видите, следующей строкой идет call 0040E158. Эта та же функция вывода сообщения. (То что это таже фунция вывода сообщения на экран, что и была перед этим, можно понять из того, что эта функция вызывается и в прошлом рассмотренном нами отрывке и сейчас по одному и тому же адресу - 0040E158)
* Possible StringData Ref from Data Obj ->"Thank you for registration!"
|
:004072A6 6834654100 push 00416534 ; Кладем в стек адрес сообщения об успешной регистрации программы
* Reference To: MFC42.MFC42:NoName0040, Ord:0219h
|
:004072AB E8A86E0000 Call 0040E158 ; Вызывается функция, которая берет из стека адрес строки, потом берет саму строку из памяти по этому адресу и выводит ее в окошке на экран
Теперь, как я говорил в теоретической части статьи, выше должно быть сравнение двух строк и условный переход на один из любых адресов программы, где и будет либо выводиться сообщение о правильном коде, либо о неправильном. На всякий случай скажу, что условный переход - это переход, который зависит от какого-то условия. Т.е. от какого-то условия зависит выполнится ли этот переход, или нет. Это на будущее... Что нам теперь нужно знать. Команды сравнения - cmp и test . CMP <что-то>, <что-то> (например cmp eax, ebx - сравнивает регистры eax и ebx. Аналогично cmp eax, 30h - сравнивает регистр eax с шестандцатеричным числом 30h) устанавливает флаг нуля, если эти <что-то> равны. Т.е флаг нуля становится равным 1. Команда test ЧАЩЕ ВСЕГО используется для сравнения значения регистра с 0. Записывается так : test eax, eax . Тут может быть не eax а любой другой регистр, но чаще всего eax. Если eax равен 0, то устанавливается флаг нуля, т.е. как я уже сказал он становится равным 1.Флаг - это регистр, который может принимать значение либо 0, либо 1 (если флаг равен 1, то говорят что флаг установлен или выставлен). Флаг нуля например показывает результат предыдущего сравнения или некоторых других команд. Это я рассказал про команды, используемые для сравнения. Практически всегда после команды сравнения идет команда условного перехода, который осуществляется в зависимости от результата сравнения, ну и соотвественно в зависимости от значения флага. Основные команды условных переходов это jz, jnz, je, jne . Отмечу что команды jz и je - абсолютно одинаковые команды, соотвественно нет разницы между командами jnz и jne. Команда < jz (je) address > используется для осуществления перехода на адрес - address, если установлен флаг нуля, т.е. если перед этим либо команда cmp сравнила ОДИНАКОВЫЕ данные, либо eax при выполнении команды test eax, eax , был равен 0. Ну вы понимаете, что на самом деле вместо address в программе будет написан какой-то адрес =). Итак смотрим выше и ищем команды сравнения и условного перехода :
:00407279 E8621D0000 call 00408FE0 ; Вызываем процедуру проверки кода
:0040727E 83C404 add esp, 00000004
:00407281 85C0 test eax, eax ; Проверям, а не ноль ли в eax
:00407283 6A00 push 00000000
:00407285 0F84C8000000 je 00407353 ; Если 0, то переходим на место
:0040728B 8D4C2410 lea ecx, dword ptr [esp+10] ; вывода ссобщения о
:0040728F E89CB8FFFF call 00402B30 ; неправильном коде
:00407294 51 push ecx
:00407295 C784247801000000000000 mov dword ptr [esp+00000178], 00000000
:004072A0 8BCC mov ecx, esp
:004072A2 8964240C mov dword ptr [esp+0C], esp
* Possible StringData Ref from Data Obj ->"Thank you for registration!"
Видим это на экране и сразу замечаем строки c командами test и je. Важные строки я выделил жирным шрифтом. Хочу заметить, что как видите все просто. Нам не надо разбираться во всех этих ассемблерных командах. Просто если мы знаем, что делаем, то действуем по заранее продуманному плану, и все кажется довольно просто. Это я к тому, чтобы вы поняли и не пугались : вам не надо быть супер программистом на ассемблере, чтобы уметь взламывать программы. Основ вполне достаточно. А остальное придет с опытом исследования программ.
Теперь давайте разберемся с 3 выделенными командами. Начнем с команды test (это я так специально, чтобы вам понятнее было). Значит команда test eax, eax сравнивает eax с нулем. Если eax равен нулю, то устанавливается флаг нуля, и в этом случае сработает переход на адрес 00407353 с помощью команды je 00407353 ! Если eax не равен 0, то переход не сработает ! и мы попадем на команду lea ecx, dword ptr [esp+10] и пойдем дальше. (Когда в 5-ый раз перечитывал свою же статью решил на всякий случай еще раз пояснить, что команды je и jz выполняют переход на указанный после команды адрес, если флаг нуля выставлен. Если флаг нуля не выставлен, то переход не осуществляется и просто выполняется следующая после je (jz) команда. Аналогично команды jne и jnz выполняют переход наоборот только в том случае если флаг нуля НЕ выставлен (например если команда cmp сравнивала разные данные или при выполнении команды test eax,eax , eax не был равен 0) Посмотрим, что у нас по адресу 00407353:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407285(C)
|; Это действия, которые нас абсолютно не волнуют
:00407353 8D8C24C0000000 lea ecx, dword ptr [esp+000000C0]
:0040735A E8D1B7FFFF call 00402B30
:0040735F 51 push ecx
:00407360 C784247801000006000000 mov dword ptr [esp+00000178], 00000006
:0040736B 8BCC mov ecx, esp
:0040736D 8964240C mov dword ptr [esp+0C], esp
* Possible StringData Ref from Data Obj ->"You entered invalid key code!"
|
:00407371 6814654100 push 00416514 ; Помещаем адрес этой строки в стек
* Reference To: MFC42.MFC42:NoName0040, Ord:0219h
|
:00407376 E8DD6D0000 Call 0040E158 ; Выводим сообщение о неверном коде
Мы видим, что это знакомая нам процедура вывода на экран сообщения о неверном коде ! Самая верхняя строчка означает, что в эту процедуру можно попасть с помощью перехода с адреса 00407285. Там у нас как раз и есть наша команда перехода - je. Подведем итоги. Значит осуществляется переход на процедуру вывода сообщения о неправильном коде. В каком случае осуществляется этот переход? В случае если регистр eax = 0. Но причем тут eax и наш введенный код ? Просто обычно для проверки правильного регистрационного кода сначала вызывается процедура проверки этого кода, в которой в какой-нить регистр (это обычно eax) помещается 0 или 1 в зависимости от того правилен ли наш введенный код, или нет. После этой процедуры обычно идет команда test, которая и проверят регистр на ноль, а дальше идет условный переход. Запомните - это стандарт. И для начала вам хватит знания этого стандарта. Все это мы видим на нашем примере ! Давайте еще раз посмотрим на уже знакомый нам код:
:00407279 E8621D0000 call 00408FE0 ; Вызываем процедуру проверки кода
:0040727E 83C404 add esp, 00000004
:00407281 85C0 test eax, eax ; Проверям, а не ноль ли в eax
:00407283 6A00 push 00000000
:00407285 0F84C8000000 je 00407353 ; Если 0, то переходим на место
:0040728B 8D4C2410 lea ecx, dword ptr [esp+10] ; вывода ссобщения о
:0040728F E89CB8FFFF call 00402B30 ; неправильном коде
:00407294 51 push ecx
:00407295 C784247801000000000000 mov dword ptr [esp+00000178], 00000000
:004072A0 8BCC mov ecx, esp
:004072A2 8964240C mov dword ptr [esp+0C], esp
* Possible StringData Ref from Data Obj ->"Thank you for registration!"
Как я только что объяснил, перед командой test должен быть вызов процедуры сравнения кода. Я выделил его первой строчкой. Обычно внутри таких процедур происходят какие-то преобразования или генерация правильного кода (код генерируется или по введенному имени, или в нашем случае по серийному номеру (можете посмотреть в программе, где мы вводим код, есть поле Your serial number)). Вот по этому серийному номеру и генерируется код. Это тоже стандарт. Видите, нет ничего сложного, практически всегда все идет по стандарту. А если не идет, то просто применяются более сложные стандарты =)) Просто запомните, что если есть поле серийного номера, который тем более не вы вводите, то код будет генерироваться по этому серийному номеру. В конце процедуры обычно идет проверка введнного кода и сгенерированного правильного кода. Но процедуру генерации кода мы рассматривать не будем. Мы и так вон сколько разобрали, а то голова треснет! Если вам нравится моя статья и то, как я объясняю - не поленитесь напишите пару строчек мне на MozgCnoSpam@avtograd.ru . Там же можете попросить, чтобы я дополнил статью разбором процедуры генерации кода или может написал еще пару статей, или можете написать мне типа "Что за лажу ты, чувак, пишешь!", в общем любые комментарии. Опять отвлеклись. Вообщем что сейчас от нас требуется. Это поставить в отладчике брейкпоинт ( Брейкпоинт - это точка останвки программы, т.е. та точка, в которой программа прервет свое выполнение и мы попадем в окно отладчика. В софтайсе брейкпоинт ставится с помощью команды: bpx имя_функции . Где имя функции - это название функции, при выполнении которой программа остановится. Или же можно поставить брейкпоинт на адрес командой "bpx XXXXXXXX", где XXXXXXXX - это адрес, дойдя до которого программа прервется, и вылезет окно СофтАйса, в этот момент мы будем находиться как раз на адресе XXXXXXXX. Как узнать какая функция нам нужна если мы ставим брейкпоинт на функцию? Я советую вам где-нить посмотреть список стандартных функций, которые могут пригодиться при отладке ) на адрес 00407279, ввести в проге любой код, после чего мы прервемся в софтайсе, т.к. программа будет выполнять команду по этому адресу и сработает брейкпоинт. Дальше нам надо зайти в эту процедуру и искать место где сравнивается наш код со сгенерированным. Такое сравнение будет либо сделано запутанно, если защита неплохая, либо в конце процедуры будет просто стоять команда cmp, которая и будет сравнивать наш код. Но неужели вы думаете, что для нашего первого урока, я подобрал вам программу с замудренной процедурой сравнения? =) Конечно нет. Так что давайте зайдем в эту процедуру и будем искать там команду cmp. Сделаем это. Заходим в окно регистрации программы, вводим любой необычный, бросающийся в глаза код (я обычно ввожу 1234321) и открываем окно софтайса (CTRL + D). Теперь нам надо, как я уже сказал, поставить брейкпоинт на адрес 00407279. Что для этого надо сделать? Сперва надо сделать наш процесс (BlueFace) текущим. Для этого в окне SoftIce'а пишем "addr" и видим список загруженных процессов. Где-то в самом конце списка мы увидим строку такого содержания :
CR3 Addr PID NAME
........ ........ .... .........
xxxxxxxx xxxxxxxx xxxx BlueFace
Чтобы сделать наш процесс текущим, наберем "addr xxxx" , где вместо "хххх" подставляем соответствующее значение из колонки PID. ( Кстати, во избежание недоразумений, скажу, что в разных версиях SoftIce'a и как я понял в разных версиях Windows (98, XP) эта таблица может выглядеть по-разному. И колонки могут быть подписаны по-другому. Если у вас это выглядит не так как у меня, т.е. если у вас нет колонки PID, то наберите "addr name" где вместо name подставьте имя процесса (в нашем случае BlueFace, т.е наберите "addr blueface"). И никаких проблем возникнуть не должно. Процесс так же станет текущим ) Напомню, что нам необходимо сделать процесс текущим для того, чтобы получить возможность установить брейкпоинт на любой адрес в этом процессе (в нашем случае на адрес 00407279). Теперь убедимся, что наш процесс стал текущим : повторно набираем "addr" и видим, что наш BlueFace выделен. Теперь для установки брейкпоинта на адрес 00407279 ( Помните по этому адресу происходит вызов процедуры генерации и проверки кода? А нам нужно попасть в эту процедуру и найти в ней сравнение введенного кода с правильным ) наберем в СофтАйсе : "bpx 00407279" (enter) . Чтобы проверить, что наш брейкпоинт действительно установился, наберем команду "bl" (enter) и увидим такую строку:
00) BPX #00XX : 00407279
00 - это номер брейкпоинта. Когда их будет например несколько, то ниже будут брейкпоинты, номера которых будут продолжаться ( 01) , 02) и т.д. ). Сама эта строка показывает, что установлен брейкпоинт на адрес 00407279, т.е. мы убедились, что брейкпоинт поставился успешно. Теперь для продолжения работы программы нажимаем F5. Окно СофтАйса пропадает, и мы в окне регистрации, где ввели наш код от косяка, нажимаем ОК. И моментально оказываемся в окне софтайса по адресу 00407279 - это сработал наш брейкпоинт. Мы стоим прямо на команде вызова процедуры проверки кода. Нам нужно зайти в эту процедуру. Для пошагового выполнения программы с заходом внутрь процедур в софтайсе надо нажимать F8. Вот и нажимаем F8, происходит прыжок на код процедуры проверки кода, и вот что мы видим на экране:
:00408FE0 6AFF push FFFFFFFF
:00408FE2 6883FA4000 push 0040FA83
:00408FE7 64A100000000 mov eax, dword ptr fs:[00000000]
:00408FED 50 push eax
:00408FEE 64892500000000 mov dword ptr fs:[00000000], esp
:00408FF5 81EC08010000 sub esp, 00000108
:00408FFB 56 push esi
:00408FFC 8B84241C010000 mov eax, dword ptr [esp+0000011C]
:00409003 C784241401000000000000 mov dword ptr [esp+00000114], 00000000
:0040900E 50 push eax
:0040900F FF1504144100 Call dword ptr [00411404]
:00409015 83C404 add esp, 00000004
:00409018 8D4C2408 lea ecx, dword ptr [esp+08]
:0040901C 8D54240C lea edx, dword ptr [esp+0C]
:00409020 8BF0 mov esi, eax
:00409022 51 push ecx
:00409023 52 push edx
:00409024 C744241000010000 mov [esp+10], 00000100
:0040902C FF1568104100 Call dword ptr [00411068]
:00409032 8D44240C lea eax, dword ptr [esp+0C]
:00409036 8D4C2404 lea ecx, dword ptr [esp+04]
:0040903A 50 push eax
:0040903B E818510000 Call 0040E158
:00409040 8B4C2404 mov ecx, dword ptr [esp+04]
:00409044 8B15AC704100 mov edx, dword ptr [004170AC]
:0040904A C684241401000000 mov byte ptr [esp+00000114], 00
:00409052 8B41F8 mov eax, dword ptr [ecx-08]
:00409055 8D4C0201 lea ecx, dword ptr [edx+eax+01]
:00409059 40 inc eax
:0040905A 0FAFC8 imul ecx, eax
:0040905D 3BF1 cmp esi, ecx
:0040905F 5E pop esi
:00409060 8D4C2400 lea ecx, dword ptr [esp]
:00409064 7536 jne 0040909C
:00409066 E893500000 Call 0040E0FE
:0040906B 8D8C2418010000 lea ecx, dword ptr [esp+00000118]
:00409072 C7842410010000FFFFFFFF mov dword ptr [esp+00000110], FFFFFFFF
:0040907D E87C500000 Call 0040E0FE
:00409082 B801000000 mov eax, 00000001
Не пугайтесь такого большого кода. Это часть процедуры проверки. Как я уже сказал, наша задача на данном этапе - это найти место сравнения введенного нами кода со сгенерированным правильным кодом. Вспоминаем какие для этого команды могут использоваться (команды сравнения) и пытаемся найти в этой процедуре такую команду. Смотрим с начала процедуры, опускаем глаза и... и видим "cmp esi, ecx" ! Итак, это команда сравнения, и в данном случае сравниваются регистр esi и ecx . Нам тут ничего не надо, кроме как найти команду сравнения сгенерированного кода и введенного. Мы ее уже нашли. Я ее выделил. Больше команд cmp нету. Так что можете быть уверены, что это она =) Но давайте проверим. Нажимаем F10 ( F10 - пошаговое выполнение программы без захода в процедуры. Кстати напоминаю, что это вы должны делать, находять внутри окна SoftIce'а. Однако в этом случае вы не сможете читать эту статью т.к. отладчик закроет ее своим окном. Можно конечно нажать F4 (показать/скрыть окно софтайса во время отладки) и посмотреть что вы читали. Только вот все будет как бы зависшее. Это сделано специально, чтобы дать возможность посмотреть, что в этот момент на экране. но в то же время не дать программе выполняться дальше. Вообщем это хоть какой-то выход из ситуации. Если во время отладки что-то забыли, то жмете F4, читаете что надо (естественно прокрутить не сможете), потом еще раз нажимаете F4 - и вы снова в окне софтайса. Однако если вам надо будет пролистать страницу, то придется нажать F5, прочитать что надо и заново попасть отладчиком в нужное место. Как? Да у вас же остался установлен брейкпоинт на адрес 00407279. Значит если вы заново введете код в окне регистрации и нажмете ОК, то откроется окно отладчика и вы будете на этом адресе, ну дальше опять нажимаете F8, попадается в процедуру проверки и т.д. ) пока не дойдем до этой строки:
:0040905D 3BF1 cmp esi, ecx
Скорее всего в одном из регистров введенный код, а во втором, аналогично, правильный код. Так вот в SoftIce чтобы посмотреть содержимое регистра надо ввести "? регистр", например "? eax". (В принципе вверху окна софтайса показываются значения регистров, но там они в шестандатеричном виде, а чтобы посмотреть еще и в десятичном виде и в ASCII-кодах надо использовать "? регистр") А чтобы посмотреть содержимое памяти, по адресу хранящемуся в регистре, надо написать "dd регистр". Давайте посмотрим, что в esi : наберем "? esi" . И что мы видим ! это наш введенный код (я вводил 1234321):
:? esi
0012D591 01234321
Сначала показывается содержимое регистра в шестадцатеричном формате ( 0012D591 ), а потом в десятичном ( 01234321 ). Нам надо смотреть наш код в десятичном формате. Еще раз напомню, что у вас числа будут другие, если вы ввели другой код, а не "123431". Теперь посмотрим, что в ecx. Для этого наберем команду "? ecx" и обратим внимание на десятичную запись значения регистра. Ну что там в ecx? =) А в ecx правильный код !!! Переписываем его на бумажку, удаляем брейкпоинты ("bc *"), нажимаем F5 для возврата. Опять заходим в окно регистрации, вводим наш код и...
...И ВСЕ !!! Мы зарегестрированы !!! Ну ради галочки, и чтобы вам все полностью было понятно скажу, что ниже есть команда условного перехода jne. Если 2 сравниваемых кода не равны, то осуществляется переход на участок кода, где eax становится равным 0. Если коды при сравнении равны, то перехода не осуществляется и продолжается выполнение со следеющей ниже команды. Там в eax запихивается значение 1. Потом происходит выход из процедуры проверки, где как мы помним с помощью команды test eax,eax узнается, что в eax и т.д. Я рассказывал, что будет дальше. Почему мы не остановились и не разобрали это подробно? Да потому что мы и так узнали пароль, и для вашего блага я не стал забивать вам голову лишними вещами... Уточню правда, что после например переустановки программы серийный номер будет уже другой, и соотвественно будет генерироваться другой код, так что если захотите переустановить программу или установить ее на другом компе, то узнавать пароль придется также заново! Ну на этом я думаю все.. А что тут еще говорить ? Посылайте свои комментарии мне на MozgCnoSpam@avtograd.ru
Еще обычно всякие приветы в конце передают... благодарности =) Ну тоже передам :
Спасибо MoonShiner'у, freeExec'у и Fess'у за помощь, за то, что помогали мне разобраться в крэкинге и за все хорошее =)
Всем счастливо! MozgC (c) 2003
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Wersion <wcrkgroup2002@mail.ru>
Статья создана: 03.12.2002
Наконец-то появилось время написать статью про ASProtect новых версий. Я собрал всё лучшее, что читал про него и решил сделать нечто более-менее понятное.
Итак, что нам нужно:
Liatro Button Maker 2.2-наша цель.
Инструменты:
[LordPE] by Yoda
[IceDump] v 6.x. //он заменит нам ручку с бумагой
[SoftIce] 4.x.
[W32Dasm] v. 8.93
[ResHacker] v 3.2
[Hiew 32] v 6.55
[Super BPM]
[Import Reconstructor] v 1.42 & plugin(s)
[Microsoft Visual Studio*] v 6.0
точнее, нам понадобится его редактор ресурсов.
В оригинале сия программа занимает ~300 МБ, и т.к. немного неудобно всё это
покупать и/или устанавливать, то я в своё время сократил его до 1.5 МБ - это уже можно
скачать. Правда, на чужом компьютере я своё творение не испытывал, и тот, кто захочет
испробовать эту поистине замечательную вещь, может написать на wcrkgroup2002@mail.ru.
И если программа будет у вас отлично работать, то я выставлю её на http://k2wincrk.boom.ru.
Приступим непосредственно к исследованию. Сначала посмотрим нашу прог-му в LordPE и ResHacker'е.
Налицо все признаки ASProtect'a. Т.е. точка входа 0x1000, характеристики секций C0000040 и повреждённые
ресурсы. Итак, что же нам надо сделать?
Узнать Original Entry Point, запустить программу,
остановить на OEP. Затем сдампить, подправить Exe-file, задать Original Entry Point.
Потом выкинуть куски ASProtect'a, оставшиеся в теле программы, подправить ресурсы и
вставить оригинальную таблицу импорта, которую тоже надо добыть.
Реализация:
1. Нахождение OEP.
Немного теории. Любая (практически) программа желает знать адрес, по которому она загружена.
Для этого используется:
HMODULE GetModuleHandle(
LPCTSTR lpModuleName // address of module name to return handle for
);
Соответственно, чтобы получить собственный Handle, в качестве параметра надо передать
NULL или по-нашему 0. Очевидно, все эти события происходят недалеко от OEP.
(Обычно в 1-м call-e). Следовательно, наша задача - поймать этот момент.
В SoftIce'е: bpx GetModuleHandleA if(*(esp+4)==0) //Не забудьте сделать FAULTS OFF.
Каждый раз, когда срабатывает наш брейкпоинт, смотрим на стек.(dd esp).
Когда увидите в памяти адреса, похожие на программные, снимайте брейкпоинт (bd *).
Жмём F12, пока не увидим следующее:
EAX=00000001 EBX=00660000 ECX=000003F8 EDX=00BE003C ESI=816C9018
EDI=00000000 EBP=0076FE38 ESP=0076FDC0 EIP=0042F278 o d I s z a p c
CS=016F DS=0177 SS=0177 ES=0177 FS=1F77 GS=0000
--------------------------------------------------dword-------------PROT---(0)--
0177:0076EB70 00434D12 00000000 816C9018 00434E6A .MC.......l.jNC. .
0177:0076EB80 0076FDB0 00660000 00000000 00000000 ..v...f......... .
0177:0076EB90 00000000 00000000 00000000 00000000 ................
0177:0076EBA0 00000000 00000000 00000000 00000000 ................
0177:0076EBB0 00000000 00000000 00000000 00000000 ................
0177:0076EBC0 00000000 00000000 00000000 00000000 ................ .
0177:0076EBD0 00000000 00000000 00000000 00000000 ................ .
-------------------------------------------------------------------------PROT32-
016F:0042F258 890D940E4D00 MOV [004D0E94],ECX .
016F:0042F25E C1E108 SHL ECX,08 .
016F:0042F261 03CA ADD ECX,EDX
016F:0042F263 890D900E4D00 MOV [004D0E90],ECX
016F:0042F269 C1E810 SHR EAX,10
016F:0042F26C A38C0E4D00 MOV [004D0E8C],EAX
016F:0042F271 6A01 PUSH 01
016F:0042F273 E8FF5B0000 CALL 00434E77
016F:0042F278 59 POP ECX (X)
016F:0042F279 85C0 TEST EAX,EAX
016F:0042F27B 7508 JNZ 0042F285
016F:0042F27D 6A1C PUSH 1C
016F:0042F27F E8C3000000 CALL 0042F347
016F:0042F284 59 POP ECX
016F:0042F285 E8B2350000 CALL 0043283C
016F:0042F28A 85C0 TEST EAX,EAX
016F:0042F28C 7508 JNZ 0042F296
016F:0042F28E 6A10 PUSH 10
016F:0042F290 E8B2000000 CALL 0042F347
016F:0042F295 59 POP ECX .
016F:0042F296 33F6 XOR ESI,ESI . . .
------------------------------------PACKEDLBMAKER!+0002E258---------------------
:dd esp
:bd *
:/screendump C:\dump1.dos
Packedlb
Для проверки того, что это действительно начало программы, можно ещё раз нажать F12,
произойдёт обычный её запуск. Потом опять доберитесь до этого места.
Пролистайте вверх, пока не увидите:
016F:0042F21A 55 PUSH EBP (1)
016F:0042F21B 8BEC MOV EBP,ESP
016F:0042F21D 6AFF PUSH FF
016F:0042F21F 68E04E4B00 PUSH 004B4EE0
016F:0042F224 68DC4E4300 PUSH 00434EDC
016F:0042F229 64A100000000 MOV EAX,FS:[00000000]
016F:0042F22F 50 PUSH EAX
016F:0042F230 64892500000000 MOV FS:[00000000],ESP
016F:0042F237 83EC58 SUB ESP,58
016F:0042F23A 53 PUSH EBX
016F:0042F23B 56 PUSH ESI
016F:0042F23C 57 PUSH EDI
016F:0042F23D 8965E8 MOV [EBP-18],ESP
016F:0042F240 FF1548B44A00 CALL [004AB448]
Видно, что (1) - это OEP.
Как снимается после этого что-нибудь простое, типа ASPack*** ?
Ставиться брейкпоинт на OEP, вписывается туда JMP EIP. Потом дампиться и в Entry Point ставиться OEP - Image Base, правиться в Hiew, ну и всё.
Но Alexey Solodovnikov не так-то прост. Во-первых, он выкинет все ваши брейкпоинты,
а если вам (как и мне) удасться их сохранить, то вам дадут Protection Error 15,
т.к. ASProtect в самый последний момент проверяет целостность кода.
Обратимся опять к теории. У каждого, кто занимается распаковкой и не лишен мозгов,
возникает вопрос: а почему, собственно, надо зацикливать программу?
Правда, его редко задают и этим самым ограничивают себя. А надо бы знать, что
программа при запуске много чего инициализирует в секции данных и даже кода. Соответственно, когда дамп пытается повторить сделанную им в "прошлой жизни" операцию,
у него ничего не выходит. Так получим же чистый, "ещё не работавший" файл.
Для этого перед исследованием запустим Super BPM(c флажком Erase), очутившись в позиции Х
поставим брейкпоинт: bpm 42F21A R //our OEP
Теперь каждый раз, попадая в SoftIce, делаем u 0x42F21A. Как только видим нормальный код,
зацикливаем программу, дампим с помощью Lord PE и убиваем её. Проследите, чтобы были включены
опции 1,2 и последняя в Task Viewer. Потом открываем файл в Visual Studio, сохраняем
ресурсы как один .res файл. Затем заходим в ResHacker, и делаем Update All Resources
нашему дампу. Теперь вычисляем и выставляем OEP и смело вырезаем код
ASProtect'a из программы(2 последние секции). Как это делается:
Truncate at section start & Wipe Section Header. Операцию начинать с конца.
Запускаем нашу программу. Запускаем Import Reconstructor. Пишем в OEP 2F21A.
Затем Iat Autosearch; Get Imports. Видим много неправильного. Прежде чем всё это исправлять,
посмотрим, нет ли здесь откровенного бреда. Вот и он:
FThunk: 000AB830 NbFunc: 0000000D
0 000AB830 ? 0000 00401360(1)
0 000AB834 ? 0000 00401210
0 000AB838 ? 0000 004011E0
0 000AB83C ? 0000 00401190
0 000AB840 ? 0000 0041C0E0
0 000AB844 ? 0000 0041C0C0
0 000AB848 ? 0000 0041C0A0
0 000AB84C ? 0000 0041C040
0 000AB850 ? 0000 0041C020
0 000AB854 ? 0000 0041C000
0 000AB858 ? 0000 0042DCB0
0 000AB85C ? 0000 0042DCA0
0 000AB860 ? 0000 00401130(L)
Адреса 1..L не принадлежат ни к чему, относящемуся к Import Table.
Поэтому убираем их через контекстное меню->Delete thunk(s).
Далее Show Invalid, Trace Level 1, ASProtect Plug-in. Найдутся все функции кроме одной.
Самый простой способ узнать её - посмотреть, чего здесь не хватает. Для этой цели я держу у
себя таблицы импортов нормальных программ (например "Блокнота"). Итак, наша функция
-GetProcAddress. Дважды щёлкаем и выбираем. Затем Fix Dump. Флажок Add New Section должен
стоять. В принципе, уже всё. Теперь в дело идёт PE Editor. Переименуйте секции по вкусу,
первой поставьте E0000020, чтобы можно было нормально дизассемблировать.
Далее Rebuild PE, в PE Rebuilder's Options выставьте всё, кроме того, что связано с Import Table
& Image Base.
Собственно взлом. В регистрационном диалоге вводим наши данные. В SoftIce'e:bpx hmemcpy
Жмём "Unlock", В SoftIce'e:bd *; F12 пока не увидим:
016F:00411EEB 6A01 PUSH 01
016F:00411EED E8F19C0600 CALL 0047BBE3
016F:00411EF2 8DBE98010000 LEA EDI,[ESI+00000198]
016F:00411EF8 8BCF MOV ECX,EDI
016F:00411EFA E818470600 CALL 00476617
016F:00411EFF 8BCF MOV ECX,EDI
016F:00411F01 E8C5460600 CALL 004765CB
016F:00411F06 8D9E9C010000 LEA EBX,[ESI+0000019C]
Ниже видим такой код:
016F:00411F50 51 PUSH ECX
. 016F:00411F51 52 PUSH EDX
016F:00411F52 B9A8ED4C00 MOV ECX,004CEDA8
016F:00411F57 E824030000 CALL 00412280 (1)
016F:00411F5C 85C0 TEST EAX,EAX
016F:00411F5E 7422 JZ 00411F82
016F:00411F60 6AFF PUSH FF
016F:00411F62 6A00 PUSH 00
016F:00411F64 68CD000000 PUSH 000000CD
016F:00411F69 E857410700 CALL 004860C5
016F:00411F6E 8B06 MOV EAX,[ESI]
016F:00411F70 8BCE MOV ECX,ESI
016F:00411F72 FF90C8000000 CALL [EAX+000000C8]
016F:00411F78 5F POP EDI
016F:00411F79 5E POP ESI
016F:00411F7A 5B POP EBX
016F:00411F7B 81C400020000 ADD ESP,00000200
016F:00411F81 C3 RET
. 016F:00411F82 6AFF PUSH FF
Нам надо, чтобы после (1) в EAX оказалось 1.
Зайдём туда.
* Referenced by a CALL at Addresses:
|:00408AC8 , :0040982B , :00409E18 , :0041199C , :00411F57
|:004126D0 , :00413E7A , :004151C0 |
:00412280 81ECB4000000 sub esp, 000000B4
:00412286 56 push esi
:00412287 8BF1 mov esi, ecx
:00412289 8B5604 mov edx, dword ptr [esi+04]
:0041228C 85D2 test edx, edx
:0041228E 750C jne 0041229C
:00412290 33C0 xor eax, eax
:00412292 5E pop esi
:00412293 81C4B4000000 add esp, 000000B4
:00412299 C20800 ret 0008
Внесём необходимые изменения с помощью Hiew.
:0041228C 33C0 xor eax, eax
:0041228E 40 inc eax
:00412290 909090 - NOP,NOP,NOP
ВСЁ! ПРОГРАММА ЗАРЕГИСТРИРОВАНА!
Кладите в архив и добавляйте *.nfo.
Если ASProtect всё-таки умудрился отключить ваши брейкпоинты, сделайте в Softice:
be [номер брейкпоинта].
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy <bad_guy@mail333.com>
Статья создана: 16.03.2003
Написанная мной в феврале 2003 года статья "Социальная инженерия в реверс инженеринге" - понравилась многим авторам сайтов Рунета, ее разместили на своих страницах порядка десяти сайтов, среди которых был даже сайт журнала "Хакер". И спустя месяц ко мне с просьбой написать статью для журнала "Компьютерра" обратился редактор Сергей Леонов, статью я написать согласился (она уже напечатана в "Компьютерре" от 22.04.2003), а от гонорара отказался в пользу размещения ссылки на CRACKL@B в журнале. Надо сказать, что я переоценил возможности журнала в продвижении сайта, ну да ладно...
А сейчас вы можете ознакомиться с содержанием этой статьи, однако сразу скажу, что статья писалась "на массу", поэтому вряд ли будет интересна опытному крэкеру.
Множество программистов занимаются разработкой shareware (платных) программ и создают поистине замечательные продукты, но механизм регистрации пишут обычно на последнем этапе, и нередко "на скорую руку". В этом кроется большая ошибка, которой могут воспользоваться исследователи защит программ или попросту крэкеры, к коим я и отношусь. В этой статье будут рассмотрены типовые методы защиты программ и способы их "обхода", однако поскольку статья рассчитана на широкую аудиторию читателей, я не буду здесь приводить программных кодов.
Один из наиболее распространенных способов защиты программы - написание этой защиты собственными руками, и именно в таком способе проявляются крайности: эти защиты либо очень надежны, либо, наоборот, очень слабы. Объясняется это, по-видимому, степенью образованности автора в области защиты программ. Приведу простой пример: вы написали компьютерную игру и ничего не знаете про крэкеров, дизассемблеры, отладчики… Вы создаете окошко, в котором написано "Введите имя пользователя", "Введите регистрационный код", затем, по нажатию "OK", складываете коды всех символов в регистрационном имени и сравниваете это число с введенным регистрационным кодом, а потом, в зависимости от результатов сравнения, выдаете пользователю окошко, либо "Спасибо за регистрацию!", либо "Неверный регистрационный код". Теперь расскажу, как легко снять эту защиту: понадобится отладчик (самый популярный - SoftIce). Когда исследователь защиты вводит свое "имя пользователя" и произвольное число в качестве "регистрационного кода", он ставит в отладчике прерывание, которое остановит вашу программу при считывании данных из тех самых полей ввода. Отладчик покажет текст дизассемблированного кода программы в этом месте, далее программа пошагово исполняется под отладчиком, контролируемая крэкером. Рано или поздно, независимо от хитрости превращения имени пользователя в регистрационный код, крэкер увидит место, где сгенерированный программой правильный код будет сравниваться с введенным неправильным кодом. Теперь достаточно просто записать на бумажку правильный регистрационный код и ввести его в окошке регистрации. Реально весь описанный процесс занимает от 30 секунд до 10 минут. Самый же надежный на сегодняшний день способ защиты - это шифрование правильным регистрационным кодом тех процедур, которые работают только в зарегистрированной версии программы - такой способ защиты осуществить чрезвычайно тяжело, даже я не до конца знаю, как это сделать. Однако, слабой стороной этого метода является то, что код (или его часть) будет одним и тем же для каждого пользователя, то есть при распространении такого кода на крэк-сайтах, автор не будет знать, какой пользователь его распространил. Соответственно, он будет продолжать посылать коды для новых версий своей программы в частности и этому пользователю. Совсем не обязательно даже покупать программу, для получения кода есть два других способа: один из них противозаконный - его я рассматривать не буду, потому что действую всегда в рамках закона, другой способ менее действенный, но весьма законный - это социальная инженерия.
Социальная инженерия пришла в крэкерство из хакерства (в Рунете - во многом благодаря стараниям автора этой статьи), в хакерство же она пришла из жизни, где существовала с незапамятных времен. Как ни странно, многие и по сей день не знают что это такое, поэтому специально для разработчиков и исследователей программ рассказываю. Социальная инженерия - это некоторые действия над человеческим сознанием с целью получения желаемого результата, поэтому скорее речь идет не о том, как взломать программу, а о том, как "взломать" ее автора. Суть самого метода такова: надо уверить автора, что вам очень нужна зарегистрированная версия его программы, но у вас нет денег на ее приобретение. Таким образом вполне реально получить коды к shareware-программам не пользуясь ничем, кроме электронной почты. Разработчики программ должны знать о таком способе "взлома", чтобы не допускать влияния "человеческого фактора" на надежность защиты. Эта технология подробно описана автором в статье "Социальная инженерия в реверс-инженеринге", которую несложно найти поиском в Интернете.
Второй способ защиты программы, ставший недавно весьма популярным - использование специального протектора исполняемых файлов, то есть после компиляции своего творения автор берет программу-протектор и запаковывает ей собственную программу. Протекторы пишутся весьма грамотными профессионалами в области защиты, поэтому обеспечивают неплохой уровень противодействия взлому, с которым большинству исследователей программ не справиться. Но, поскольку некоторые из протекторов становятся очень популярными, их начинают исследовать все больше и больше не самых безграмотных крэкеров, которыми впоследствии пишутся программы-анпротекторы (распаковщики этой защиты). Подобные средства быстро и автоматически снимают эту защиту, хотя некоторые варианты приходится снимать вручную - это высший уровень крэкерства, доступный не каждому.
Третий способ - защита через Интернет. Если ваша программа работает с сетью, например, это может быть менеджер закачки файлов, браузер или FTP-клиент, можно применить проверку введенного в программу кода через Интернет, используя базу данных пользователей на сайте программы. Однако проверять нужно какие-либо косвенные данные, чтобы исследователь не мог получить с сайта программы, например, базу данных с серийными номерами. Для того чтобы снять такую защиту, нужно найти в программе место, где идет обращение к сайту и возвращается результат проверки. После нахождения достаточно просто подменить результат, например, с помощью пропатчивания программы в нужном месте. Сложность взлома этой защиты заключается в том, что достаточно непросто найти в коде программы место, где идет обращение к Интернет-серверу именно с целью проверки регистрационного кода.
Четвертый способ - аппаратные ключи. Этот метод защиты доступен только крупным разработчикам программного обеспечения, потому что приходится поставлять пользователю нечто материальное: диск с программой и сам ключ, кроме того, стоимость такого метода довольно велика. Снятие этой защиты - задача достаточно сложная, но осуществимая. Уже существуют эмуляторы аппаратных ключей, однако из-за редкости применения указанного способа, крэкеров, снимающих подобную защиту мало - многие ею просто не занимаются.
Безусловно, здесь приведены не все способы защиты программ, а лишь наиболее популярные. В помощь российским разработчикам программного обеспечения, как профессионал-исследователь защит программ, могу дать несколько полезных советов. На мой взгляд, в первых версиях своей shareware программы не стоит серьезно заниматься механизмом защиты. Дело в том, что можно, во-первых, переоценить практическую ценность своей программы - на самом деле она так плоха, что ее никто даже не купит, и смысл в защите пропадает. Во-вторых, зачем тратить на разработку защиты то время, которое можно с успехом потратить на раскрутку самой программы.
Допустим, ваш продукт начал продаваться, и вы получили свой первый гонорар. Теперь начинайте заходить на всевозможные крэк-сайты и ищите там крэк к своей программе. Пока вы его не найдете, не занимайтесь улучшением защиты - улучшайте саму программу, это принесет больше прибыли. Как только вы найдете крэк к своей программе в сети, сразу подумайте о другой защите, именно другой - меняйте сам принцип. Если вы не умеете самостоятельно писать защиту и не имеете средств на заказ профессионала, воспользуйтесь каким-нибудь коммерческим протектором программ. Разумеется, вам придется заплатить за его регистрацию порядка сотни долларов, но ведь ваша программа принесла уже больше… или нет? Можно предложить еще один альтернативный способ: обратиться к крэкеру, дабы он помог разработать алгоритм защиты. Конечно, это тоже будет не бесплатно, но наверняка меньше тех самых ста долларов, ведь большинство крэкеров - это обычные студенты. Желательно знать такого человека лично, иначе, при взаимодействии только через сеть, вас могут запросто обмануть.
Для тех, кто хочет самостоятельно писать защиту своих программ, также хочется привести несколько общих рекомендаций:
Вполне возможно, что прочитав эту статью вы решите заняться исследованием защит программ, или попросту, присоединиться к когорте крэкеров. Что для этого нужно? Как минимум: неплохое знание программирования на любом высокоуровневом языке (Pascal, C и т.д.), базовое знание ассемблера (достаточно знать его функции), также полезно знание архитектуры какого-нибудь еще более-менее используемого процессора (очень хорош для понимания Intel 486), нужно найти отладчик SoftIce, ну и еще пару статей для крэкеров-новичков. На первых порах - не лениться, не пугаться, проявлять настойчивость и уверенно действовать, тогда вы рано или поздно станете замечательным крэкером, а может даже и профессионалом по защите программ.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Ïðîàíàëèçèðîâàâ ñîäåðæèìîå ôàéëà OperationFlashpoint.exe, ÿ îáíàðóæèë, ÷òî íàçâàíèÿ ñåãìåíòîâ íå ñîäåðæàò íå îäíîãî ñèìâîëà è ýêñïîðòèðóåòñÿ ìèíèìàëüíûé íàáîð ôóíêöèé èç ìîäóëåé KERNEL32.DLL, USER32.dll: LoadLibraryA, GetProcAddress, VirtualProtect, ExitProcess, MessageBoxA. Òàê îáû÷íî ïîñòóïàþò, ÷òîáû ñêðûòü ñîäåðæèìîå ôàéëà îò âñÿêèõ äèñàññåìáëåðîâ, ò.å. êîãäà ôàéë çàïàêîâàí.
Äàëåå çàïóñêàþ SoftICE è ñòàâëþ áðåêïîèíò íà ôóíêöèþ îïðåäåëåíèÿ òèïà óñòðîéñòâà (bpx GetDriveTypeA). Âñòàâëÿåì CD è çàïóñêàåì èãðó. Óáåæäàåìñÿ, ÷òî ôóíêöèþ âûçâàëà èãðà, à íå explorer.exe. Äàëüøå æìó F5 ïîêà ýòó ôóíêöèþ íå âûçîâóò ñ ïàðàìåòðîì óêàçûâàþùèé ïóòü ê CD.
00011E2: lea eax,[ebp][-000C]
00011E5: push eax
00011E6: call d,[000407018] ; GetDriveTypeA
00011EC: mov dl,al ; al=05 òóò ìû îêàçàëèñü ïîñëå âûõîäà èç ôóíê.
00011EE: lea edi,[ebp][0FFFFF254] ; ññûëêà íà áóôåð ñ ìåòêîé òîìà äèñêà
00011F4: or ecx,-001
00011F7: xor eax,eax
00011F9: repne scasb
00011FB: not ecx
00011FD: dec ecx ; ecx ðàâåí äëèíå ìåòêè
00011FE: add ecx,esi ; esi ñîîòâåòñòâóåò àäðåñó íà 4 áàéòà ìåíüøå ÷åì àäðåñ áóôåðà, ò..å îáðàáîòêå ïîäëåæàò ïîñëåäíèå 4 ñèìâîëà
0001200: mov bl,[eax][ecx]
0001203: add bl,dl
0001205: mov [eax][ecx],bl ;óâåëè÷èâàþò ñèìâîëû íà 5(âåðíóëà ôóíê.) ïîçèöèé äàëüøå
0001208: inc eax
0001209: cmp eax,004 ; âñåãî 4 ñèìâîëà
000120C: jl 000001200 -------- (2)
000120E: mov ecx,[ebp][-0010]
0001211: lea edx,[ebp][0FFFFFD1F]
0001217: push ecx
0001218: lea eax,[ebp][0FFFFF254]
000121E: push edx
000121F: push eax
0001220: call 0000014C0 -------- (3) ; ýòà ôóíêöèÿ ñðàâíèâàåò äâà áóôåðà ïåðåäàííûå åé â ïàðàìåòðàõ
0001225: add esp,00C
0001228: test eax,eax
000122A: jne 0000012D5 -------- (4)
Ôóíêöèÿ (3) âîçâðàùàåò 0, åñëè áóôåðà îäèíàêîâûå, è çíà÷èò (4)-ûé ïåðåõîä íå îñóùåñòâëÿåòñÿ.
:00401230 lea ecx, dword ptr [ebp-6C]
:00401233 push ecx
:00401234 call dword ptr [00407014] ; GetStartupInfoA
:0040123A xor eax, eax
:0040123C mov cl, byte ptr [ebp+eax-00000179] ; mrc32.dll
:00401243 mov byte ptr [ebp+eax-00000DAC], cl
:0040124A inc eax
:0040124B test cl, cl
:0040124D jne 0040123C
:0040124F lea edi, dword ptr [ebp+FFFFF254]
:00401255 or ecx, FFFFFFFF
:00401258 xor eax, eax
:0040125A mov dx, word ptr [004080C0]
:00401261 repnz
:00401262 scasb
:00401263 or ecx, FFFFFFFF
:00401266 mov word ptr [edi-01], dx
:0040126A mov edi, dword ptr [ebp+10]
:0040126D repnz
:0040126E scasb
:0040126F not ecx
:00401271 sub edi, ecx
:00401273 lea edx, dword ptr [ebp+FFFFF254]
:00401279 mov esi, edi
:0040127B mov ebx, ecx
:0040127D mov edi, edx
:0040127F or ecx, FFFFFFFF
:00401282 repnz
:00401283 scasb
:00401284 mov ecx, ebx
:00401286 dec edi
:00401287 shr ecx, 02
:0040128A repz
:0040128B movsd
:0040128C mov ecx, ebx
:0040128E lea eax, dword ptr [ebp-28]
:00401291 and ecx, 00000003
:00401294 push eax ; struct _PROCESS_INFORMATION
:00401295 repz
:00401296 movsb
:00401297 lea ecx, dword ptr [ebp-6C]
:0040129A lea edx, dword ptr [ebp+FFFFF254]
:004012A0 push ecx ; struct _STARTUPINFO
:004012A1 push 00000000
:004012A3 push 00000000
:004012A5 push 00000004
:004012A7 push 00000000
:004012A9 push 00000000
:004012AB push 00000000
:004012AD push edx ; mrc32.dll
:004012AE push 00000000
:004012B0 call dword ptr [00407010] ; CreateProcess
:004012B6 test eax, eax
:004012B8 jne 00401307
...
:00401307 mov ecx, dword ptr [ebp+FFFFFCF8]
:0040130D mov edx, dword ptr [ebp-28]
:00401310 lea eax, dword ptr [ebp-08]
:00401313 add ecx, 00400000
:00401319 push eax ; áóôåð, ñþäà âåðíóò ñòàðûå ïðàâà
:0040131A push 00000040 ; íîâûé êîä äîñòóïà, 40h=PAGE_EXECUTE_READWRITE
:0040131C push 00000100 ; ðàçìåð
:00401321 push ecx ; àäðåñ ðåãèîíà äëÿ èçìåíåíèÿ äîñòóïà ê ñòðàíèöå ïàìÿòè
:00401322 push edx ; HANDLE hProcess èç struct _PROCESS_INFORMATION
:00401323 call dword ptr [0040700C] ; VirtualProtectEx
:00401329 test eax, eax
:0040132B jne 00401348
…
:00401348 mov edx, dword ptr [ebp+FFFFFCF8]
:0040134E lea eax, dword ptr [ebp-08]
:00401351 push eax ; áóôåð, ñþäà âåðíóò êîëè÷åñòâî çàïèñàííûõ áàéò
:00401352 mov eax, dword ptr [ebp-28]
:00401355 lea ecx, dword ptr [ebp+FFFFFD70]
:0040135B push 00000100 ; ðàçìåð áóôåðà
:00401360 add edx, 00400000
:00401366 push ecx ; àäðåñ – îòêóäà ñêîïèðîâàòü (12FCA4)
:00401367 push edx ; àäðåñ – êóäà ïèñàòü (44CCBF)
:00401368 push eax ; HANDLE hProcess
:00401369 call dword ptr [00407008] ; WriteProccessMemory
:0040136F test eax, eax
:00401371 je 0040137C
:00401373 cmp dword ptr [ebp-08], 00000100
:0040137A je 00401398 ; îñóùåñòâëÿåòñÿ ïðûæîê
…
:00401398 mov ecx, dword ptr [ebp-24]
:0040139B push ecx ; HANDLE hThread
:0040139C call dword ptr [00407004] ; ResumeThread
:004013A2 mov edx, dword ptr [ebp-28]
:004013A5 push FFFFFFFF ; êîëè÷åñòâî ìèëëèñèêóíä
:004013A7 push edx ; HANDLE hHandle
:004013A8 call dword ptr [00407000] ; WaitForSingleObject
Òåïåðü ðàçáåðåìñÿ âî âñåõ âûçûâàþùèõñÿ ôóíêöèÿõ. GetStartupInfo íóæíà äëÿ ïîëó÷åíèÿ îäíîèìåííîé ñòðóêòóðû, òðåáóþùåéñÿ äëÿ ôóíêöèè ñîçäàíèÿ ïðîöåññà - CreateProcess. Ñîçäàåì ïðîöåññ èñïîëüçóÿ ôàéë mrc32.dll, îí òî è åñòü ÿäðî èãðû. Çàòåì ôóíêöèåé VirtualProtectEx íàçíà÷àåì íîâûå ïðàâà êîäó çàãðóæåííîãî ìîäóëÿ, à èìåííî ðàçðåøàåì âûïîëíÿòü ýòîò êîä. Ïîòîì òóäà êîïèðóåì êîä èç àäðåñà 12FCA4, è ïåðåäàåì óïðàâëåíèå ñîçäàííîìó ïðîöåññó, ôóíêöèåé WaitForSingleObject. Åäèíñòâåííàÿ òðóäíîñòü ýòî ïîëó÷èòü êîä êîòîðûé ìû êîïèðóåì äëÿ èñïîëíåíèÿ. Ìîæíî áûëî êîíå÷íî ïåðåïèñàòü ýòè 256 áàéò è ðóêàìè, íî ÿ ñäåëàë ïî äðóãîìó.
Âñòàâëÿþ CD, ñòàâëþ áðåêïîèíò íà ôóíêöèþ GetDriveTypeA (bpx GetDriveTypeA), çàïóñêàþ èãðó. Ïîñëå âûëåòà â ôóíêöèþ, ñòàâëþ åùå îäèí áðåêïîèíò (bpx 401355),æìó F5. Òåïåðü ìíå íóæíû àäðåñà òðåõ ôóíêöèé CreateFileA, WriteFile, ExitProcess. Ïîëó÷àþ èõ ïîìîæüþ êîìàíäû EXP (exp CreateFileA), â îòâåò äîëæíî áûòü ÷òî-òî òàêîå:
exp CreateFileA
KERNEL32
001B:77E7A837 CreateFileA
exp WriteFile
KERNEL32
001B:77E79D8C WriteFile
exp ExitProcess
KERNEL32
001B:77E75CB5 ExitProcess
Çàòåì çàäàþ ïàðàìåòðû ïåðâîé ôóíêöèè, ïðÿìî â ñòåê.
d esp ## ïîêàçàòü ñòåê
e ## íà÷àòü ðåäàêòèðîâàòü åãî
Äîëæíî ýòî âûãëÿäåòü êàê-òî òàê. Ôóíêöèÿ íà ÿçûêå Ñè âûãëåäèò òàê: CreateFileA(&filename, 0x40000000, 0, 0, 2, 0x80, 0); 8C 9D E7 77 – ýòî àäðåñ âîçâðàòà (íà ôóíêöèþ WriteFile = 77E79D8C), òóäà ïîïàäàåì ïîñëå çàâåðøåíèÿ ôóíêöèè CreateFileA. Ïî àäðåñó 0012E198 (98 E1 12 00) íàõîäèòñÿ èìÿ ôàéëà çàâåðøàþùååñÿ íóëåâûì ñèìâîëîì. Ýòîò ôàéë äîëæåí ñóùóñòâîâàòü. Òåïåðü ñòàâèì óêàçàòåëü íà íà÷àëî ôóíêöèè CreateFileA.
r eip=77E7A837 # èçìåíÿåì çíà÷åíèå ðåãèñòðà EIP
bpx WriteFile # ÷òî îòëîâèòü ìîìåíò êîãäà çàâåðøèòñÿ ïåðâàÿ ôóíêöèÿ
Æìó F5. Åñëè âñå íîðìàëüíî, òî äîëæåí îñòàíîâèòñÿ íà ïåðâîé êîìàíäå ôóíêöèè WriteFile, à EAX íå ðàâíÿòüñÿ FFFFFFFF, ïîòîìó ÷òî ýòî êîä îøèáêè. Ó ìåíÿ EAX=000007CC, ýòî õýíäë íà òîëüêî ÷òî ñîçäàííûé ôàéë.
Çàäàþ ïàðàìåòðû âòîðîé ôóíêöèè, ïðÿìî â ñòåê.
d esp ## ïîêàçàòü ñòåê
e ## íà÷àòü ðåäàêòèðîâàòü åãî
Äîëæíî ýòî âûãëÿäåòü êàê-òî òàê. Ôóíêöèÿ íà ÿçûêå Ñè âûãëåäèò òàê: WriteFile(hHandle, 0x0012FCA4, 100, 0x0012E1C8, 0); ãäå hHandle=0x7CC, 0x0012FCA4 – àäðåñ áóôåðà ðàäè êîòîðîãî âñå è çàòåÿë, 100 åãî ðàçìåð, 0x0012E1C8 – ñþäà íàïèøóò ñêîëüêî ðåàëüíî çàïèñàëè áàéò. 5B 5C E7 77 – ýòî àäðåñ âîçâðàòà (íà ôóíêöèþ ExitProcess = 77E75CB5), òóäà ïîïàäàåì ïîñëå çàâåðøåíèÿ ôóíêöèè CreateFileA. Òåïåðü ó ìåíÿ åñòü âñå ÷òîáû ñ èìèòèðîâàòü çàïóñê èãðû, ò.å. íàïèñàòü çàãðóç÷èê ñàìîìó áåç âñÿêèõ âûêðóòàñîâ.
Ïðèâåäåí ïðèìåð çàãðóç÷èêà:
File calldll.asm
;--------------------------CUT HERE----------------------
.386
.model flat, stdcall
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data?
buff db 100h dup (?)
prin db 100h dup (?)
.code
start:
jmp @F
libName db "mrc32.dll",0
include patch.inc
@@:
push offset buff
call GetStartupInfo
push offset prin
push offset buff
push 0
push 0
push 4
push 0
push 0
push 0
push offset libName
push 0
call CreateProcess
mov eax, offset [prin+20h]
push eax
push 000040h
push 000100h
mov ecx, 44CCBFh
push ecx
mov eax, dword ptr [prin]
push eax
call VirtualProtectEx
mov eax, offset [prin+20h]
push eax
push 000100h
push offset patch
push 44CCBFh
mov eax, dword ptr [prin]
push eax
call WriteProcessMemory
mov eax, dword ptr [prin+4]
push eax
call ResumeThread
push 0000FFh
mov eax, dword ptr [prin]
push eax
call WaitForSingleObject
invoke ExitProcess,eax
end start
file patch.ini
;--------------------------CUT HERE----------------------
patch:
db 055h,08Bh,0ECh,06Ah,0FFh,068h,018h,024h,06Eh,000h,068h,0ECh,020h,06Ch,000h,064h
db 0A1h,000h,000h,000h,000h,050h,064h,089h,025h,000h,000h,000h,000h,083h,0ECh,058h
db 053h,056h,057h,089h,065h,0E8h,0FFh,015h,00Ch,052h,06Ch,000h,033h,0D2h,08Ah,0D4h
db 089h,015h,0C8h,070h,077h,000h,08Bh,0C8h,081h,0E1h,0FFh,000h,000h,000h,089h,00Dh
db 0C4h,070h,077h,000h,0C1h,0E1h,008h,003h,0CAh,089h,00Dh,0C0h,070h,077h,000h,0C1h
db 0E8h,010h,0A3h,0BCh,070h,077h,000h,033h,0F6h,056h,0E8h,0CAh,052h,0FFh,0FFh,059h
db 085h,0C0h,075h,008h,06Ah,01Ch,0E8h,06Fh,04Eh,027h,000h,059h,089h,075h,0FCh,0E8h
db 0B9h,062h,0FFh,0FFh,0FFh,015h,0D8h,051h,06Ch,000h,0A3h,064h,08Bh,077h,000h,0E8h
db 08Fh,02Ah,0FFh,0FFh,0A3h,0FCh,070h,077h,000h,0E8h,0A3h,0A0h,0FFh,0FFh,0E8h,037h
db 0A1h,0FFh,0FFh,0E8h,0F4h,036h,0FFh,0FFh,089h,075h,0D0h,08Dh,045h,0A4h,050h,0FFh
db 015h,010h,052h,06Ch,000h,0E8h,0FEh,0FEh,0FFh,0FFh,089h,045h,09Ch,0F6h,045h,0D0h
db 001h,074h,006h,00Fh,0B7h,045h,0D4h,0EBh,003h,06Ah,00Ah,058h,050h,0FFh,075h,09Ch
db 056h,056h,0FFh,015h,0E8h,050h,06Ch,000h,050h,0E8h,099h,087h,0FDh,0FFh,089h,045h
db 0A0h,050h,0E8h,0F3h,036h,0FFh,0FFh,08Bh,045h,0ECh,08Bh,008h,08Bh,009h,089h,04Dh
db 098h,050h,051h,0E8h,060h,001h,000h,000h,059h,059h,0C3h,08Bh,065h,0E8h,0FFh,075h
db 098h,0E8h,0C3h,036h,0FFh,0FFh,083h,03Dh,004h,071h,077h,000h,001h,075h,005h,0E8h
; ------------------END CUT -----------------------
file compl.bat
;--------------------------CUT HERE----------------------
@echo off
e:\masm32\bin\ml /Zf /Zi /c /coff /w calldll.asm
if errorlevel 1 goto exit
echo _
echo MASM32 OK *************************************************
echo _
e:\masm32\bin\Link /DEBUG /SUBSYSTEM:WINDOWS calldll.obj
:exit
pause
; ------------------END CUT -----------------------
Âåñü àðõèâ ìîæíî ñêà÷àòü (è îí âðîäå äàæå ðàáîòàåò ) http://freeexec.pisem.net/Donwloads/OperFlashPoint_noCD.rar
Àâòîð: FreeExec
E-mail: freeExec@mail.ru
Ìàòåðèàëû íàõîäÿòñÿ íà ñàéòå http://cracklab.narod.ru/doc/
Статью написал: Bad_guy <bad_guy@mailru.com>
Статья создана: 06.02.2003
Недавно меня посетила мысль: "Описания какого взлома не хватает на моем сайте CRACKL@B ?". Ответ пришел незамедлительно: "Взлома методом социальной инженерии.", что ж: сказано - сделано !
За все время своей крэкерской карьеры я не раз встречал множество статей с описаниями множества способов взлома программ - чего там только не было... однако мне ни разу не доводилось встречать описания взлома методом социальной инженерии, хотя такой метод и был отмечен в классификации способов взлома. Не знаю почему никто в Рунете не хотел описывать до меня такой интересный и аватюристский метод взлома, как социальная инженерия, может быть многие крэкеры считают это ниже своего достоинства или просто тычутся между стенками разнообразных крэкерских утилит забывая об альтернативных способах взлома ? Надеюсь, что эта статья приобретет скандальную известность в крэкерских кругах и откроет большому числу крэкеров новые непознанные пути... а теперь - в путь !
На всякий случай, давайте сначала определим что же такое Социальная Инженерия (СИ). СИ - это некоторые действия над человеческим сознанием с целью получения желаемого результата. Поэтому сегодня вы узнаете скорее не как взломать shareware-программу, а как взломать shareware-автора.
С целью получения некоторых статистических данных о методе социальной инженерии в реверс инженеринге, было решено взломать не одну, а пять программ, с авторами первых двух программ я когда-то немного общался, поэтому решил взять их программы, остальные три программы были выбраны следующим образом: у меня на диске был старый каталог download.ru, я зашел на главную страницу, выбрал раздел "Мультимедиа и графика", затем раздел "графические редакторы" - на той странице и находились все эти программы, они были выбраны так, чтобы автором был частный разработчик и чтобы цена была не менее 100 рублей, но и не более 500, а также, чтобы программа была рассчитана на обычного юзера и ее версия не была последней выпущенной, кстати, скачивать те программы я не стал за ненадобностью, а из первых двух я иногда использую только Advanced Video Poker, который уже давно взломал обычным способом.
Был составлен такой список (там присутствовал еще e-mail автора):
!ВНИМАНИЕ! Некоторые нижеследующие грамматические ошибки допущены намерено, как часть общего замысла.
%PROGRAM% | %AUTHOR% | %PRICE% |
ZSKSoft Synchronizer 1.11 | колектив ZSKSoft | 100 руб. |
Advanced Video Poker 1.30.1 | колектив Aimgames | 20$ |
WaveL Pic2Pic Pro 1.7 | Леонид Николаевич | 200 руб. |
VCW VicMans Photo Editor 5.43 | Виктор | 150 руб. |
QuickPic SchemCreator 3.2 | Владислав Николаевич | 4$ |
Далее на e-mail авторам было отправлено такое сообщение:
Subject: %PROGRAM%
Здраствуйте, уважаемый %AUTHOR%.
Мне очень нравится ваша программа %PROGRAM% - я пользуюсь ей
почти каждый день и хотел бы стать зарегистрированным пользователем,
но сумма, которую надо заплатить очень велика. У нас многодетная
семья 5 детей, мы живем на 120 рублей в день и еле сводим концы с
концами, поэтому родители не позволяют мне заплатить за вашу
программу, не могли бы вы дать мне бесплатную регистрацию, я буду
вам очень-очень благодарен за это !
Поверьте, я действительно очень хотел бы ее купить, но у меня нет
денег даже на модем и интернет (я отсылаю вам это письмо от друга),
а старенький компьютер нам подарил сосед-програмист.
Огромное спасибо!
Шепелев Антон.
Адрес электроной почты: sam*****@yandex.ru
Если я вам стал противен после прочтения текста этого письма, значит вы еще не совсем Bad_guy. На всякий случай скажу, что все в этом письме чистая неправда, а то вы меня еще жалеть начнете.
Так, первый этап взлома был совершен, и, в принципе, в ответном письме я должен был получить регистрационные коды от всех программ, но не так все просто, как хотелось...
На следующий день в ящике sam*****@yandex.ru меня ждали 3 письма, но в них были не регистрационные коды, а всяческий флейм, поэтому на все три мне пришлось ответить, давайте, чтобы не создавать путаницу, разберемся теперь до конца с каждой программой.
От создателя этой программы я получил следующее письмо:
Здравствуйте Антон,
Спасибо Вам за интерес к нашей программе. Мы готовы дать Вам
бесплатную регистрацию в обмен на небольшой отчет следующего
содержания:
- для чего Вам нужен ZSKSoft Synchronizer, как Вы его используете
(желательно подробно);
- что Вам нравится в программе, что не нравится, что хотелось бы
видеть в будущих версиях;
- чем Вам не подходит бесплатная программа vuBrief:
http://www.vu-software.spb.ru/brief/
- характеристики Вашего компьютера: процессор, обьем памяти, размер
диска, операционная система.
С уважением,
Сергей Зырянов
http://www.zsk****.com/rus
support@zsk****.com
Надо сказать, этот ответ меня сильно повеселил, я еще раз убедился в предприимчивости отечественных шароварщиков.
Хотел было не отвечать, лень было изучать программу, но потом решил все таки пойти до конца, почитал help-файл, попробовал и выдал следующий текст, вжившись в положение Шепелева Антона.
Здраствуйте, Сергей.
Огромное спасибо за ответ, я рад что смогу вам чем-то помочь
в обмен на регистрацию, вот мой отчет:
1. Я использую ZSync для ежедневного резервного копирования
файлов doc и rtf на дискету (я занимаюсь набором рукописей),
дело в том что жесткий диск компьютера начал уменьшатся в
размере ежедневно (хозяин сказал, что это обычное
явление для старых дисков) - однажды я потерял весь свой труд.
2. По началу использования программы мне было сложно ее освоить,
я не сразу понял что есть что, но потом так привык к ней, что
немогу себе представить, что я буду без нее делать. Особенно
нравится мне выбор типов файлов для копирования.
3. Про vuBrief я ничего не знаю, потому что не имею личного
доступа к интернету, может быть она и подошла бы, кстати вашу
программу мне дали на диске, кажется "системные утилиты".
4. Компьютер: Pentium-90, 16 мегабайт оперативной памяти,
жесткий диск - 1 гигабайт, Windows 98.
Еще раз спасибо !
Шепелев Антон.
Это письмо я отправил через пару дней (у Антона же нет интернета - он ходит к другу, разумеется, не каждый день), да и отправлял через Web-интерфейс - новички обычно оттуда письма пишут.
На следующий день я получил такое замечательное письмо:
Уважаемый Антон,
Спасибо Вам за регистрацию ZSKSoft Synchronizer.
Файл с Вашим личным ключом регистрации (ZSync.key) находится во
вложении к этому письму. Помните, что лицензия на использование
ZSKSoft Synchronizer предоставлена лично Вам, передача кому либо или
публикация ключа влечет немедленное и автоматическое прекращение Вашей
лицензии.
Для регистрации программы выполните следующие шаги:
(предварительно ознакомьтесь с примечанием в конце письма)
1. Убедитесь, что у Вас установлена последняя версия. Для этого
запустите ZSKSoft Synchronizer и откройте окно "О программе" (пункт
меню "Помощь"/"О программе") - там должна быть строчка "Версия 1.21".
При необходимости скачайте и установите последнюю версию с
http://www.zsk****.com/rus/ZSyncSetup.zip. После установки запустите
ZSKSoft Synchronizer хотя бы один раз.
2. Откройте вложенный в письмо файл ZSync.key (наведите на него
указатель мыши и дважды щелкните, это можно сделать прямо в почтовой
программе). Если появится вопрос "Добавить в реестр информацию...?",
ответьте "Да". Вы увидите такое сообщение: "Данные из ZSync.key были
успешно внесены в реестр" либо "Information in ZSync.key has been
succesffully entered into the registry".
3. Запустите ZSKSoft Synchronizer, и Вы должны увидеть свое имя в
графе "Зарегистрировано:" в диалоговом окне "Помощь"/"О программе".
Если Вы потеряете файл ZSync.key и Вам понадобится переустановить
ZSKSoft Synchronizer - напишите в нашу службу технической поддержки
support@zsk****.com, и мы пришлем Вам ключ снова.
Как зарегистрированный пользователь Вы можете бесплатно скачивать все
обновления и новые версии программы с нашего сайта в течении 1 года с
момента регистрации. Если у Вас появятся затруднения в работе с
программой, мы всегда будем рады Вам помочь. Также мы с удовольствием
примем от Вас любые замечания, предложения и комментарии и постараемся
воплотить их в будущих версиях.
====================================================================
Это ключ должен без проблем подойти к Вашей версии ZSync (1.11).
Перенесите файл ZSync.key на свой компьютер и щелкните по нему в
проводнике Windows. Если что-то не получится - пишите, поможем.
Последняя версия (1.21) отличается от Вашей следующим:
- может сравнивать содержимое файлов, т.е. показывать, что именно
там изменилось. Это удобно для текстовых файлов, для doc и rtf
вряд ли пригодится, т.к. у них довольно-таки нечитабельный формат
- можно выбирать каталог в локальной сети
- можно проверять изменившиеся файлы не по дате/времени, а по
содержимому. Это бывает полезно, скажем, для обьектных файлов; а в
Вашем случае разве что замедлит работу с дискетой.
В общем, можете не беспокоится о том, что Ваша версия немного
устарела.
С уважением,
Сергей Зырянов
http://www.zsk****.com/rus
support@zsk****.com
Скажу на всякий случай, что программа была защищена ASProtect'ом, то есть я получил ключ, который никогда не смог бы в точности сгенерировать самостоятельно, отсюда вывод: "Никакой ASProtect не поможет против ..." - окончание фразы будет выглядеть, как вам больше нравится.
Ладно, перейдем к:
Александр Самсонов, который является автором этой программы, не ответил на мое письмо, тому можно найти много объяснений, наиболее вероятное: Он один из строителей русского shareware, что может говорить об одном из следующего:
- ему наплевать на всяких пацанов без денег;
- у него слишком много почты и ее обрабатывает некто со строгими инструкциями;
- он подумал: "может мне крэкер писал ?"
- либо он подумал: "обойдется этот парень и без моей игрушки".
Кстати, если Александр Самсонов читает эту статью может он сам мне скажет, что он подумал, хотя вряд ли он будет помогать какому-то там крэкеру.
Автор этой программы очень оперативно отвечает на почту, видимо он ярый интернетчик и неплохой специалист, что подтверждается использованием в защите программы протектора Armadillo, но меня этой сильно бесит в связи с несовместимостью Armadillo с SoftIce'ом.
Вот что он мне ответил на мое первое письмо:
Здравствуйте,
Большое спасибо за письмо, я рад что вам понравилась наша программа. Сейчас
доступна версия 2.6 которая имеет более удобный интерфейс, больше функций и
меньше ошибок. Скачать ее можно отсюда:
http://www.*****software.com/pc2pcpro.zip ~2.5Mb.
Для России у нас есть специальные цены, например Pic2Pic Pro стоит всего 200
рублей, купить ее можно здесь
http://www.shareg.com/req.php3?prodid=****&referer=29574 (страница с
информацией об оплате - http://www.shareg.net/clientfaq.php3). Мы конечно
можем выслать вам регистрационный ключ бесплатно, но мне кажется что 200
рублей не большие деньги за такую программу. Вы как считаете?
С уважением,
Леонид Паршуков
support@*****software.com
http://www.*****software.com
Надо сказать тут более легко и просто все получается, нежели в первом случае, но, похоже, автор не очень проникся положением Шепелева Антона. В ответ я черканул ему такое письмо:
Здраствуйте, Леонид.
Огромное спасибо, что вы ответили. Сейчас хотел загрузить версию 2.6, но друг мне
не разрешил, сказав, что это долго.
Я считаю, что WaveL Pic2Pic Pro достойна своей цены и даже большего, но такие
деньги я смогу получить может быть только на день рождения, в октябре, я знал,
что цена программы 200 рублей, пиша первое письмо поэтому и обратился к вам.
Буду очень вам благодарен, если вы сможете выслать регистрационый ключ.
Спасибо!
Шепелев Антон.
А вот и долгожданное письмо:
Здравствуйте,
Хорошо, можете использовать эту регистрационную информацию:
Name - Shepelev Anton
Key - ****-F884-****-CAB4-355C-32CD-530C-58CC-ABC2
Помните, что это конфиденциальная информация, пожалуйста, не распространяйте
ее.
С уважением,
Леонид Паршуков
support@*****software.com
http://www.*****software.com
Все бы хорошо, но не было у меня версии 1.7, а скачав 2.6 я убедился, что ключ к ней не подходит, ладно, может погляжу ее потом. Кстати **** в ключе это я написал, потому как распространение серийных номеров в цели этой статьи не входит.
На страницах download.ru автор называет себя, как: Victor Sazhin VCW, "что-то очень похоже это на имя крэкера/хакера" - подумал я тогда, особенно это загадочное "VCW". Короче говоря, ответа от него я не получил.
Здесь все прошло гораздо проще:
Здравствуйте, Антон
Присылайте регистрационное имя для первого варианта регистрации, см. меню
Помощь\Зарегистрировать
С уважением, Владислав, icq #125695458
Радиотехника, Схемотехника, Электроника - http://*****am.nm.ru
QuickPic SchemCreator 3.4.x - редактор электрических схем.
Пришлось, однако, скачать, чтобы регистрационное имя узнать.
Здраствуйте, Владислав Николаевич.
Еще раз огромное спасибо, вот регистрационое имя:
8080-0A6C
Шепелев Антон.
Вот и наш серийник:
Здравствуйте Антон и Олег !
Вот регистрационные данные, вводите их аккуратно, иначе программа будут работать
некорректно, и придется разрегистрировать программу (там же , в менню Помощь) и
снова вводить:
8080-0A6C
10575921062********
Удачи !
С уважением, Владислав, icq #125695458
Радиотехника, Схемотехника, Электроника - http://*****am.nm.ru
QuickPic SchemCreator 3.4.x - редактор электрических схем.
На мой взгляд, автор так "кидается" серийниками, только из-за "хитрой" регистрации программы - она использует привязку к жесткому диску (будто мы не умеем писать кейгены). Серийник подошёл и я теперь могу "наслаждаться" этой программой, хотя вряд ли буду.
3 из 5 программ были зарегистрированы, все отозвавшиеся авторы прислали ключи, потребовалось порядка 4 дней на взлом, но он прошел без особых усилий (обычно за 4 дня я не наламываю 3 программы).
А теперь сломайте этим способом все ваши любимые программы и не забудьте выложить "крэки" в интернет - надо юзверям помогать !
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Автор статьи: Bad_guy.
Мои свежие статьи и еще 100 статей других авторов можно найти на CRACKL@B: http://cracklab.narod.ru/
Связаться со мной можно по e-mail: bad_guy@mailru.com, но я не делаю крэки по заказу и не высылаю крэки и серийные номера!
Любые отзывы приветствуются !
Эта статья может свободно использоваться на любых сайтах, при условии полного сохранения содержания статьи, включая это предложение.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy
Статья создана: 29.01.03
Не секрет, что операционная систем Windows любой версии не ценится профессионалами с точки зрения защищенности данных. Отчасти это обусловлено созданием всяческих кэш-файлов, о которых сегодня пойдет речь.
Поскольку эта статья пишется для сайта CRACKLAB.narod.ru, хочу предупредить читателя, что данная статья не относится к крэкерству, а относится к безопасности и защите информации, поэтому вам не обязательно быть крэкером, чтоб понять её.
Для начала постараюсь определить, что же такое кэш. Кэш - это некие данные сохраненные на вашем диске операционной системой без вашего ведома и желания, так или иначе отражающие ваши воздействия на компьютерную систему.
Не всегда желательно оставлять какие-либо сведения о своих действиях на носителях данных, поэтому здесь я решил рассказать о некоторых кэш-массивах и о том, как их очищать, тем самым не только удаляя шпионскую информацию, но и освобождая место на накопителе.
Начнем с простейшего кэш-места Windows, папки Temp, которая находится в папке Windows, в этой папке сохраняются временные файлы пользовательских программ (особенно архиваторов, программ инсталляции). Как показывает практика, если закрыть все выполняющиеся программы (видимого режима), то все данные из папки Temp можно удалить. Готов поспорить, что если вы никогда до этого не удаляли файлы из Temp - размер этой папки у вас сейчас порядка 25-100 МБайт - удалите их.
Отдельный разговор по поводу кэш-данных в системном реестре, украв файлы реестра (user.dat и system.dat из папки windows) злоумышленник может получить доступ к вашей электронной почте. Если вы не хотите этого, то надо стереть реестр - нет, конечно, я шучу - его стирать нельзя, но пароли можно оттуда удалить. Простейший способ это сделать - не сохранять пароли ящиков в Outlook Express, я могу понять, что это не удобно, но решайте сами, что вам дороже время или безопасность. Для себя я решил так: Outlook Express у меня содержит более 8 учетных записей, поэтому пароли я решил доверить реестру.
Взглянем теперь на кэш паролей dialup доступа и некоторых интернет сайтов. Зайдите в папку Windows и нажмите F3, в строке поиска введите: *.pwl, найдется один или несколько pwl файлов - в них в зашифрованном виде содержатся эти пароли, если у вас нет принципиальных соображений не стирать эти файлы, сотрите их, теперь вам придется при подключении к интернету вводить пароль доступа - НЕ ставьте галочку "сохранить пароль", однако это не всё - продолжайте следить, чтобы со временем pwl файлы не росли в размере (в байтах), дело в том, что сейчас появилась свежая идея обманывать "хитрого юзера" который не ставит галочку "сохранить пароль" - это можно достичь пропатчив должным образом файл rasapi32.dll, после чего пароли не просто будут записываться в pwl-кэш, но и в незашифрованном виде. Однако спешу вас успокоить - этот файл невозможно перезаписать в windows - он недоступен, однако в режиме dos это возможно. Хочу дать вам один дополнительный совет по поводу сохранности паролей: никогда не открывайте файлы bat,exe,scr,com, пришедшие по электронной почте даже от знакомых (это может быть подделкой) они могут содержать вирусы или даже новейшие вирусы, которые ещё не занесены в базу AVP, кроме того, если вирус делается на 10-100 пользователей, то не исключено, что он вообще никогда не попадёт в AVP и прочие антивирусные базы. Dialup пароли я запоминаю - ведь нет ничего страшного в том, чтобы заставить себя запомнить 8-15 символов (у меня на это уходит примерно 30 секунд), чтобы пользоваться ими потом в течение месяца, если для вас это сложно, то можно приклеить бумажку с паролем к монитору, но это только дома.
Если вы используете броузер Internet Explorer (а его используют более 90% пользователей интернет), то можете увидеть, что адреса сайтов, посещаемых вами сохраняются в выпадающем списке адресной строки, а если вы работаете на компьютере не монопольно, то возможно, не стоит оставлять после себя эту информацию. Сейчас я углублюсь в вопрос очистки кэш-структур Internet Explorera, именно этими знаниями хотел поделиться, садясь за эту статью. Начнем с реестра: существует раздел HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs в котором сохраняются набранные вами с клавиатуры адреса сайтов (страниц) - их можно удалить без сожаления, перейдем к файловым кэш-структурам и самой главной хочу выделить папку: Windows\Temporary Internet Files - ее содержимое можно использовать во благо, а можно и во вред. Во благо я использую ее так: есть программы просмотра кэша IE у меня это CacheX 2.03 - частенько сайты содержат объемные описания правил или вообще статьи, на прочтение которых в online жалко денег, обычно эти страницы сохраняются в кэш и их можно легко посмотреть позже с помощью CacheX, отключившись от сети. Соответственно, если вы заходите на какие-то не совсем обычные сайты (например, тот же Webmoney Keeper) не желательно, чтобы ваш сменщик подглядел за вашими "делами" просмотрев кэш из Temporary Internet Files, поэтому я люблю удалять этот кэш, но он полностью (вместе с посещенными адресами в той же адресной строке) удаляется из Dos, перезагружаемся в MS-DOS и стираем всё содержимое папки Temporary Internet Files, особенно важно стереть index.dat из вложенных папок - в нем все связи, но не спешите загружаться в windows после этого, еще нужно стереть все из папки windows\history - в ней по дням в течение недели записаны все посещенные html файлы, а теперь давайте-ка удалим еще и все кукисы из папки Windows\cookies, чтобы стать "новыми" посетителями для "любимых" сайтов, после этого со спокойной душой можно работать в windows с отключенным антивирусом, хотя я раз в три месяца проверить диски антивирусом не помешает.
Я выражаю вам свою благодарность за то, что вы прочитали эту статью. Если вы знаете еще какие-то "опасные" кэш-записи, свяжитесь со мной bad_guy@mailru.com, я уверен, что эту статью еще можно неограниченно расширить, ведь программисты Microsoft оставили нам море возможностей для этого.
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: Fess | Дата: 12.05.2002 | Тьютор: 6 |
-+-+-+-+-+-+-+-+-+-+ For education uses only +-+-+-+-+-+-+-+-+-+-
Target: Audio MP3 Maker 1.12
Tools: Some brains
TRW 2000 (Soft-Ice)
Win32Dasm 8.93
Любой hex-редактор (я использую QView)
Вступление
Как это начиналось:
Взял я компакт Hard&Soft от 04.2002 глубокомысленно изучив список
еще не взломанных прог остановился на этой. Такие программы как правило
не сильно защищены и сломать их не сложно.
Что за прога:
Да обычная грабилка с CD в MP3 таких сейчас навалом. Конечно красивый
интерфейс и прочее. Может в ней и есть, что-то полезное, но я выбрал ее
прото так. Занимает все это хозяйство в установочном архиве 1.2 Мб.
Примечание:
Господа крякеры. Кто считает себя мастером крякером или на самом деле
является таковым не читайте эту статью. Да бы не выблевать только что съе-
деный ужин. Статья написана для начинающих и в ней подробно разжевывается
весь этап от взлома программы, до написания кейгена используя эту программу.
Начало
Итак приступим. Я не перестаю повторять: любой взлом начинается с
определения типа защиты программы. Я выделяю 3 таких типа это имя-код,
код, ключ-файл (отсортированы в порядке встречаемости в природе). Так же
можно выделить демо, но такие программы (если программист не последний
лопух) взлому не поддаются.
Что мы видим при запуске программы: за эту прогу просят 29.95 зеленых
портретов американского президента. Почему не 30? Потому, что так решили
менеджеры компании. Ну да мы все равно ни за что платить сегодня не будем.
Продолжаем. На появившемся диалоге три кнопки это "Buy Now", "Exit",
и "Try It". Жмем "Buy Now" типа щас хочу. А он лезет в Инет. Значит пароль
вводят не здесь. Жмет тогда "Try It", кнопка "Exit" не для нас, мы так
просто не сдаемся.
В появившемся окне замечаем кнопку Register. О, это для нас подходит.
Давим туда со всей силы. Вываливается окно с примерно таким текстом
Если бабки заплатил,
То и кодик получил,
Коли так пиши скорей
Не зевай, да не робей.
Ну мы, конечно, ничего не платили, но попробуем что-нибудь написать.
Авось проге понравится и скажет что зарегистрирована. Если у Вас это
получилось, то можете считать себя страшно везучим, комбинаций трилиарды.
Дальше читать статью Вам не имеет смылса пакуйте чемоданы и направляй-
тесь в Лас-Вегас. Если не угадали Вам написали Invalid reg code. Ну и
ладно. Можете погрозить компьютеру кулаком и обругать производителей этой
проги последними словами...
Успокоились? Тогда читайте дальше. Сегодня вашему вниманию будут пред-
ставлены сразу три способа взлома одной проги. Один легче другого, но я
для порядка их распределю так по сложности:
1) Патч (Patch)
2) Подсмотр кода
3) Кейген из этой же программы
1. Патч (Patch)
Этот способ произошел от слова Patch - что по научному значит: изме-
нять. Способ известен с давнишних времен, когда грамотные индейцы стирали
долотом лишние цыферки в ведомостях на каменных плитах, чтобы платить по
меньше налоги.
На мой взгляд это самый простой способ взлома. Обычно для взлома та-
ким способом хватает: чайной ложки мозгов, дизассемблера, hex-редактора.
Этот способ я познал сам не читая никаких тьюториалов, с моей помощью Вы
получите все знания необходимые для взлома прог этим способом.
Недостаток данного метода в том, что для каждой последующей версии
этой программы придется заново ее ломать, а если они выходят чуть ли не
каждый божий день. Хотя для сиюминутной потребности в самый раз.
Приступаем берем дизассемблер Win32Dasm и дизасмим exe-файл программы
с названием amm.exe. Все завершилось хорошо, значит он не запакован exe-
паковщиком. Это радует, так как проблем намного меньше.
Далее идем в секцию строк (кнопка "Strn Ref" или в меню "Refs\String
Data References). Там и ищем нашу строку. Какую? Я напомню: Invalid reg
code. Когда найдете два раза кликните на нее, и попадете в такой участок
кода. Я пронумерую строки, а самые основные выделю цветом.
1) :0040D83F 8B1B mov ebx, dword ptr [ebx]
2) :0040D841 8B4DE8 mov ecx, dword ptr [ebp-18]
3) :0040D844 53 push ebx
4) :0040D845 51 push ecx
5) :0040D846 E8AE9E0000 call 004176F9
6) :0040D84B 83C408 add esp, 00000008
7) :0040D84E 85C0 test eax, eax
8) :0040D850 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Message"
|
9) :0040D852 68C47B4400 push 00447BC4
10):0040D857 7518 jne 0040D871
* Possible StringData Ref from Data Obj ->"Thank you, please restart programs"
|
11):0040D859 68EC7D4400 push 00447DEC
12):0040D85E 8BCE mov ecx, esi
13):0040D860 E889CE0100 call 0042A6EE
14):0040D865 8B16 mov edx, dword ptr [esi]
15):0040D867 8BCE mov ecx, esi
16):0040D869 FF92C4000000 call dword ptr [edx+000000C4]
17):0040D86F EB37 jmp 0040D8A8
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D857(C)
* Possible StringData Ref from Data Obj ->"Invalid reg code"
|
18):0040D871 68D87D4400 push 00447DD8
19):0040D876 8BCE mov ecx, esi
20):0040D878 E871CE0100 call 0042A6EE
21):0040D87D EB29 jmp 0040D8A8
Наша строка в 18, а чуть повыше строка 11 только с обратным сообще-
нием, о том, что программа зарегистрирована. Значит должна быть проверка
а после нее переход. Между строками 17 и 18 написан адрес откуда идет
переход на строку 18. Перейдя на указанную там строку оказываемся на
строке 10. Переход jne означает, что переход если не равно. Эта команда
одно и тоже, что и команда jnz (переход если не 0). Так что не удивляй-
тесь, если в своем hex-редакторе увидите jnz вместо jne поторяю это одно
и тоже. Смотрим чуть повыше и видим команду сравнения test eax,eax. Меня
(в бытность мою начинающим крякером) удивляло, как может осуществляться
сравнение строк этой командой. Эта команда, как оказалось вовсе и не
сравнивает строки, а устанавливает флаг нуля (флаг Z), который может
принимать два значения 1 или 0. Если 1 переход осуществляется у команды
je (jz), если равно (если ноль). Если же 0 переход осуществляется у
команд jne (jnz), которые мы рассматривали. Сравнение же идет в процеду-
ре перед этой командой, которая возвращает в eax 0, если строки не равны
и 1 в противном случае. test аналогична команде and с тем условием, что
and изменяет сами регистры, а test флаг нуля. У команды test eax,eax
флаг нуля будет выставляться в том случае, когда eax<>0.
У Вас может возникнуть вопрос, что же сравнивает команда call стоя-
щая по номером 5. Это может быть правильный код и наш введенный код
(обчно так и бывает) или сгенерированные контрольные суммы у нашего кода
и нашего имени. Самый простой способ это узнать используя отладчик. Но
нас это пока не интересует.
Первое, что приходит на ум изменить jne на обратный переход je. Это
самое простое, но увы, не всегда верное. Обращение к процедуре сравнения
может идти из разных частей программы. В итоге выполучите, то что прога
напишет вам, что вы зарегистрированы. Но при перезапуске программы все
повторится снова. Можно, конечно, найти все вызовы этой функции и после
них переправить все переходы. Мы же применим другой метод, т.е. в самой
процедуре сравнения сделаем так, чтобы она всегда возвращала 1, т.е. что
сравниваемые строки всегда равны.
Делаем следующее заходим в процедуру, это можно сделать, поставив
курсор на процедуру (у нас это номер 5) и нажав кнопку call. Вернуться
обратно можно с помощью кнопки ret. После того как мы туда зайдем, по-
смотрим чуть повыше, откуда же вызывается эта функция? Ооо.. много. Вот
поэтому менять переход после процедуры не хорошо. Можно сделать просто,
а можно наверняка.
Сразу после входа в процедуру ставим команду ret, т.е. выход из
процедуры, эффект основан на том, что при входе в процедуру eax не будет
равно 0. Вероятность этого 98,2%.
Сразу после входа в процедуру пишем такие команды.
xor eax,eax
inc eax
ret
Как это сделать. Я буду описывать как это сделать с помощью QView, в
принципе его использование аналогично использованию Hiew, так что я ду-
маю это сработает и для него.
Приступим.
1) Записываем байты, с которых начинается процедура, обычно достаточно 9
главное, чтобы такой кусок кода встречался в программе один единствен-
ный раз. У нас это: 55 8B EC 83 3D 3C C8 4400005356.
2) Закрываем Win32Dasm, т.к. Windows производит разделение доступа к фай-
лам, и если вы его не закроете, то не сможете в него записать. Рекомендую
так же перед этим сохранить проэкт файла, т.к. в случае чего его открыть
будет намного быстрей, чем еще раз дизассемблировать.
3) Копируем файл qview.exe в каталог с программой.
4) Создаем резервную копию изменяемого файла.
5) Пишем команду qview.exe <имя-изменяемого-файла>
У нас будет такая команда: qview.exe amm.exe.
6) Два раза нажимаем F4, чтобы перейти к ассемблерному коду.
7) Один раз нажимаем F2, чтобы перейти к 32-битному режиму.
8) Нажимаем F7 и вписываем в hex-поиск предварительно записанные байтики.
Жмем Enter.
9) Нажимаем Shift-F7 для повтора поиска, если больше совпадений нет, то
начинаем изменять, иначе выписываем еще несколько байтов и повторяем поиск
10) Нашлась одна, теперь нажимаем Tab и начинаем писать команды.
У нас строка нашлась на 176F9. Пишем написанные выше команды, после каждой
нажимаем Enter.
11) Нажимаем Esc. И в ответ на предложение сохраниться нажимаем "W".
Запускаем программу, выскакивает сообщение об ошибке. Черт, значит мы
ошиблись это просто процедура сравнения строк и она используется, не толь-
ко для сравнения пароля. Как же нам быть? Я думаю так: посмотрим еще раз
на участок кода с 3 по 10. Значит так в стек заносятся параметры ebx и ecx
что-то подобное вероянее всего будет и при следующих проверках. Нажимаем
поиск и вводим call 004176F9. Ищем до того момента, когда командой
push в стек будут заносится регистры общего назначения (оканчивающиеся на
..x ). Ищем пока не натыкаемся на следующий участок кода.
:00404FD0 8B4DE4 mov ecx, dword ptr [ebp-1C]
:00404FD3 8B55DC mov edx, dword ptr [ebp-24]
:00404FD6 51 push ecx
:00404FD7 52 push edx
:00404FD8 E81C270100 call 004176F9
:00404FDD 83C408 add esp, 00000008
:00404FE0 8D4DDC lea ecx, dword ptr [ebp-24]
:00404FE3 85C0 test eax, eax
:00404FE5 0F94C0 sete al
:00404FE8 25FF000000 and eax, 000000FF
:00404FED 885DFC mov byte ptr [ebp-04], bl
Больше таких участков не встречается, значит проверка одна. Что нам это
дает? Значит изменив переход здесь мы получим полноценный вариант програм-
мы. Перед повторным изменением, не забудьте восстановить из копии рабочий
вариант программы. "А где же здесь переход?" - спросите Вы. А я Вам отвечу
нету его здесь. Здесь переход заменен на команду sete al, она устанавлива-
ет al=1, если результат последней проверки истина. Последней проверкой и
будет наше сравнение. Сделаем так, чтобы в al всегда была 1. Делается это
элементарно. Мы видим, что команда sete al занимает 3 байта это 0F94C0. А
команды
xor eax,eax - 31C0
inc eax 40
Тоже ровно 3 байта получается полноценный замен. Раз все получается, за-
меняем! Надеюсь Вас не надо учить пользоваться hex-редактором?
Запускаем программу и что же мы видим?.. Nag-screen пропал, все работает
просто отлично. Покажем всем друзьям какой Вы КулХацкер. И начнем дальней-
шее обучение по методу дядюшки Fess'a.
2. Подсмотр кода
Подсмотр кода. Этот метод появился на заре цивилизации с появлением
рыбаков, которые, если у другого ловится, а у них нет начинают вынюхивать,
почему так происходит. Подсмотрев за другим рыбаком, они используют его
методу и у них тоже начинает клевать. К сожалению, рыбаки народ особый и
не очень-то любит расставаться со своими секретами, поэтому приходится
прибегать к хитрым средствам,таким как: дерево, заросли и самое надежное -
бутылка водки.
У нас этой бутылкой станет отладчик TRW 2000. Можно было бы использо-
вать и старый проверенный Soft-Ice. Но мне было в лом перезагружаться, де-
лов то, на 5 секунд. Я немного ошибся, надо было этот способ сделать пер-
вым по простоте, ну уж ладно.
Помните, что я Вам говорил в 1 части про патч, показывая вот этот кусок
кода. После выполнения команд 1 и 2 в регистрах ebx и ecx находятся две
строки. А что за строки предстоит узнать Вам вооружившись отладчиком.
!!!! Не забудьте восстановить файл из резервной копии, проверять, то надо
на настоящем файле.
1) :0040D83F 8B1B mov ebx, dword ptr [ebx]
2) :0040D841 8B4DE8 mov ecx, dword ptr [ebp-18]
3) :0040D844 53 push ebx
4) :0040D845 51 push ecx
5) :0040D846 E8AE9E0000 call 004176F9
6) :0040D84B 83C408 add esp, 00000008
Вообщем, грузим файл в TRW 2000. Нажимаем Load и вываливаемся в точке
входа в файл. Что за точка и по какому адресу нас не колышет и мы с усерди-
ем на лице ставим бряк на адрес 40D844 командой bpx 40D844. Т.е. сразу пос-
ле того как адреса окажутся в ebx и ecx. Запускаем программу (кнопка F5).
Идем в до боли знакомый пункт регистрации набираем свое имя и любой пароль.
Я обычно набираю Name: Fess, Code: 110022334455. (такую строку искать в па-
мяти легко). Жмем кнопку ЗАРЕГИТЬ МЕНЯ КАК СВЯТОГО КОНЯ и вываливаемся в
окно TRW. Как раз на команде под номером 3. Теперь можно посмотреть, а что
у нас в памяти по этим адресам. Пишем команду d ebx и видим в окне данных
введенный Вами код. А что по другому адресу? Набираем команду: d ecx и в
окне данных видим преинтереснейшее число. И тут из глубины души зараждается
мысль, что это и есть тот самый настоящий код. Хватаем ручку и быстро чер-
каем на любом огрызке бумаги этот код. Посмотрели какой он длинный можете
подсчитать каким везением надо обладать, чтобы угадать ТАКОЕ! Теперь вводим
подсмотренный нами код. И программа в агонии от радости, что вы ее купили.
Хе-хе-хе как бы не так. Просто не правда ли?
Таких программ становится все больше. Начинающим крякерам это очень нра-
вится теперь можно перед всеми хвастаться настоящим реальным кодом да еще
на свое имя, а если еще распечатать регистрационную анкету. То вообще все
поверят, что вы ее купили.
3. Кейген из этой же программы
Кейген нетакое давнее изобретение годов 40-х когда стали распространяться
машинки для шифрования. И чтобы расшифровать, надо было сбацать такую же
машинку. Написание настоящего кейгена, как и создание машинки вещь почти
всегда кропотливая и рассчетливая. Надо же догадаться как считается код и
написать такой же генератор. Наша же задача другая создание кейгена на ос-
нове имеющийся программы. У меня уже был тьюториал посвященный этой теме
с названием 'Взлом программ это просто - "Электронная кулинарная книга"'.
Кто захочет почитает.
Создать кейген на основе имеющейся программы достаточно просто, если в
ней заложен принцип сравнения правильного и неправильного кода. Этот метод
является совокупностью первого и второго. Еще раз взглянем на этот отрывок:
3) :0040D844 53 push ebx
4) :0040D845 51 push ecx
5) :0040D846 E8AE9E0000 call 004176F9
6) :0040D84B 83C408 add esp, 00000008
7) :0040D84E 85C0 test eax, eax
8) :0040D850 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Message"
|
9) :0040D852 68C47B4400 push 00447BC4
10):0040D857 7518 jne 0040D871
Чем является в данном контексте слово "Message". Оно является заголовком
окна при правильной и неправильной регистрации. Так? Так вот, а что если
нам слово "Message" заменить правильным регистрационным кодом. Каково, а?
Делается это просто элементарно просто. Надо Push " Message" заменить на
Push правильный регистрационный номер. Т.е. push 00447BC4 на push ebx. Пос-
кольку push на эту строку единственный, то строка его индитификационных
байтов единственная. Посмотрим ищем hex строку 68C47B4400. А нет, не едист-
венная, их две. Добавим еще один байт 75, теперь одна. Теперь ее надо заме-
нить на строку push ebx, а его код 53 остается 4 лишних байта. Для того,
чтобы программа могла нормально работать, их надо забить nop'ами, т.е. пу-
стыми операторами. Код у nop'a 90. Т.е. надо заменить строку 68C47B4400 на
5390909090. Теперь даже если Вы напишите неправильный код программа выдаст
вам правильный в заголовке.
Она выводит Ваш пароль вместо нормального? Так и есть это я недосмотрел.
Просто после выполнения процедуры ecx и ebx приравниваются, а пароль нахо-
дится в edx. Так что вместо 53, надо написать 52 и все заработает. Надеюсь.
К сведению, удалить информацию о предыдущей регистрации можно, удалив
файл keyinfo.key из каталога программы
Теперь вы можете показать всем какой вы Хацкер, снабдив их все кодами со
своими именами.
Так же можите поробовать записать вместо текста "Invalid reg code" тоже
этот же пароль. Это будет Вашим домашним заданием. Сделав которое, Вы пой-
мете, что нет на свете вещи интересней, чем ломание прог.
Послесловие
Хочу выразить огромную благодарность авторам за предоставленный продукт,
побольше бы таких продуктов и их программы, вообще, перестали бы покупать.
Люди читающие эту статью! Мир не без добрых людей, если Вам понравилась
эта программа купите ее, поддержите финансами развивающуюся отрасль.
Программистам компании! Ну что Вы в самом деле, защитить свою продукцию
нормально не можете. Сравнение настоящего кода с введенным это примитив,
который был в моде лет восемь назад. Сейчас крякеры выделяют такие програм-
мы в категорию: худшая защита месяца.
"Кряк это отражение морали и духа крэкера в единице письменного,
ибо иначе это сводит на нет его усилия." (Fess)
Автор: Fess
Все ругательства отправлять в null
Все остальное на lomovskih@yandex.ru
Удачи в Reversing Engeneering!
P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!
P.P.S. Возможно имеют место опечатки, заранее извините!
With best wishes Fess
И да пребудет с вами великий дух bad-сектора.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: Fess | Дата: 31.05.2002 | Тьютор: 10 |
-+-+-+-+-+-+-+-+-+-+ For education uses only +-+-+-+-+-+-+-+-+-+-
Вступление
Наконец, я решился на написание этой статьи, идея пришла давно, но
полностью систематизировать решился только сегодня. Сегодня мы не будем
рассматривать конкретного взлома. На это есть две причины:
1) У меня начал глючить CD-ROM, пора менять
2) Статья получилась бы слишком длинной
В принципе вторая причина меня волнует мало, но первая встала доста-
точно остро.
Хотя сдесь и будет в основном теоретический материал, о способах за-
щиты от копирования с CD и методах устранения такой нехорошести, но я
буду приводить и примеры игр, к сожалению, многое ломается на ходу и не
обременяешь себя запоминанием, поэтому примеры игры в основном одни и
те же.
Принципы и методы защиты
Сейчас я постараюсь написать все, когда либо встреченные методы за-
щиты:
5) Проверка на наличие файла и его аттрибуты
1) Проверка на наличие диска
Я разделяю эти проверки на два класса:
1) Функцией GetDriveTypeA
Теория: Функция GetDriveTypeA возвращает в eax тип диска по его имени
Вот список возвращаемых значений.
0 -- - Невозможно определить тип
1 -- - Диск не найден
2 DRIVE_REMOVABLE - Гибкий (возможна замена)
3 DRIVE_FIXED - Жесткий (замена невозможна)
4 DRIVE_REMOTE - Сетевой диск
5 DRIVE_CDROM - CD-ROM
6 DRIVE_RAMDISK - RAM - Диск
Как часто встречается:
Такая проверка стоит на абсолютном большинстве ИГР.
Методы взлома:
1) Используя Soft-Ice/TRW2000 поставить бряк на эту функцию командой
bpx GetDriveTypeA и если после выхода в вызывающую программу, недалеко
стоит cmp eax, 00000005, то следует 5 исправить на 3, т.е. программа будет
искать не CD-ROM, а жесткий диск.
2) Дизассемблировать перейти к месту вызова функции, посмотреть, есть ли
сравнение. Это несколько модернизированный вариант пункта 1.
3) На эту идею я натолкнулся в статье Vadim M. "Как отучить игры от про-
верки CD-ROM (на примере Hellfire)". Краткое описание: поскольку функция
GetDriveTypeA вызывается из kernel32.dll будем править там, смысл, чтобы
все жесткие диски в системе были бы как CD-ROM'ы, этого легко достичь пере-
правив результат возвращаеммый функцией с 3 на 5, правдо это не всегда про-
ходит. Эту статью можно увидеть на www.reversing.net
Примеры игр:
Project IGI, Deadly Dozen, and many others
2) Запись имя диска в реестр или файл
Как часто встречается:
Достаточно часто
Метод взлома:
Я использую такой метод, т.к. программа где-то сохранила имя CD-ROM'a,
значит, если мы изменим имя, то программа откажется запускаться, даже если
диск будет торчать в CDюке. Изменяем имя и если запускаться перестанет, то
ищем с помощью RegMon и FileMon, куда программа его запрятала.
Примеры игр:
Shockman (Шокмэн), записывала в файл WINDOWS\facked.ini
2) Проверка на метку тома
Теория: Метка тома проверяется с помощи функции GetVolumeInformation,
если эта функция вызывается, то почти однозначный вывод проверка метки
тома. Функция очень часто используется с категорией 1.
Как часто встречается:
Очень часто
Методы взлома:
1) Используя Soft-Ice/TRW2000 поставить бряк на эту функцию командой
bpx GetVolumeInformation. После этой процедуры скорее всего идет
процедура сравнения правильной метки с вашей. После процедуры переправить
переход.
2) Дизассемблировать перейти к месту вызова функции, посмотреть, есть ли
сравнение и т.д.. Это несколько модернизированный вариант пункта 1.
3) Если категорию 1 вы уже правили. Посмотреть метку тома на компакт-ди-
ске, и установить такую же на любом жестком диске.
4) Если категорию 1 не правили. Берем любой свой компакт с длинной метки
тома меньшей, либо равной длинне метки на ломаемом компакте. Ищем в испол-
няемых файлах программы, настоящую метку и заменяем ее нашей. Вывод если
Вы вставляете свой компакт, игра думает, что это ее родной.
Примеры игр:
Deadly Dozen
3) Проверка на наличие места
Теория: Наличие свободного места на диске проверяется функцией
GetDiskFreeSpace. Функция вызывается для того, чтобы проверить
что это за диск, ведь на CD свободного места нет.
Как часто встречается:
Бывает
Методы взлома:
Аналогичны методам 1 и 2 из 1 и 2 категории, только на другую функцию.
Примеры игр:
Была какая-то, но не помню названия.
4) Проверка на наличие файла и его аттрибуты
Теория: Один из распространившихся в последнее время приемчиков,
часто это используется для проверки видео. Которое не копируется на ЖД.
В основном используются такие функции:
GetFileAttributesA - Проверка аттрибутов файла
ReadFile - Чтение файла
GetFileSize - Получение размера файла
FindFirstFile - Поиск файла.
Как часто встречается:
Иногда
Метод взлома:
Я использую такой метод, запускаем FileMon. Затем запускаем игру, со
вставленным компактом. Потом сразу же выходим и смотрим, к каким файлам
шло обращение. Если файлы не большие можно скопировать их на ЖД, если есть
большие видео, то их можно заменить любыми другими видаками маленького
размера. В других случая придется править переходы. Если используются все
эти функции придется попотеть.
Примеры игр:
Project IGI, в этой игре были два файла по 1 байту, я их скопировал на
диск C: в корневой, изменил после GetDriveTypeA сравнение и все.
5) Проверка на запись файла
Теория: Для этого используются функции WriteFile и GetLastError.
Одна для записи файла другая для проверки ошибки, если они стоят подряд, то
это явно она.
Как часто встречается:
Ни разу не встречал
Метод взлома:
Чуть-чуть исправленный метод из предыдущей категории.
Примеры игр:
Я же сказал: "Не встречал!"
6) Другие виды проверки
Теория: Бывают и другие сильно замусоленные проверки
Как часто встречается:
На дисках компании "Русобит"
Метод взлома:
Почитайте статьи ASMax'a на www.reversing.net.
Примеры игр:
Казаки, Star Force.
7) Некоторые общие моменты
Часто в играх проверки объединены в одну общую процедуру. И удалив ее,
программа начинает работать.
Практически всегда программа защищена совокупностью защит, которые здесь
представлены в разных категориях.
Автор: Fess
Статья не претендует на всеобщность, поэтому я не могу предугадать
ходы разработчиков. Статья открыта для дополнения, если у Вас есть
какие нибудь ценные мысли по этому поводу, шлите на мыло.
Все ругательства отправлять в null
Все остальное на lomovskih@yandex.ru
Удачи в Reversing Engeneering!
P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!
P.P.S. Возможно имеют место опечатки, заранее извините!
With best wishes Fess
И да пребудет с вами великий дух bad-сектора.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: Fess | Дата: 7.07.2002 | Тьютор: 16 |
-+-+-+-+-+-+-+-+-+-+ For education uses only +-+-+-+-+-+-+-+-+-+-
Target: Crackers
Tools: Some brains
Зачем все это:
Приветствую Вас! В этой статье не будет описано конкретного взлома, здесь я попытаюсь рассказать "Зачем крэкеры ломают программы и чем это хорошо и чем плохо. Конечно, Вы можете не согласиться с моими размышлениями это Ваше право, я никого не заставляю думать так же как и я. Этой статьей я хочу Вас подтолкнуть к познанию искусства крэка и что за ним стоит. Именно ИСКУССТВА, а не просто мелочевки.
Хм.Хм.
Углубимся немножко в историю, лет так 15-20 назад. В те далекие времена на заре зарождения персональных компьютеров, крэкеров было мало, да они и не считали себя таковыми это были первоклассные спецы в программировании. Тогда еще не было хороших дизассемблеров, удобных отладчиков и прочего инструмента, без которого сейчас крэкера не представить, тогда все операции приходилось выполнять или на бумажке или в голове, а для этого просто небходим был математический склад ума. Тогда не было кучи тьториалов, по которым можно было набраться опыта, не было инета и е-мыла, чтобы узнать совет специалиста. Их было мало, но их возможности компенсировали этот недостаток...
Вернемвся в наши дни, сейчас при развитии техники, обилия программ и документации, любой, я повторюсь - ЛЮБОЙ может стать крэкером, для этого уже не нужно досканальное знание математики и архитектуры компьютера (хотя и не помешает) достаточно иметь компьютер, время, кучу статей по крэку и чуть-чуть логического мышления и вы, можно считать, уже без пяти минут крэкер.
Так вот перво наперво, давайте определимся, что же подталкивает человека к изучению искусства крэка. Первое, желание себя показать, что вот я рульный крэкер. Второе, заработать деньжат. Третье, испытать неизведанное. Вот три основных желания. Ну второй пункт, можно почти однозначно выкинуть - заработать на этом врядли удастся, хотя кто знает...
Тем временем, количество крэкеров увеличивается. Почему такое происходит? А по одной простой причине - чувство Победы. Радость. Счастье. Гармония души. Все Вы знаете, что значит выйграть в лотерею или победить в каком-либо соревновании, радость испытанная после этого. Чем выйгрыш больше или крупнее соревнования, тем сильнее радость. Например, выйгать на городских соревнованиях и на олимпийских играх не одно и тоже, так ведь? Здесь теже соревнования, соревнования крэкер-программист, кто кого? И чем сложней программа, чем трудней был взлом, тем сильнее это не с чем не сравнимое чувство ПОБЕДЫ.
Чем же это плохо? Хорошо и плохо понятия расплывчатые, как добро и зло. Но вот, что я скажу: тут, как всегда происходит из-за нескольких нерадивых, которые после взлома выкладывают патчи, кейгены, серийные номера в интернете, где их может найти любой и естественно воспользоватся ими. Вот, например, я Fess. Ну сломал я программу, воспользовался крэком, даже дал своим ближайшим друзьям, но и все, ущерб минимальный, а если я бы выкладывал их в инете или в FIDO, где их могли бы все найти, тем самым я бы нанес компании намного больший ущерб. Согласитесь. Что же еще, ну то, что программистам приходится трудится над защитой вместо того, чтобы улучшать свои продукты.
"И чем же это хорошо?" - Спросите Вы, - "Покамест ты называл только отрицательные стороны". Если есть плохое, значит есть и хорошее.
Как видите достаточно много причин, чтобы заниматься этим, и мало чтобы не заниматься. По мне, так это гораздо интересней, чем воевать и торговать (ширятся) наркотой. По этому спорту равно, как и искусству давно пора проводить соревнования.
Удачи в Reversing Engeneering!
Заниматься этим или нет, каждый решает сам, но отрицать полезность этого - это все равно, что плевать в колодец, из которого потом сам будешь пить.
Вредный совет
Если сканер Ваш планшетный
Не работает как надо,
А листочки уже завтра
Надо к вечеру сдавать -
Все прозрачные фигнюшки
Изолентою заклейте,
Пусть он гадина узнает,
Что такое слепота.
(Fess)
Автор: Fess
Все ругательства отправлять в null
Все остальное на lomovskih@yandex.ru
P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!
P.P.S. Возможно имеют место опечатки, заранее извините!
With best wishes Fess Member of the group PTDS
И да пребудет с вами великий дух bad-сектора.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
О защите: Полиморфный упаковщик, как обычно с антидебаговыми примочками, поганит импорт, секции в файле обзывает именами других упаковщиков. Вот так :(
Инструменты: Softice, IceDump, Imprec.
Как найти OEP: bpx GetModulehandleA, потом /tracex imagebase xxxxxx , где xxxxxx число примерно пониже базы распаковщика.
А вот с импортом не все так просто. Взяв Imprec будет сразу видно что 2 секции никак не востанавливаются. И элементы этих секций указывают на какие-то разные области памяти, даже не в области упаковщика. Если глянуть в эти области, то нас постигает огромный облом... Некоторые элементы указывают в пустые куски памяти (те что с ?? ?? ...), а остальные указывают на вызовы процедур из библиотек через полиморфные куски кода!!! Хана... Это ж даже не подизасмишь. Но выход есть! Берем к примеру первый не найденый элемент к примеру 5b140 ссылается на 700000. Смотрим на код по адресу 700000. Он имеет вид:
0167:00700000 JMP 00700005
0167:00700002 JMP EBX
0167:00700004 INVALID
0167:00700006 NOP
0167:00700007 PUSH ES
0167:00700008 JO 0070000A
0167:0070000A INC EAX
0167:0070000B PUSH DWORD PTR [EAX]
0167:0070000D RET
Делаем u 00700005 и видим:
0167:00700005 MOV EAX,00700690
0167:0070000A INC EAX
0167:0070000B PUSH DWORD PTR [EAX]
0167:0070000D RET
теперь делаем d 00700690+1 (+1 тошо inc eax).
Видим:
0167:00700691 D1 AB F8 BF A3 B9 F7 BF-7E B9 F7 BF 9F 42 F8 BF ........~....B..
0167:007006A1 B9 41 F8 BF E7 FF F7 BF-D4 49 F7 BF B8 48 F7 BF .A.......I...H..
0167:007006B1 D7 13 F8 BF 65 43 F7 BF-3C 43 F7 BF 1A 06 FA BF ....eC..<C......
0167:007006C1 A3 7D F7 BF 85 7D F7 BF-AD 73 F7 BF 36 73 F7 BF .}...}...s..6s..
0167:007006D1 ED 12 F9 BF 59 EA F9 BF-B1 77 F7 BF AC 6D F7 BF ....Y....w...m..
0167:007006E1 1A 77 F7 BF FB 76 F7 BF-B4 20 F8 BF E2 50 F8 BF .w...v... ...P..
0167:007006F1 AC C5 F8 BF A0 E0 F8 BF-5B 7B F7 BF C4 64 F7 BF ........[{...d..
0167:00700701 CA D4 F8 BF D5 6F F7 BF-DC D6 F9 BF 3F 71 F7 BF .....o......?q..
0167:00700711 A0 C3 F9 BF 5F 83 F8 BF-3D 70 F7 BF 83 06 FA BF ...._...=p......
0167:00700721 74 57 F7 BF B5 6F F7 BF-85 58 F7 BF DF 7A F7 BF tW...o...X...z..
0167:00700731 64 E0 F7 BF 00 00 00 00-00 00 00 00 00 00 00 00 d...............
Это кусок импорта! Теперь делаем хитрую вещь... /dump 700691 a4 c:\1.dmp
и /load 45b140 a4 c:\1.dmp
Я подменил кусок таблицы импорта на реальные адреса апи функций.
Прога на этот момент запущена. И прекрасно работает ничего не заметив. Так мы поборем полиморфные вызовы.
Остаются вызовы которые ведут в никуда. В никуда они вести не могут. Поэтому нужно просто глянуть на эти места когда EIP=OEP :)
И действительно! В момент когда прога тока собирается запустится, все наместе и можно дописать оставшиеся куски. Там тоже будут полиморфы.
Еще останется несколько вызовов процедур типа:
0167:00700338 MOV EAX,0046C48D
0167:0070033D NOP
0167:0070033E PUSH DWORD PTR [EAX]
0167:00700340 RET
Причем по адресу 46C48D или ноль идет или пустота...
Поэтому ячейки которые указывают на такие процедуры нужно просто отсекать (cut thunks).
Итак нужно просто остановить прогу на OEP скопировать правильные адреса в таблицу импорта, а потом дать проге запуститься и дальше уже в Imprec завершить "косметику" :)
Автор: Hex
E-mail: hex@xtin.org
Материалы находятся на сайте http://cracklab.narod.ru/doc/
1) Numega Softice fow WIN32
2) HVIEW
3) ProcDump
Как-то попался мне диск "Журнал Хакер" на котором было много шароварных прог.
(Что же это за "хакеры" которые издают диски с шароварными программами,
львиная доля которых откровенный отстой, ну да ладно...)
На диске была программа FontLister...
Итак, программа триальная, при старте огромный НАГ-скрин с надписью
Unregistered User а также в окне о программе записывается дата установки и
если дата установки далека от текущей, то... фигня дело вобщем :)
Будем кракать...
Запускаем программу при помощи SymbolLoader'a из пакета SoftIce, чтобы
оказаться в самом начале программы, мы окажемся здесь:
015F:004D4BF9 MOV EBP,ESP
015F:004D4BFB ADD ESP,-0C
015F:004D4BFE MOV EAX,004D4868
015F:004D4C03 CALL 00406460
015F:004D4C08 MOV EAX,[004D6778]
015F:004D4C0D MOV EAX,[EAX]
015F:004D4C0F MOV EDX,004D4CD8
015F:004D4C14 CALL 004502F8
015F:004D4C19 MOV EAX,[004D6778]
015F:004D4C1E MOV EAX,[EAX]
015F:004D4C20 ADD EAX,38
015F:004D4C23 MOV EDX,004D4CEC
015F:004D4C28 CALL 00403B58
015F:004D4C2D XOR EAX,EAX
015F:004D4C2F PUSH EBP
015F:004D4C30 PUSH 004D4CB6
015F:004D4C35 PUSH DWORD PTR FS:[EAX]
015F:004D4C38 MOV FS:[EAX],ESP
015F:004D4C3B CALL 004D474C
015F:004D4C40 TEST AL,AL
015F:004D4C42 JZ 004D4C78 <-- очень подозрительный условный переход
Попробуем поменять по адресу 015F:004D4C42 команду JZ 004D4C78 на JMP 004D4C78
и с удивлением обнаружим, что наг-окна при старте нет.
Теперь сделаем так, чтобы в меню "о программе" всегда высвечивалась
"правильная" дата инсталяции:
Запустим Regedit.exe и посмотрим к каким записям в реестре обращается наша
прога и находим очень интересный раздел:
HKEY_CURRENT_USER\Software\ConquerWare\FontLister\Registration\Date
в котором, очевидно, хранится дата инсталляции. А если убить эту запись?
Может прога подумает, что мы тока инстальнулись и запишет туда сегоднящную
дату? И правда, после того как я убил этот раздел, он был заново создан
прогой, но с текущей датой. (Очень глупо).
Но нам перед каждым запуском килять запись не очень удобно, поэтому тут два
варианта:
1) Искать в программе то место, где проверяется наличие ключа Date
2) Встроить в программу маленькую функцию, которая при запуске проги будет килять
разедел.
Я выбрал второй вариант, потому как это сложнее и интереснее, а как сказал
кто-то "Если это будет просто, то это того не стоит!". Приступми:
встраивать будем функцию RegDeleteKeyA, т.к. эта функция предназначена для
удаления записей реестра и она содержится в импорте нашей программы :)
Посмотрим на параметры, которые надо передавать этой функции:
LONG RegDeleteKeyA(
HKEY hKey, // handle of open key
LPCTSTR lpSubKey // address of name of subkey to delete
);
у нас параметры приймут вид:
hKey = HKEY_CURRENT_USER = 0x80000001
lpSubKey = "Software\ConquerWare\FontLister\Registration",0
Я предлагаю изменить OEP (Точка входа в программу) на начало нашей процедуры:
push offset lpSubKey
push 80000001h
call RegDeleteKeyA
jmp настоящая_точка_входа
Я нашел свободного места (под свободным местом понимаем кучу 20h) по адресу
004D50BF
Заглянув в таблицу импорта, я узнал, что фактическим вызовом
call RegDeleteKeyA
будет
call 000056DC
Также я узнал, что OEP = 004D4BF9, заменим его при помощи ProcDump или
вручную на адрес начала нашей процедуры (004D50BF)
и по адресу 004D50BF пишем в HVIEW такую процедуру:
.004D50BE: 90 nop
.004D50BF: 68D3504D00 push 0004D50D3 ;" MP+"
.004D50C4: 6801000080 push 080000001 ;"А "
.004D50C9: E80E14F3FF call RegDeleteKeyA ;advapi32.dll
.004D50CE: E925FBFFFF jmp .0004D4BF8 -------- (2)
и сразу за процедурой вписываем строку:
"Software\ConquerWare\FontLister\Registration",0
В HVIEW получим следующее:
.004D50D0: BD 32 00 53-6F 66 74 77-61 72 65 5C-43 6F 6E 71 +2 Software\Conq
.004D50E0: 75 65 72 57-61 72 65 5C-46 6F 6E 74-4C 69 73 74 uerWare\FontList
.004D50F0: 65 72 5C 52-65 67 69 73-74 72 61 74-69 6F 6E 00 er\Registration
Теперь меняем точку входа в программу на 004D50BE (что на единицу меньше,
чем адрес нашей процедуры, но так надо! Это тема не этой статьи).
И ... При старте программа сначала выполнила нашу небольшую процедурку, т.е.
убила раздел о регистрации и потом передала управление оригинальной программе,
которая создала раздел по-новой и записала туда сегоднящнюю дату.
Вау! Кульно.
Теперь осталось вместо строки "Unregistered User" вставить что-то типа
"cracked_by_vallkor". Делается это просто:
Заходим в HVIEW нажимаем F7 (поиск) ищем строку "Unregistered User" и
меняем на что угодно, только в конце новой строки не забывайте ставить
нулевой байт.
Крак делайте сами, поскоку слишком много изменений, а QVIEW не плюсюет
автоматом ImageBase :) На этом досвиданья.
Исследовал (и получил от этого удовольствие):
vallkor [PTDS]
E-mail : vallkor@chat.ru
Page : vallkor.chat.ru
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Бредисловие:
Вот и осмелился я наконец написать обзор часто задаваемых вопросов о
взломе программ. Многие вопросы здесь задавал себе как-то и я. Теперь
же изложу их ответы. Да, кстати, любые вопросы можно задать мне по
адресам: vallkor@ukr.net
vallkor@chat.ru
vallkor@etel.dn.ua
Приступим...
Q: Какие виды защиты используют программы и какие методы их взлома?
A: наиболее распространенный вид защиты - защита серийным номером,
т.е. по вашему имени или по специальному шаблону генерятся серийные
номера. Заполучить их просто с помощью любого дебагера (отладчика),
я рекомендую SoftIce. При этом важно "словить" событие, которое
происходит при неправильном вводе серийного номера. Как правило это
MessageBox - сообщение об ошибке, но если программа написана в Делфи
- то там messagebox не канает, т.к. "продвинутый" Делфи не использует
стандартное сообщение Windows.
Есть временная защита, т.е. программа работает 30 дней - тут совсем
всё просто, можно написать за 5 имнут программу, которая бы переводила
на секунду время назад, запускала нужную нам программу и возвращала
бы время назад;
Просто почитайте литературу по ломке программ.
Q: где взять такую литературу.
A: искать нужно литературу по защите программного обеспечения. На
рынках часто продают диски с названиями "Все для хакера" - там много
полезной инфы. Есть куча туториалов (пояснений) - т.е. описаний, как
нужно ломать ту или иную программу, я рекомендую регулярное издание
команды CiA - "tKC's tutorials". Просто введите в любом поисковике
заветные слова и куча инфы вам обеспечена. Совет (который мне тоже
кто-то советовал): "читайте всё подряд, даже если не понимаете -
потом будете знать, где искать". ЗЫ: www.reversing.net - русскоязычный
и класный.
Q: Какими инструментами пользуются кракеры?
A: Тут однозначно не ответишь. Ведь программ существует уйма и у каждого
свои вкусы. Могу лишь сказать свои вкусы:
- SoftIce (как отладчик (дебагер) )
- WinDASM (как декампилятор)
- Qview (как hex-редактор и дизассемблер)
- RegMon и FileMon (для просмотра обращений программы к внешним файлам
и системному реестру)
Q: Что такое декампилятор?
A: Это программа, которая из машинного кода программы получает исходный
код на ассемблере.
Q: А можно ли получить исходный текст на языке, на котором была написана
программа?
A: Если знать на каком языке написана прога (компилятор) то теоритически
можно, но практически ещё не видел.
Q: Какие программы для начала лучше поломать для тренировки?
A: Желательно самые самодельный, типа супердиалер или суперблокнот.
Я лично захожу на сервер ShareWare-ных программ и качаю всё подряд -
из 10 одна стоящая найдётся. Впринципе, сломать самодельную программу
ничего не стоит.
Q: Как сломать защиту на проверку компакт диска?
A: Предлагаю классический вариант:
- Ставим брекпоинт на функцию GetVolumeDriveType (т.е. определение вида
носителя) и программа проверяет компакт ли это диск (т.е. сверяет
результат с 00000005)
- теперь хекс-редакоторм меняем 005 на 003 (т.е. жесткий диск)
- Создаем любым эмулятором компакт-дисков из директории Fake диск нашей
программы.
- Теперь программа найдя жесткий диск подумает, что это сидюк и потом
обнаружит на нём все нужные файлы и конечно запустится.
Q: Я ломая программу изменил хекс-редактором программу и она запустилась
с сообщением "Программа была изменена. Переустановите её". Как отключить
проверку на изменения кода программы?
A: Это, пожалуй, самый модный приём в защите програмы от посягательств.
Называется он CRC - алгоритм проверки программы на изменения. Отключается
он не просто, но есть один способ:
- копируем оригинальную программу в безопасное место и делаем изменения
в коде программы
- ставим прерывание на функцию GetModuleFileName и проходя по коду
Изменённой программы дебагером записываем все переходы (jnz,jz...)
на бумагу
- запускаем "нормальную" программу и сравниваем все переходы с
записанными
- после нахождения различия уже всё будет просто, меняем к примеру jnz на jz
и дело в шляпе.
Q: Я дизассемблировал программу WDAsm'om и увидел там пустоту!
A: тут, скорее всего, программа защищена каким-то пакером или протектером.
Q: Что такое пакер и как с ним бороться?
A: Пакер - это программа, которая запаковывает (сжимает) нужную программу
и прикрепляет распаковщик. При этом при запуске этот распаковщик распаковывает запакованную прогу и передает её управление. Из известных
пакеров: UPX, ASPack etc. Есть ещё так называемые Протектеры, они действуют
так же как и пакеры, только не просто запаковывают прогу а и зашифровывают
сам её код, таблицы импорта и экспорта, да все что угодно, при этом такие
проги напичканы различными антиотладочными средствами и т.д. Из пакеров:
ASProtect, VBox,PESHiELD etc.
Q: Есть ли стандартные примеры быстрого взлома?
A: Вопрос не совсем понятен. Есть стандартная ошибка многох программ: когда
серийный номер сгенерён, то он не затирается, а остаётся в памяти очень
часто прямо рядом с неправильным серийным номером (Что очень глупо). Т.е.
нам стоит открыть SoftIce и ввести строку поиска:
s ds:0 l ffffffff "введенный_номер" -
и где-то рядом в памяти будет нужный серийник.
Q: Я ломал программу и поставил прерывание bpx messageboxA, но софт айс не
выскочил, хоть сообщение об ошибке (messagebox) выскакивает исправно.
A: попробуй:
bpx MessageBox
или
bpx MessageBoxW
Q: Сколько уходит времени на взлом программы?
A: У меня, либо программа ломается сразу (5 мин) либо не сразу
(до 2 дней - по настроению). А вообще чётких терминов нет, они ограничены
только умелостью самих программ.
Q: Что такое FrogIce?
A: Это патчер для SoftIce. Он предназначен для того, чтобы работать с
программами, которые определив, что загружен СофтАйс не грузились.
Но после его обнародывания новые программы используют другие методы
определения, поэтому если какая-то программа не хочет запускаться или
выдает глупые сообщения - найдите самый свежий Патчер такого рода.
}{Отя я лично этой фигнёй не пользуюсь - подумай сам, ведь до момента
обнаружения софтайсом пользоваться ещё можно :)
Q: что такое IceDump?
A: Это плагин для СофтАйса. В нем куча новых, недостающих в айсе функций.
Вот некоторые из них:
/dump <from> <length> <filename> - дампит область памяти в файл.
Проигрывание компакт-дисков прямо из айса, проигрывание MP3 файлов из
айса, а также на радость многим встроен тетрис. Короче, скачайте IceDump
и почитайте доки (они там небольшие).
Q: Что такое IDA?
A: Это Интерактивный Дизассемблер. Но работать новичку с этой штукой, это
все равно что на дачу ездить на космическом корабле, а раз ты задал такой вопрос, то смело бери другой дизассемблер - WDasm32
***************************
*Дополнение (1) от Fess'a *
***************************
Q: А можно ли получить исходный текст на языке, на котором была написана
программа?
A: Иногда, максимально близко к исходному коду, но точно никогда.
И для таких компиляторов, которые оставляют много мусора в exe-файле.
Таких как Visual Basic и частично Delphi.
Q: Какие программы для начала лучше поломать для тренировки?
A: Крякмисы для начинающих, коих в сети немеренно.
Q: Как сломать защиту на проверку компакт диска?
A: Мои методы такие
1) GetDriveTypeA.
2) Устанавливаем игру. Переключаем имя CD-ROMa на другое, перезагружаем.
Если прога начинает кричать, что диск не найден (cd не вынимаем). То значит
она записала куда-то имя диска. Берем FileMon и RegMon и ищем куда.
Исправляем.
3) Идем в kernel.dll (Оттуда берется функция) и заменяем mov eax,03000000
на eax,05000000, т.е. все ЖД становятся CDюками. Но некоторые игры могут
не понять юмора. Так что надо сохранить старый kernel
4) Если игра полностью установилась на ЖД. И проверяет только наличие CD.
Можно так. Берем настоящий диск смотрим метку тома (в основном для опред.
настоящности CD проверяют метку тома). Ищем ее во всех файлах программы.
Если нашлась, то делаем так. Берем любой другой CD, который постоянно у Вас
смотрим там метку тома. И в проге старую метку заменяем на новую.
Комментарий не для печати: Они что там все тупые за океаном. Хотя бы
проверку на свободное место. На присутствие всех файлов. Попытаться
сделать запись на CD. Идиотизм. М-да.... Лишь наши пытаются что-то
сбацать (Руссобит), но еще слабовато.
Q: Я ломая программу изменил хекс-редактором программу и она запустилась
с сообщением "Программа была изменена. Переустановите её". Как отключить
проверку на изменения кода программы?
A: Еще проще. Она пишет, что "Проге Плохо". Дизассемблируем смотрим где
находится
эта строка. Смотрим откуда она вызывается (чуть выше). И исправляем там
переход. Или ставим бряк на MessageBox и исправляем переход.
Q: Есть ли стандартные примеры быстрого взлома?
A. Ставим бряк на введеный s/n (см. Взлом Delphi). Запускаем процедуру
проверки и ждем, когда прога будет его проверять с настоящим.
Q: Особенности взлома Делфи?
A: Простой взлом. Пусть не исполует стандартные функции GetWindowTextA
и MessageBox зато можно поймать так:
В окне ввода нэйма и сернама. Вводим их. Нажимаем Ctrl-D. Вводим команду
s 0 l ffffffff "ваш_сернам". После того как найдет это будет в районе
8xxxxxxx. Ставим бряк bpmb <адрес найденой строки> rw . Теперь Ctrl-D,
нажимаем Ок. Вываливаемя в Soft-Ice. Жмем F12 раз 8 пока не увидим
примерно такую строку mov eax, xxxxx. Проходим ее по F10. Вводим
d eax. Если в окне данных появился ваш сернам, то удаляем страрый бряк
bc*. Ставим новый bpmb eax rw. А дальше по обстоятельствам.
Q: Особенности взлома C++?
A: Сложность зависит от мастерства автора. В понимании все просто
ведь пишется на чистом API. Но если автор знает, что делает, то
взлом может быть долгим.
Q: Особенности взлома Visual Basic?
A: В моем понимании самый если не самый сложный взлом, то самый тормозной.
Компилятор так издевается над программой, что превращяет ее в фиг знает что.
Могу посоветовать только прогу VBREF, которая после Win32Dasm по его листингу
ищет в exe-шинике строки, которые VB хранит в другом формате, не как все. То
же делает и один из патчей к Win32Dasm. VB использует свои функции, описание
которых я пока не видел, понимается только по смыслу. Новичкам не советую.
Q: Я распаковал программу запакованную exe-паком, почему она не
дизассемблируется в Win32Dasm? (Комментарий не для печати: Я тоже долго
это искал.)
A: Exe-паковщики исправляют таблицу размещения в PE. Но можно поступить так:
Запускаем ProcDump32. Запускаем в нем PE-Editor. Открываем распакованный
файл. Нажимаем Sections. Там в нажимаем на первой секции (в C++ это .text)
правой кнопкой, выбираем Edit и в поле Characteristics вместо C0000040
пишем E0000020. Так же можно сделать и с секцией .rsrc. Почему так
смотри стандарт PE.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy
Статья создана: 14.10.02
FlashGet(JetCar) - это замечательная программа для быстрого скачивания файлов из интернета, вот заходим мы на интерду, находим пара сайтиков, находим логику в нумерации картинок, создаём список... и поехали... ну или на даунлодру заходим.
В общем, программа не выкидывает НАГ окон, но показывает баннер в верху своего окна, и многим это даже совсем не мешает, если вам не мешает - не надо его убирать, ведь авторы именно на этих показах и делают деньги, и пускай делают, мы лишь исследуем программный код с целью выясенения их ленивости.
Был у меня такой FlashGet - 0.86 и был 1.10, я решил посмотреть версию 1.10 и наконец-таки избавиться от, отвлекающего меня, баннера.
Во FlashGetе в окне "Убрать баннер" я ввёл своё замечательное имя, Bad_guy, и 12345 в качестве кода, нажал OK и получил сообщение: "Спасибо за регистрацию!....Перезапустите программу...". Неужели, я угадал код - конечно нет - просто программа у нас "крутая", она проверяет пароль при запуске. Ну что ж, перезапустим под RegMon'ом, что же мы видим: в реестре есть ветка, где живет наш FlashGet по имени JetCar, вот она: HKEY_CURRENT_USER\Software\JetCar\JetCar\, посмотрим в этой ветке раздел General. Этот раздел содержит два преинтересных параметра RegName="Bad_guy" и RegPass="12345", вот почти наш FlashGet и попался, мы теперь знаем, что, в принципе, можно поставить прерывание на функцию RegQueryValueExA? но она плохая функция - её слишком часто вызывают многие программы, боюсь, сложно будет докопаться до истины (FlashGetа). Признаюсь, что я тщетно баловался SoftIce'ом достаточно долго, прежде чем понял, что он мне не поможет целиком "сломать" FlashGet и я решил взять W32Dasm. После того, как программа была раздизассемблирована можно было догадаться, что скоро настоящий регистрационный код для FlashGet мною будет найден, давайте взгляним на этот дизассемблированный код, важные строки я выделил красным цветом:
* Possible StringData Ref from Data Obj ->"RegName"
|
:0041807F 6878B34D00 push 004DB378
:00418084 8D442414 lea eax, dword ptr [esp+14]
* Possible StringData Ref from Data Obj ->"General"
|
:00418088 6848A44D00 push 004DA448
:0041808D 8BF1 mov esi, ecx
:0041808F 50 push eax
:00418090 E868C70800 call 004A47FD
:00418095 68D4134E00 push 004E13D4
* Possible StringData Ref from Data Obj ->"RegPass"
|
:0041809A 6870B34D00 push 004DB370
:0041809F 8D4C2410 lea ecx, dword ptr [esp+10]
* Possible StringData Ref from Data Obj ->"General"
|
:004180A3 6848A44D00 push 004DA448
:004180A8 51 push ecx
:004180A9 8BCE mov ecx, esi
:004180AB C744243400000000 mov [esp+34], 00000000
:004180B3 E845C70800 call 004A47FD
:004180B8 8B54240C mov edx, dword ptr [esp+0C]
:004180BC BB01000000 mov ebx, 00000001
:004180C1 885C2424 mov byte ptr [esp+24], bl
:004180C5 8B42F8 mov eax, dword ptr [edx-08]
:004180C8 85C0 test eax, eax
:004180CA 0F84CF000000 je 0041819F
:004180D0 8B442408 mov eax, dword ptr [esp+08]
:004180D4 8B48F8 mov ecx, dword ptr [eax-08]
:004180D7 85C9 test ecx, ecx
:004180D9 0F84C0000000 je 0041819F
:004180DF 57 push edi
:004180E0 53 push ebx
:004180E1 6A43 push 00000043
:004180E3 8D4C2420 lea ecx, dword ptr [esp+20]
:004180E7 E84D280700 call 0048A939
:004180EC 8D4C241C lea ecx, dword ptr [esp+1C]
:004180F0 53 push ebx
:004180F1 51 push ecx
:004180F2 8D4C2414 lea ecx, dword ptr [esp+14]
:004180F6 C644243002 mov [esp+30], 02
:004180FB E8F82C0700 call 0048ADF8
:00418100 8B542418 mov edx, dword ptr [esp+18]
:00418104 8B00 mov eax, dword ptr [eax]
:00418106 52 push edx
:00418107 50 push eax
:00418108 E806380600 call 0047B913
:0041810D 83C408 add esp, 00000008
:00418110 8D4C241C lea ecx, dword ptr [esp+1C]
:00418114 85C0 test eax, eax
:00418116 0F94C0 sete al
:00418119 25FF000000 and eax, 000000FF
:0041811E 8BF8 mov edi, eax
:00418120 E89E730700 call 0048F4C3
:00418125 8D4C2418 lea ecx, dword ptr [esp+18]
:00418129 885C2428 mov byte ptr [esp+28], bl
:0041812D E891730700 call 0048F4C3
:00418132 8B4C2410 mov ecx, dword ptr [esp+10]
:00418136 57 push edi
:00418137 8D542418 lea edx, dword ptr [esp+18]
:0041813B 51 push ecx
:0041813C 52 push edx
:0041813D 8BCE mov ecx, esi
:0041813F E89C000000 call 004181E0
:00418144 8B44240C mov eax, dword ptr [esp+0C]
:00418148 8B4C2414 mov ecx, dword ptr [esp+14]
:0041814C 50 push eax
:0041814D 51 push ecx
:0041814E E8C0370600 call 0047B913
:00418153 83C408 add esp, 00000008
:00418156 885C2428 mov byte ptr [esp+28], bl
:0041815A 85C0 test eax, eax
:0041815C 5F pop edi
:0041815D 8D4C2410 lea ecx, dword ptr [esp+10]
:00418161 7537 jne 0041819A
:00418163 E85B730700 call 0048F4C3
:00418168 8D4C2408 lea ecx, dword ptr [esp+08]
:0041816C C644242400 mov [esp+24], 00
:00418171 E84D730700 call 0048F4C3
:00418176 8D4C240C lea ecx, dword ptr [esp+0C]
:0041817A C7442424FFFFFFFF mov [esp+24], FFFFFFFF
:00418182 E83C730700 call 0048F4C3
:00418187 8BC3 mov eax, ebx
:00418189 5E pop esi
:0041818A 5B pop ebx
:0041818B 8B4C2414 mov ecx, dword ptr [esp+14]
:0041818F 64890D00000000 mov dword ptr fs:[00000000], ecx
:00418196 83C420 add esp, 00000020
:00418199 C3 ret
Как можно увидеть из листинга, я искал имена параметров, под которыми в реестре сохранены наши регистрационные данные. Каждый из них встречается в листинге дважды, первый раз я увидел рядом строку "Спасибо за регистрацию...", в общем это то место, где мы вводили наши данные, а вот второй случай более интересен, беру этот адрес (ну, например, 0041807F) и ставлю в SoftIce прерывание на него, если не знаете, как это сделать - подскажу - (перед тем, как запускать FlashGet поставьте в SoftICE прерывание bpx hmemcpy и запустите FlashGet, сразу же прервётесь, жмите F12, пока не окажетесь в модуле по имени FlashGet, а дальше спокойно ставьте прерывания на любые адреса, полученные для этой программы в W32Dasme - этот метод "добраться до программы" хорош для любых программ, а не только FlashGet). Вот мы уже прервавлись по адресу 0041807F, смотрим по моей методике бегло все "прыги" и значения в регистрах и вот мы добрались до 00418144, давайте ещё раз поглядим на этот код:
:00418144 8B44240C mov eax, dword ptr [esp+0C]
:00418148 8B4C2414 mov ecx, dword ptr [esp+14]
:0041814C 50 push eax
:0041814D 51 push ecx
:0041814E E8C0370600 call 0047B913
:00418153 83C408 add esp, 00000008
:00418156 885C2428 mov byte ptr [esp+28], bl
:0041815A 85C0 test eax, eax
:0041815C 5F pop edi
:0041815D 8D4C2410 lea ecx, dword ptr [esp+10]
:00418161 7537 jne 0041819A
Если даже не будем смотреть значения в регистрах, всё равно увидим, что jne 0041819A отправляет нас за ближайший RET, а это подозрительно, теперь поглядим значения в регистрах перед CALLом, наберём:
:deax - там '12345'
:decx - там '37949NE1L6' - правильный рег. номер
Проверим, введя эти данные в FlashGet и получим, что мы правы и что:
Регистрационный ключ для FlashGet(JetCar) Version 1.10
Name: Bad_guy
Serial: 37949NE1L6
А вот памятка, которую я по-быстрому набросал специально для себя с целью будущего исследования новых версий FlashGet:
Вводим любые рег. данные, ищем их в реестре: HKEY_CURRENT_USER\Software\JetCar\JetCar\General, название параметров (RegName, RegPass) ищем в W32Dasm дизассемблерном листинге, ставим в SoftIce прерывание на второй из двух найденных адресов, смотрим в SoftIce, перед RET есть JZ. Перед входом в CALL, меняющий флаг, есть PUSH eax, PUSH ecx - в EAX неправильный номер, в ECX - правильный. (адрес для версии 1.10 был 41814D).
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy
Статья создана: 24.09.02
Для тех, кто пришёл просто за крэком к WinRAR 3.0:
WinRAR 3.0 Full Rus с крэком - http://cracklab.narod.ru/dload/wrar300full.zip
Сам крэк для WinRAR 3.0 Full Rus - http://cracklab.narod.ru/dload/wrar3fp.zip
Наконец-то мои руки добежали по кнопкам до написания этой статьи, но идея кипела в моей голове уже долгое время, не давая мне есть, спать, ходить, сидеть, ну и так далее... неужели я успокоюсь после написания статьи, наверное НЕТ (идеи распирают голову вот-вот она лопнит, придёться экран вытирать... э-э-э, чего-то меня понесло, пора переходить к делу).
Одним прекрасным днём родилась идея обновить любимый архиватор ВинРАР, я зашёл на сайт rarsoft или rarlab (не помню как он тогда назывался) и, о чудо, увидел, что мне сейчас доступен WinRAR 3.00 beta 4, да ещё и русская версия, я получил вожделенные ~980Kb и, установив, заметил небезизвестное (через букву "ы") окошечко с 40 дневным предложением поюзать UNREGISTERED VERSION. Я не помню такого дня, чтоб я не воспользовался Winrar'ом хотя бы один раз и, естественно, наг окно через пару дней мне надоело и решил "Иванушка-дурачок" снять его НАВСЕГДА (ФОРЭВА - для тех, кто в танке).
Скажу сразу, что для осуществления взлома мне потребовался только отладчик SoftIce, но позже понадобился и шестнадцатиричный редактор (WinHEX) и Delphi, а ещё текстовый редактор Bred, чтобы писать эту статью.
Допустим, вы запустили WinRAR 3.0, увидели всё то же окошко и задумались какой же ставить брэйкпойнт? Я тоже когда-то над этим задумался и что-то придумал, что - сейчас уже выветрилось из головы... попробую вспомнить (засечём время).
Прошло 10 минут... напрочь забыл - начал врубаться по-новой.
Говоришь, 40 дней - ставим брэйк в SoftIce:
:bpx GetLocalTime
Говоришь - "незарегистрированная версия" в заголовке окна - получай
:bpx SetWindowTextA
Теперь, как сделает программист:
Сначала поставит "незарегистрированная версия" в заголовке окна, а потом узнает время - вряд ли, что подтверждается на практике.
Попробуем, насколько "солёненький" WinRAR нам попался - запускаем его.
004367B3 - здесь у нас GetLocalTime;
0043FA27 - а здесь SetWindowTextA;
Скорее всего между этими двумя адресами и будет вычисление "зарегистрированности" версии.
Сразу после 004367B3 идёт вызов какой-то процедуры, которая возвращает результат в AL в виде 0 или 1, а затем значение AL закидывается в некоторый адрес памяти. Поглядев внимательно внутрь этой процедуры, я заметил, что она начинает проверять файл RARReg.Key (я не сказал: у меня был легальный ключик для 2.9 версии, я его положил первым делом в папку с новым WinRAR 3.0), пока я смотрел процедуру я успел понять, что в принципе она должна как-то возвратить значение AL не 0, а 1, но я пошёл дальше.
AL закидывается в некоторый адрес памяти - я заменил значение AL перед этим и "отпустил" программу на выполнение, программа загрузилась как "незарегистрированная", но когда она прервалась по SetWindowTextA при создании НАГ-окна я посмотрел в тот адрес памяти, где должна была быть 1 и увидел там 0 и тут я решил поставить брэйкпойнт на память и посмотреть, что программа всё-таки делает с этой переменной ?
:bpm 48dd1c rw
За всё количество прерываний по этому брэйку, два раза пришлось сменить значение по этому адресу (48dd1c) с 0 на 1 (команда :eb - для тех, кто не знает) и увидел на экране зарегистрированную версию WinRAR 3.0 beta 4 Rus.
Посмотрим, где же в память записывается 0, в какой процедуре ? - а в той же, что и в первом случае, значит просто находим место в ней где сделаем, чтобы в AL ВСЕГДА возвращалось значение 1 и будем писать крэк для WinRAR 3.0 beta 4 Rus.
Как оказалось технология та же и для WinRAR 3.0 Full, но я думаю, что с легкостью по этому же принципу можно будет создать кряк и для WinRAR 3.1, 3.2 и может 3.3, ну а потом уж автор WinRAR (мультимиллионер супершароварщик Евгений Рошал или его наёмники) найдут в инете эту статейку и закроет лазейку, а мы постараемся найти другую !
Что-то у меня получилось не внятно как-то, ладно в таком случае дам я вам ещё исходники патчера для WinRAR 3.00 Full (между прочим для минимизации размера написал я его на Delphi без использования VCL, то есть на WinAPI):
//--------------PATCHER.DPR----------------
Program Patch;
Uses windows,messages, shellapi;
const
ar : array[1..6] of byte = ($e8,$bd,$07,$00,$00,$58);
ar2 : array[1..6] of byte = ($b8,$01,$00,$00,$00,$90);
var
msg: tmsg;
win: hwnd;
bol: boolean;
i,b: byte;
f: file of byte;
{$R API.RES}
Procedure CreateReg;
var f1:textfile; str:lptstr;
begin
Assignfile(f1,'RarReg.b_g');
rewrite(f1);
Writeln(f1, 'RAR registration data');
Writeln(f1, 'Bad_guy');
Writeln(f1, 'Advanced GOD Pro version');
Writeln(f1, 'UID=fd402b81950501fbd1a1');
Writeln(f1, '6412212250d1a118e384ae1996cdea4f90d100b3dcd53ea5fa77c2');
Writeln(f1, 'a2a9458b4636334c81d46035c6ab9048e2c5c62f0238f183d28519');
Writeln(f1, 'aa87488bf38f5b634cf28190bdf438ac593b1857cdb55a7fcb0eb0');
Writeln(f1, 'c3e4c2736090b3dfa45384e18e9de05c5860c0cbfb4a4cbbe9549e');
Writeln(f1, 'b4ca3bc23f80d0cde2d91ba211839f05b0a5de11631072687e814d');
Writeln(f1, 'd0fa0ace9439b90564d3ba7de5413d0824487a50f64e6ea360c858');
Writeln(f1, 'ee31cdacb655824a7a443ec0da598dfb6e79f305d8bf4260523534');
closefile(f1);
end;
Function SettingsDlgProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;
Var S : String;
Begin
Result := 0;
Case Msg of
wm_InitDialog : Begin
Result := 0;
End;
wm_Command : Begin
case LoWord(WParam) of
50:
begin
AssignFile(f,'winrar.exe');
{$i-}
Reset(f);
{$i+}
If IoResult <> 0 then
Messagebox(Win,'An error ocured while opening file','Error',MB_OK)
else begin
If Filesize(f) = 752640 then begin
Seek(f,$B26A);
bol := true;
for i:=1 to 6 do
begin
Read(f,b);
If b <> ar[i] then bol := false;
end;
if bol then begin
Seek(f,$B26A);
for i:=1 to 6 do
Write(f,ar2[i]);
Closefile(f);
CreateReg;
Messagebox(win,'Patched succesfully','Congratulation',MB_OK);
end
else
Messagebox(win,'An error ocured while patching','Error',MB_OK);
end
else
Messagebox(win,'Wrong file size','Error',MB_OK);
end;
end;
51: DestroyWindow(Win);
53: Messagebox(Win,PChar('Автор крэка: Bad_guy'+#13#10+'Выпущен:
25.07.02'+#13#10+'Ограничения: вы не сможете использовать "электронную
подпись"'+#13#10+'Адрес программы:
http://cracklab.narod.ru/dload/wrar300full.zip'),'About',MB_OK);
54:
ShellExecute(win,'open',PChar('http://cracklab.narod.ru/'),nil,nil,SW_MAXIMIZE);
end;
end;
wm_Close : DestroyWindow(Win);
wm_Destroy : PostQuitMessage(0);
else Result := 0;
end;
end;
Procedure RunSettings;
Var Result : Integer;
Begin
Win := CreateDialog(hInstance,PCHar(101),0,@SettingsDlgProc);
Showwindow(Win,SW_SHOW);
Updatewindow(Win);
End;
begin
RunSettings;
While GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
//---------END OF PATCHER.DPR-------------
//-------------API.RC---------------------
101 DIALOG 0, 0, 266, 95
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUPWINDOW |
WS_DLGFRAME
CAPTION "WinRAR 3.00 Rus Patch by Bad_guy"
FONT 8, "MS Sans Serif"
{
DEFPUSHBUTTON "Patch", 50, 13, 73, 59, 14
PUSHBUTTON "Cancel", 51, 188, 73, 65, 14
CTEXT "[-== Bad_guy ==-] \n Remove 40-day limit and NAG-screen \n i'm a genius,
you are a shit", 100, 13, 42, 240, 27, SS_SUNKEN
CONTROL 101, -1, "STATIC", SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE |
SS_SUNKEN, 13, 8, 240, 30
PUSHBUTTON "About", 53, 75, 73, 50, 14
PUSHBUTTON "Our Website", 54, 130, 73, 54, 14
}
//-----------END OF API.RC---------------
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Статью написал: Bad_guy
Статья создана: 29.08.02
Многие люди стремятся заниматься программированием, но существует и такая часть компьютерных профессионалов, как крэкеры, причём крэкеры не стесняются обычно заниматья и программированием тоже.
Существует слух, что крэкер серьёзной программы не напишет, с этим мнением мне лично сложно согласиться, однако если представить человека погружённого в крэк целиком, естественно можно предположить, что серьёзнее кеймекера он программы не напишет. Всё же большинство крэкеров не абсолютные энтузиасты и равно как и крэком любят заниматься и программироаванием, а может даже больше программированием, к коим я, собственно говоря, и отношусь.
... Время шло, мой опыт рос, и в один прекрасный момент мою голову поразила мысль о том, что надо бы интернет - то как-нибудь окупать, вот и решил я тогда взять ноги в руки, прокопать как следует свои дельфовые проекты и создать коммерческий продукт. Есть идея - есть дело и через пару недель мой первый коммерческий проект был закончен, не буду вам говорить что это за программа, скажу лишь что продавать её я решил только на западе, потому что у нас в стране хроническая привычка покупать софт только в переходах метро, может быть конечно это и неплохо, ну да ладно...
Во время написания этой программы я не мог не удилить внимания её защите, ведь можно сказать это моя слабость, а можно и - специализация, но защиту эту поленившись я конечно придумал не 100% надёжности, да и понадеялся, что за её цену на Западе даже и руки не станет пачкать никакой крэкер (зря я конечно так-то сам ведь знаю, что здесь энтузиазм главное), кстати, почитав конференцию шароварщиков я понял, что выход крэка не подрывает целиком их бизнес, только малая доля потенциальных покупателей использует крэк, остальные - всё равно купят (для России я думаю дело всё-таки обстоит иначе), ну, пожалуй хватит лирики...
Суть моего метода защиты в программе была такова:
Сначала я написал всю программу. Назвав её Freeware, можно было бы её выкладывать, но как бы не так (теперь я вообще наверно не одной фриверки не напишу - деньжатами запахло), затем я стал предпринимать попытки навешать всяких нагов и ограничений и это у меня тоже получилось. Защита была организована так:
решено было использовать ключ, регистрационное имя в вычисление ключа не входило. В тех местах, где было ограничение (например, вместо окна сохранения, нажав кнопку "сохранить" вы получаете сообщение "Отключено в незарегверсии") я вставил вызов процедуры-пустышки, программа шла в ту пустышку, пустышка усиленно что-то шифровала, складывала, делила и _ВСЕГДА_ возвращала значение переменной, допустим число "17", этот значение сравнивалось с оригиналом и если не совпадало, происходил выход из программы, а если совпадало, то в переменную где было "17" записывался "0" и программа спокойно продолжала работать. В чём сила, брат, спросите вы ? А вот в чём вся сила: адрес этой вызываемой процедуры был не указан внутри кода, то есть было сделано не так:
Call 40152A
а вот так:
Mov eax, regprocaddr
Call eax
причём если regprocaddr не был известен (был равен 0 в незарегистрированной версии), то конечно программа показывала сообщение "Отключено в незарегверсии" и не шла в тот код, regprocaddr же каждый пользователь получал следующим образом:
regcode, который присылался пользователю состоял из двух частей long integerов, в строковом формате, эти две части xorились и это и есть regprocaddr. Теперь было так: если regprocaddr > 0 тогда программа попадала на этот код:
Mov eax, regprocaddr
Call eax
и если regprocaddr был неправильный, то программа вызывала черт знает что вместо процедуры и естественно вылезал exception, а если даже и попадала в какую-то процедуру, то всё равно вероятность того, что та процедура вернёт в переменную значение "17" нулевая и программа всё равно завершит работу.
Вы, прочитав всё вышесказанное, скажете: а я обойду твою процедуру и сравнение с "17" тоже, согласен, но вы никогда не сможете подобрать regcode и обязательно должны будете попатчить программу, а этот портит всю красоту взлома, а, да я ещё не так прост и вам будет надо патчить прогу в 7-10 местах так-то, а теперь представьте себе ваш патчер, который будет пропатчивать 60-100 байт - во веселье-то.
Так что, как видите, мною была осуществлена 100% защита от подбора ключа и слабенькая защитка от патча (расситанная в основном на отсутствие упорста у крэкера). Для полного понта я ещё и запаковал программу компрессором, ну ещё одна подножка неупорному крэкеру (в моей голове уже давно зараждается мысль "поправить" исходники UPX и таким образом создать свой компрессор). Самая главная пакость этого метода защиты (для меня) это то, что зная один правильный регистрационный код можно сделать кеймекер и я даже не узнаю какой из "законопослушных" "зарегистрированных" пользователей так постарался. А вообще я не жадный, получу 100$, а потом уж пускай хоть всю изломают эту защиту - для меня программа (интернет) уже окупится.
P.S. Вот найдите теперь эту мою crackme.exe и потренируйтесь на практике, а то я уверен, что многие кто это всё прочитал не очень врубились в смысл.
Удачи вам в вашей деятельности, чем бы вы ни занимались, Bad_guy.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
1. Исследуем язык, на котором написана программа. Я обычно использую Restorator 2.50 [1024 Kb], либо Exescope'ом [409 Kb] можно посмотреть. Сразу же узнаём запакована программа или нет.
1.1 Тип языка я определяю по размеру файла и по ресурсам:
- Assembler - размер файла меньше 40 Kb (если не использует картинок), присутствует раздел Dialog в ресурсах. На ассемблере обычно пишут перцы, так что шанс взломать резко снижается (скорее будет патч, нежели подбор номера).
- Visual C++ - размер файла - разный, если меньше 40 Kb и файл импортирует функции из модуля MFC42.DLL или больше 40 + присутствуют ресурсы Dialog, тогда это С++, по моему опыту ломается лучше всего, так как структура программы более менее линейна (наглядна)+ запрашиваются WinAPI функции, на которые всегда можно поставить брейкпойнт.
- Delphi - определется легче всего - в ресурсах присутствует раздел "RCDATA" или "DATA" - кто как показывает, в котором обязательно есть ресурс PACKAGEINFO + почти всегда ресурс типа TFORM1 (или другой, но обязательно с буквы T). Ломаются такие программы не очень сложно, учитывая то, что множество программистов Delphi - любители (новички), однако сам код, откомпилированный в Дельфе очень не нагляден - бесконечные джампы и процедуры + не используютcя "наши" API функции (но зато железно работает hmemcpy)
- Visual Basic - что касается самого Бэсика, так я его не уважаю, потому что программы работают только при наличии VBRUNxxx.DLL или другой (в зависимости от версии) ботвы в системных папках (в PATH-папках) + код не скомпилирован по человечески (до версии 5) и можно ломать только декомпилятором. Начиная с версии 5 стал создаваться некоторый скомпилированный код (вообщем SoftIce'ом можно поломать). Отличить VB программу от других легко - открываем в Exescope и видим, что импортируется библиотека вида VB######.dll или MSVBVM##.dll.
1.2 Запакована или нет?
Самый простой способ это проверить - открыть программу в Restorator'e и посмотреть все ресурсы, если вместо ресурсов высвечивается надпись "Ресурс повреждён" - значит файл пожат, а это в свою очередь означает, что путь патча нам уже закрыт.
Комментарий от 22 мая 2002 года: наконец-то до меня дошла (или я дошёл) версия компрессора UPX (1.20) [117 Kb], которая может разжимать сжатые любыми версиями UPX программы, теперь бы ещё распаковщик Aspack'а...
Комментарий от 17 августа 2002 года: Распаковшик AsPack тоже был найден, может быть скоро можно будет его здесь скачать (называется AspackDie у меня - v1.4).
Также нашёлся распаковщик PECompact (моего любимого) - называется UnPECompact 1.31 (написал тот же чувак, что и AspackDie).
2. Ищем в программе куда нужно вводить код (ну, я думаю сами найдёте).
3. Вводим код в соответствующее окно и, не нажимая Enter, вызываем SoftIce и ставим брейкпойнты bpx getdlgitemtexta, bpx windowtexta - для любой программы + bpx hmemcpy - для Delphi- программы, затем нажимаем на "ОК"-кнопку и мы должны попасть в SofIce по одному из этих брейкпойнтов.
4. Что же далее: вот мы в SoftIce'е, я обычно первый раз гоню программу по F10, смотрю и запоминаю, пока не вылезет окно сообщения о неправильном рег. номере (назовём его окно "обломис"). Вы скажете, ну и что же ты запоминаешь: а вот что - я плевать хотел на всякие Call и прочие умные вещи, я запоминаю долго ли я гоню по F10, а также все условные переходы (jz, jnz, jne, je ...). Когда вам вылезло окно "обломис", возвращаемся в SoftIce, смотрим вверх и ищем то место, где есть условный переход, который так или иначе может увести нас от вызова "обломиса", а теперь ищем процедуру, которая может изменить флаг, на который реагирует этот переход (для jz, jnz, jne, je - это флаг Z). Могу с уверенностью сказать, что если вы уже на этом месте и всё вышесказанное получается, то большая половина дела уже сделана (похоже программисты забыли поставить шлагбаум, хотя такой как я программист мог бы приколоться - поставить пустышку).
5. Теперь надо начать ковырять процедуру, да не очень усердно - вдруг пустышка. Да вот тут то я могу вам ничем не помочь все они сделаны по разному, ну признаюсь на этом этапе я обычно ставлю брейк на процедуру, выхожу и пробую ввести рег. данные заново, а потом, как тупой америкос, попав в SoftIce начинаю тупо смотреть содержимое регистров и вот что самое интересное в не более 50% случаев - помогает и я рано или поздно вижу правильный рег. номер в каком-нибудь регистре. Ну, я представляю что сейчас подумал обо мне профессионал, случайно забредший на эту страницу, что ж, лень, как известно, двигатель прогресса, а я ужасно ленивый, просто иногда даже злюсь на себя. Да, кстати, надо иметь чутьё на рег. номер - иногда они бывают вот такие: &^&$&%&ufs - и если до процедуры, на которую мы поставили брейк вы его не нашли, то поищите внутри неё.
Вообще надо действовать по ситуации, потому что не один крэкер не даст вам супер оптимальной и в то же время простой инструкции по взлому, а для того, чтобы заниматься крэком, нужно немногое - настойчивость, голова на плечах (знающая немного ассемблера), а также мания величия (ну этого, я заметил, почти у всех компьютерщиков хватает, даже у меня, иначе вы это сейчас бы не читали, а я бы не писал).
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Вот три примера крэка программ с нарастанием по сложности (в пределах своей компетентности).
1. Самая простая защита программы, которая мне попалась за мой период работы - Screen Loupe for Windows 95 NT v4.5 [122 Kb] - она увеличивает часть рабочего стола, показывает координаты мыши на столе, цвет под указателем мыши в виде #XXXXXX, грабит экран и другое, вообщем иногда нужна.
Она относится к классу Shareware (мой любимый) и показав себя в действии требует регистрации в течение ХХ дней (это не имеет значения) с начала использования.
Ну, я взял и, недолго думая, поставил в SoftIce'е брэйкпойнты на GetWindowTextA и GetDlgItemTextA (надеюсь вы знаете как это делать, если нет, то сначала прочитайте текстик, ссылка на который находится в самом верху этой страницы), ввёл данные в поля Name, Company, Serial#, причём на месте Serial# я обычно ставлю 12345 (3039h). Нажимаю OK и программа забрейкпойнтилась по GetDlgItemTextA - нажав 2 раза F12 и посмотрев в регистре ESI вы увидите введённое имя, по следующему GetDlgItemTextA увидите вашу фирму, а далее по ещё одному GetDlgItemTextA, оказавшись по адресу 40626B можно посмотреть в регистре ECX (команда: db ECX) кое-что (ну, что узнали?), а затем пройдя по F10 до адреса 406271, посмотрите на EAX - я там увидел 3039 (это шестнадцатиричное 12345), далее EAX копируется в EBX. Сейчас можно предположить, что правильный номер, когда он вычислится, будет: во-первых - сравниваться с EBX, во-вторых - в шестнадцатиричном виде. Я посмотрел далее и вот оно !!! по адресу 4062B8 CMP EAX, EBX , а дальше JZ XXX... Смотрим правильный рег. номер командой ?EAX , можно записать его на бумажку и подпрыгивать от радости, когда программа скажет вам Thank You!, но я предлагаю сделать проще: когда вы ещё по адресу 4062B8 - пишите команду r ebx=eax - и выходим из SoftIce'a, ну что ж, одна программа сломана. Вот, где она сохраняет свои регистрационные данные: HKEY_CURRENT_USER\Software\Software by Design\Screen Loupe for Windows 95/NT\Registration
2. Более сложная защита программы (...но на самом деле очень простая :-), которой защищено БОЛЬШИНСТВО программ класса ShareWare была применена авторами программы BadCopy99 v1.5 [273 Kb] Программа эта весьма замечательная и интерфейс у неё симпатичный, она нужна для того, чтобы считывать информацию с попорченных дискет и дисков(помните такую ошибку: "Неудаётся произвести чтение с устройства"), нечитаемые сектора заменяются нулями.
Ну для начала я открыл её в Restorator'e и сразу понял, что написана она на Дельфи и установка брейкпонтов GetWindowTextA, GetDlgItemTextA ничего мне не даст, тогда я воспользовался ЗАМЕЧАТЕЛЬНЕЙШИМ брейкпойнтом bpx hmemcpy и, конечно, не безрезультатно.
Посмотрим, сколько раз программа прервётся по hmemcpy ---- 4 раза - появился MessageBox, ага - очень хорошо даже окошечко ввода данных не закрылось, теперь по четвёртому hmemcpy будем начинать смотреть алгоритм работы программы - смотрим, смотрим (жмём F12 пока RET ни кончатся) - ну вот мы пришли на код:
MOV EDX, [EBP-38]
POP EAX
CALL 00403E94
Перед входом в процедуру смотрим данные по адресу EAX
:d EAX - это введённый вами код;
теперь EDX:
:dedx - ну что ? вот и код - ещё тёпленький совсем !
Нет, конечно я соврал, большинство программ защищено лучше, а эта - полминутный крэк для новичка.
3. Ну и наконец самый сложный способ защиты (для новичка)...надо сказать я долго думал, прежде чем выбрал эту программу...пожалуй это будет Xara3D4 (2 May 2000) [989 Kb] - вы набираете текст на клавиатуре, он выводится как трехмерный объект, вы можете вращать его, натягивать на него текстуру, на фоне тоже можно использовать текстуру из внешнего файла, выходной файл может быть либо анимация: GIF, AVI; либо картинка: BMP, GIF, JPG. Но плоха она тем, что пока вы не "зарегистрированы" на фоне КРУПНЫМИ БУКАМИ сотни раз написано слово DEMO, и ясно, что пока мы это не уберём, о качественном результате речь не идёт. Метод защиты у этой программы довольно запутанный, проверка пароля зарыта где-то в процедурах.
Сразу же оговорюсь, что ломает она себя сама, как и Screen Loupe, но в отличие от неё она для вычисления своего пароля использует имя компьютера + случайно или псевдо-случайно сгенерированный для себя код. Вот это-то меня поначалу и подвело: поломавшись она создала свой ключ в реестре, а я взял, да и скопировал этот ключ + псевдо-случайно сгенерированный код (который она показывает в заголовке окна регистрации) из реестра в файл реестра и думал, что всё на этом, не тут-то было: пришёл я на работу, установил программу, подсунул в реестр те данные и круто обломался...ведь имя компьютера на работе другое. И тогда мне в голову пришла мысль злостно её поломать ХА-ХА-ХА
А вот как это сделать вам предстоит разобраться самостоятельно...
4. Сразу предупрежу вас о граблях-программах на которые иногда мне приходилось наступать. Дело в том, что существуют ShareWare программы (их примерно 25% от общего числа ShareWare), которые практически невозможно взломать (обычно они очень дорогие от 40$ или очень дешёвые 2$)
Комментарий от 7 мая 2002 года:
C прискорбием сообщаю, что программы скаченные мной в 2002 году удивили меня хорошей защитой - теперь не взломать где-то 50-70% этих программ. Что ж, может это и хорошо, что программисты умнеют ?!, а может это я скачиваю слишком "умные" программы ?
Комментарий от 16 августа 2002 года:
Оказалось, что программисты не умнеют, а просто юзают ASProtect и подобные программы, да ещё категорически отказываются изучать методы защиты своих программ (из личного общения с shareware программистами).
Комментарий от 27 августа 2003 года:
Да, блин, фигня это все. С каждым днем понимаешь, что почти любую программу ТЫ можешь взломать !
Материалы находятся на сайте http://cracklab.narod.ru/doc/
1. Для того, чтобы заниматься взломом виндовских программ обязательно нужен отладчик - самый популярный сейчас SoftIce, он есть на www.numega.com, но там его придётся покупать, можно также качнуть его, но уже бесплатно, здесь , а вообще лучше взять, да купить что-нибудь на подобии диска "Штурман хакера" - там много чего ещё есть.
2. Установка SoftIce'а тоже дело серьёзное - когда дело дойдёт до выбора модели видеокарты - ничего не выбирайте, а установите флажок "Universal Video Driver", иначе выходить будете только по RESET. На вопрос о выборе порта мыши честно отметьте к какому порту она подключена - иначе придётся обходиться без мыши. При запросе на изменение AUTOEXEC.BAT разрешите это - добавляется строка каждый раз запускающая SoftIce до Windows'а (кстати не знаю насколько я прав, но по моему Windows ME вообще не запускает AUTOEXEC.BAT во время загрузки - возможно придётся установить Windows 98).
3. Если вы всё вышесказанное сделали правильно, то войдя в винды и нажав Ctrl-D - вы получете окно SoftIce'а в верхнем левом углу экрана (убирается окно также - Ctrl-D или F5), но это ещё не всё - для полноценного ломания программ, SoftIce нужно ещё и настроить. Все его настройки хранятся в файле Winice.dat в папке, куда установлена программа, откройте его в текстовом редакторе и сделайте следующее:
Во-первых, вместо INIT="X;"
наберите INIT="color 7 e 1a 5b a; code on; lines 60; wc 40; faults on; X;" ; - это управление интерфейсом.
Во-вторых, там существует множество строк типа:
;EXP=c:\windows\system\netlib32.dll
обратите внимание на ";" в начале строки - проверьте какие из перечисленных там файлов действительно существуют по соответствующему адресу и УБЕРИТЕ ";" перед теми строками.
4. Теперь, после перезагрузки компьютера, отладчик готов к работе - можно переходить к урокам крэкерства.
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Использованные программы: Hellfire v2.0, W32Dasm v8.9, Dos Navigator v1.5
В статье рассматриваются следующие вопросы:
Суть проблемы состоит в том, чтобы доказать программе, что винчестер на самом деле совсем не винчестер, а CD-ROM. Или скажем - как в данном случае - в выдаче за локальный CD сетевого, ну один CD на работе, а играть-то всем охота!
Приступим. Цель - Функция GetDriveType(). Она возвращает тип диска, имя которого ей передали. Вот ее прототип:
UINT GetDriveType(LPCTSTR lpRootPathName);
Функция возвращает следующие значения:
Числовое | Идентификатор | Описание диска |
0 | - | Невозможно определить тип |
1 | - | Диск не найден |
2 | DRIVE_REMOVABLE | Гибкий (возможна замена) |
3 | DRIVE_FIXED | Жесткий (замена невозможна) |
4 | DRIVE_REMOTE | Сетевой диск |
5 | DRIVE_CDROM | CD-ROM |
6 | DRIVE_RAMDISK | RAM - Диск |
Стандартно программа получает список всех дисков, проверяет их на "CDромность" и по нахождению проверяет наличие нужных файлов. Для проверки, необходимо, очевидно, сравнить возвращаемое значение с 5. Найдем этот момент программы, вот как он выглядит после дизассемблирования HellFire с помощью W32Dasm :
Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
| | |
:0041D976 FF151CA56F00 | Call dword ptr [006FA51C] |
:0041D97C 83F805 | cmp eax, 00000005 |
:0041D97F 752A | jne 0041D9AB |
В принципе можно использовать любой другой дизассемблер, или SoftICE, в последнем случае для нахождения нужного куска необходимо написать:
bpx GetDriveType
bpx GetDriveTypeA
В самом же W32Dasm можно воспользоваться списком использованных функций. Ищем KERNEL32.GetDriveTypeA и два раза щелкаем по функции мышью. В IDA такой список есть в конце отдизассемблированного файла. Листинг полученный Sourcer'ом придется исследовать обычным текстовым поиcком.
Запишем HEX-DUMP этого куска и найдем его в шеснадцатеричном редакторе. Например в DN: откроем файл hellfire.exe по F3, далее F4 (переход в HEX режим), F7 (поиск), в строке ввода HEX строки введем записанное ранне и вперед (т.е. ENTER).
Вместо 83F805 введем 83F804 и любой из подключенных сетевых дисков теперь будет восприпринят прораммой за CD, иначе введем 83F803 - тогда жесткие диски будут приниматься за CD. Фантазия может развиваться по-любому, можно изменить условие перехода после сравнения, тогда не придется заботится о типе диска.
Вот и все на сегодня, в следующий раз можно будет поговорить о минимизации количества данных, копируемых с диска. Эта проблема отнюдь не тривиальна, так как файлы обычно храняться в виде типа PAK как, например в QUAKE. Для простых же программ можно посоветовать обнулить все WAV, AVI файлы. Для этого есть специальные утилиты, но, конечно, проще создать файл нулевой длинны с таким же именем, например по Shift-F4 в любом дисковом коммандере (DN,NC,etc.).
Для DOS существовала прекрасная утилита - FakeCD, которая подменяла MSСDEX и эмулировала таким образом CD-диск который, на самом деле, был каталогом на винчестере. Для Win95 такую программу найти не просто, поэтому необходимо ее сделать самим. Этим мы и займемся, тем более, что это будет прекрасная практика по копанию в недрах 95'ого.
Посмотрим на проблему, обсуждавшуюся раннее, с другой стороны. Заменим не использование функции, а саму функцию. Если в DOS для замены функций необходимо только было изменить обработчик прерываний, то в Windows такой финт уже не поможет. Выясним, где "живет" GetDriveType(). И - о ужас - это главная библиотека Win95 KERNEL32.DLL. Что делать? Как всегда, запастись кофе и напуcтить на KERNEL32.DLL дизассемблер. OK, ждем окончания процесса и смотрим список экспортируемых функций. Вот нужная нам:
Exported fn(): GetDriveTypeA - Ord:013Fh
:BFF777C4 57 push edi
:BFF777C5 6A21 push 00000021
...
...
...
:BFF777E1 F2 repnz
:BFF777E2 AE scasb
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:BFF777DA(C)
|
:BFF777E3 648F02 pop dword ptr fs:[edx]
:BFF777E6 83C408 add esp, 00000008
:BFF777E9 5F pop edi
:BFF777EA E9E5D4FFFF jmp BFF74CD4
Делаем переход в конце(кнопка Jump to на панели W32Dasm) и видим продолжение. Функция, оказывается-то, длинная! Не будем в ней разбираться, а лучше вспомним как происходит возврат значения из функции. Т.о. ищем строку типа
mov eax,03000000
Нашли? Далее, как и при любом взломе, запомним последовательность HEX кодов нужной команды (а лучше нескольких следующих, так как загрузка в аккумулятор числа 3 не самая редкая операция) и найдем этот блок в копии библиотеки (в копии - потому что файл используется системой и не может быть изменен). Все, осталось лишь в режиме DOS подменить KERNEL32.DLL. Перезагрузимся и в Проводнике насладимся результатом - все ваши жесткие диски представленны в виде кругленьких пластинок ранее обозначавших CD.
А теперь - для ленивых - кусок кода, который возвращает 3:
* Possible Reference to String Resource ID=00003: "....."
| :BFF74E0F B803000000 mov eax, 00000003 //Возвращаемое значение
:BFF74E14 EB05 jmp BFF74E1B //Переход на возврат
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:BFF74DEB(C), :BFF74DFC(C), :BFF74E0D(C)
|
* Possible Reference to String Resource ID=00006: "..."
Да - лучше сохранить старый KERNEL32, так как некоторые программы могут не оценить ваш юмор, и решить, что несколько CD и ни одного винчестера - это слишком. (комментарий Bad_guy: не рассчитывайте теперь на проверку винчестера scandisk'ом и на прочие винчестерные утилиты) А вообще идеально было бы изменить функцию коренным образом. Скажем сделать CD дисками все, начиная с T. Тогда можно было бы подключать subst'ом каталоги, которые были бы CD, а винчестеры остануться винчестерами. Но это уже задание на дом. Удачи!
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Автор: ED!SON [UCF]
Перевод: Mr.Boco/TCP
СОДЕРЖАНИЕ
==========
1. Введение в ломание Windows-программ
2. Обзор SoftICE/Win 2.oo
3. Поиск регистрационных кодов
3.1 Task Lock 3.00 - простая защита на
основе серийного номера
3.2 Command Line 95 - простая регситрация
"имя-код"
4. Создание генератора ключей для
Command Line 95
5. Как работают инструкции PUSH и CALL
когда программа вызывает функцию
6. О программах, написанных на Visual
Basic
ПРИЛОЖЕНИЯ
==========
A. Как в SoftICE загружать символьные
имена (имена функций etc)
B. Синтаксис функций GetWindowText,
GetDlgItemText и GetDlgItemInt
C. Где найти программы
D. Как связаться с автором
1. ВВЕДЕНИЕ В ЛОМАНИЕ WINDOWS-ПРОГРАММ
======================================
Ломать программы Windows в большинстве
случаев даже проще, чем ломать
программы Dos. В Windows сложно что-нибудь
скрыть от того, кто ищет,
особенно если программа использует
стандартные функции Windows.
Первая (и часто единственная) вещь,
которая Вам потребуется - это
SoftICE/Win 2.oo, мощный отладчик от фирмы
NuMega. Некоторым людям
он кажется очень сложным в
использовании, но я расскажу Вам,
как с
ним управляться и, я надеюсь, Вы
поверите мне. =) В приложении A я
привел некоторую информацию,
которую Вам следует прочитать.
URL всех программ, которые Вам
понадобятся, приведены в
приложении C.
- ED!SON, edison@ccnux.utm.my
2. ОБЗОР SOFTICE/WIN 2.OO
=========================
Ниже приведен очень схематичный
рисунок, демонстрирующий окно SoftICE:
|--------------------|
| Регистры | 'R' - правка значения регистров
|--------------------|
| Окно данных | 'D' - просмотр памяти, E' - правка памяти
|--------------------|
| Окно кода | 'U' - просмотр кода по адресу, 'A' - вставка кода
|--------------------|
| Окно команд | Здесь Вы набираете команды
|--------------------|
Другие важные клавиши (в
стандартной настройке):
'H'/F1 - помощь
F5/Ctrl+D - запуск программы (или
продолжение прерванной программы)
F8 - пошаговая отладка с заходом в
тело функции
F10 - пошаговая отладка без захода в
тело функции
F11 - выйти из функции (будет работать
только до первого PUSH в функции)
3. ПОИСК РЕГИСТРАЦИОННЫХ КОДОВ
==============================
Возможно, наилучший способ
попрактиковаться - это найти где-нибудь
шареварную (shareware) программку и
попытаться зарегистрировать ее.
3.1 Task Lock 3.00 - простая защита на
основе серийного номера
==============================================================
Это очень простая защита: номер не
зависит ни от каких факторов.
3.1.1 Медицинское обследование
==============================
Какой разрядности программа - 16 или
32 бит? Где вводится регистрационная
информация? Даст ли мне справка
какие-нибудь предположения о том,
как
устроена регистрация? Попробуйте
ответить на эти вопросы перед тем,
как
мы продолжим.
....Сейчас Вы должны быть заняты
обследованием....Вы заняты
обследованием?
...Ну как, уже все?...
OK, теперь Вы знаете, что это 32-битное
приложение, работающее под
Windows 95 и что регистрация
заключается в заполнении
регистрационного
номера в диалоговом окошке, которое
появляется когда Вы выбираете меню
"Register|Register...". Из справки Вам
также стало известно, что
существует
два типа регистрации: для
индивидуального использования и
для использования
в "конторе" (в оригинале - site
license). Поэтому очень вероятно, что
в программе будет ДВЕ проверки
регистрационных кодов.
3.1.2 Прерывание программы
==========================
Регистрационные коды чаще всего
вводятся в обычных строчках ввода
типа
Windows Edit. Чтобы проверить код,
программа должна прочитать
содержимое
строки ввода при помощи одной из
функций:
16-бит 32-бит
------ ------
GetWindowText GetWindowTextA, GetWindowTextW
GetDlgItemText GetDlgItemTextA, GetDlgItemTextW
Последняя буква в названии 32-битных
функций говорит о том, какие строки
использует эта функция:
однобайтовые или двухбайтовые.
Двухбайтовые
строки используются ОЧЕНЬ редко.
Возможно, что Вы уже уловили мою
мысль. "Если бы можно было
прерваться по
вызову GetWindowText..." - и Вы МОЖЕТЕ это
сделать!!! Но сперва Вы должны
убедиться, что символьные имена (имена
функций) загружены SoftICE'ом. Если
Вы не знаете, как это сделать - см.
приложение A.
Чтобы установить "ловушку" (на
самом деле это называется точкой
останова
или брейкпоинтом) в SoftICE, Вы должны
зайти в отладчик нажатием клавиш
Ctrl-D и использовать команду BPX. В
качестве параметра команды можно
использовать либо имя функции, либо
непосредственно адрес. Так как наш
"объект изучения" (Task Lock)
является 32-битным приложением, мы
должны
поставить брейкпоинт на функцию
GetWindowTextA. Если это не поможет,
попробуйте поставить брейкпоинт на
другие функции.
В командной строке SoftICE наберите
следующее:
:bpx getwindowtexta
Если Вы получите сообщение об
ошибке (например, "No LDT"),
убедитесь, что
в фоне у Вас не выполняются никакие
другие приложения. Я заметил, что
Norton Commander в фоне является причиной
подобного поведения SoftICE.
Вы можете проверить наличие
брейкпоинтов командой:
:bl
В результате Вы увидите что-нибудь
типа:
00) BPX USER32!GetWindowTextA C=01
Чтобы выйти из отладчика, нажмите
Ctrl-D (или F5) еще раз.
Продолжим... Итак, Вы установили
брейкпоинт и теперь SoftICE будет
"выскакивать" при каждом
вызове функции GetWindowTextA. Попробуем
ввести
какое-нибудь значение в окне
регистрации и нажмем OK. Вы
нажимаете OK...
...и получаете дурацкое сообщение о
том, что Ваш код был неправильным.
Значит, это была не функция
GetWindowTextA... Попробуем GetDlgItemTextA.
Удалим старый брейкпоинт:
:bc 0
(0 - это номер брейкпоинта в списке
брейкпоинтов)
И установим новый:
:bpx getdlgitemtexta
Ну что ж, попробуем еще раз...
3.1.3 В отладчике
=================
Wow! Работает! Теперь вы в SoftICE, в
самом начале функции GetDlgItemTextA.
Чтобы попасть туда, откуда она была
вызвана, нажмите F11. Теперь Вы
внутри
модуля SGLSET.EXE. Если Вы не уверены -
посмотрите на строчку между окном
кода и окном командной строки, она
должна выглядеть так:
----------SGLSET!.text+1B13----------
Сейчас Вы уже можете запретить
реакцию на вызов функции:
:bd 0
Если Вам вдруг захочется снова
разрешить ее, наберите:
:be 0
Первая строка в окне кода выглядит
так:
CALL [USER32!GetDlgItemTextA]
Чтобы посмотреть строчки над ней,
нажимайте Ctrl+Up ("стрелка вверх")
до
тех пор, пока не увидите
нижеприведенный кусок кода. Если Вы
ничего не
понимаете в Ассемблере, я добавил
комментарии которые могут Вам
помочь.
RET ; Конец функции
PUSH EBP ; Начало другой функции
MOV EBP, ESP ; ...
SUB ESP, 0000009C ; ...
PUSH ESI ; ...
> LEA EAX, [EBP-34] ; EAX = EBP-34
PUSH EDI ; ...
MOVE ESI, ECX ; ...
PUSH 32 ; Макс. длина строки
> PUSH EAX ; Адрес текстового буфера
PUSH 000003F4 ; Идентификатор управления
PUSH DWORD PTR [ESI+1C] ; Идентификатор окна
диалога
CALL [USER32!GetDlgItemTextA] ; Получить текст
Команды PUSH означают сохранение
значений для последующего
использования.
Я пометил важные строчки символом
'>'. Глядя на этот код, мы видим, что
адрес текстового буфера хранился в
регистре EAX и что EAX был EBP-34h.
Поэтому нам стоит взглянуть на EBP-34h:
:d ebp-34
Вы должны были увидеть текст,
который вы ввели в диалоговом окне.
Теперь мы
должны найти место, где Ваш номер
сравнивается с реальным серийным
номером.
Поэтому мы пошагово трассируем
программу при помощи F10 до тех пор,
пока
не встретим что-нибудь о EBP-34. Не
пройдет и нескольких секунд, как Вы
наткнетесь на следующий код:
> LEA EAX, [EBP+FFFFFF64] ; EAX = EBP-9C
LEA ECX, [EBP-34] ; ECX = EBP-34
PUSH EAX ; Сохраняет EAX
PUSH ECX ; Сохраняет ECX
> CALL 00403DD0 ; Вызывает функцию
ADD ESP, 08 ; Удаляет сохраненную
информацию
TEST EAX, EAX ; Проверяет значение
функции
JNZ 00402BC0 ; Прыгает, если не "ноль"
Мне кажется, что это выглядит как
вызов функции сравнения двух строк.
Эта функция работает так: на входе -
две строки, на выходе - 0, если
они равны и любое другое значание,
если не равны.
А зачем программе сравнивать какую-то
строчку с той, что Вы ввели в окне
диалога? Да затем, чтобы проверить
правильность Вашей строки (как Вы,
возможно, уже догадались)! Так-так,
значит этот номер скрывался по
адресу
[EBP+FFFFFF64]? SoftICE не совсем корректно
работает с отрицательными
числами и поэтому настоящий адрес
следует посчитать:
100000000 - FFFFFF64 = 9C
Вы можете сделать это вычисление
прямо в SoftICE:
:? 0-FFFFFF64
Число 100000000 слишком велико для SoftICE,
а вычитание из 0 дает тот же
самый результат.
Наконец пришло время взглянуть, что
же скрывается по адресу EBP-9C...
:d ebp-9c
В окне данных SoftICE Вы видите длинную
строчку цифр - это серийный номер!
Но Вы помните, что я говорил Вам
раньше? Два типа регистрации - два
разных
серийных номера. Поэтому после того,
как Вы записали на бумажечку первый
серийный номер, продолжайте
трассировать программу при помощи
F10. Мы
дошли до следующего куска кода:
> LEA EAX, [EBP-68] ; EAX = EBP-68
LEA ECX, [EBP-34] ; ECX = EBP-34
PUSH EAX ; Сохраняет EAX
PUSH ECX ; Сохраняет ECX
> CALL 00403DD0 ; Снова вызывает функцию
ADD ESP, 08 ; Удаляет сохраненную
информацию
TEST EAX, EAX ; Проверяет значение
функции
JNZ 00402BFF ; Прыгает если не "ноль"
И что Вы видите по адресу EBP-68?
Второй серийный номер!
:d ebp-68
Вот и все... Я надеюсь, что у Вас все
получилось как доктор прописал? =)
3.2 Command Line 95 - легкая регистрация "имя-код",
создание генератора ключей
======================================================================
Это программа - хороший пример, с
легким алгоритмом генерации кода.
3.1.1 "Обследование"
====================
Вы осмотрели программу и увидели,
что это 32-битное приложение,
требующее
имя и код в окне регистрации.
Поехали!
3.1.2 Прерывание программы
==========================
Мы поступаем так же, как и с Task Lock'ом
- ставим брейкпоинты. Можно даже
поставить сразу два брейкпоинта на
наиболее возможные функции:
GetWindowTextA и GetDlgItemTextA. Нажмите Ctrl-D,
чтобы вызвать отладчик
и наберите в окне команд:
:bpx getwindowtexta
:bpx getdlgitemtexta
Теперь возвращайтесь в прерванную
программу, идите в окно регистрации
и
вводите имя и какой-нибудь номер (обыкновенное
целое число - это наиболее
вероятный код). Я написал примерно
следующее:
Name: ED!SON '96
Code: 12345
Программа остановилась на GetDlgItemTextA.
Так же, как и в случае с Task
Lock'ом, мы нажимаем F11 чтобы
вернуться в вызывающюю функцию.
Просматриваем
окно кода при помощи Ctrl+Up. Вызов
функции выглядит так:
MOV ESI, [ESP+0C]
PUSH 1E ; Максимальная длина
PUSH 0040A680 ; Адрес буфера
PUSH 000003ED ; Идентификатор управления
PUSH ESI ; Идентификатор окна диалога
CALL [User32!GetDlgItemTextA]
Число 40A680 кажется нам интересным,
поэтому мы проверяем этот адрес:
:d 40a680
Что же видно в окне данных, как не
имя, которое мы ввели? =) А теперь
взглянем на кусок кода под
вышеприведенным:
PUSH 00 ; (не интересно)
PUSH 00 ; (не интересно)
PUSH 000003F6 ; Идентификатор управления
MOV EDI, 0040A680 ; Адрес буфера
PUSH ESI ; Идентификатор окна диалога
CALL [User32!GetDlgItemInt]
Функция GetDlgItemInt похожа на GetDlgItemTextA,
но возвращает не строку,
а целое число. Она возвращает его в
регистре EAX, поэтому мы трассируем
этот код (F10) и смотрим, что же у нас
появилось в окне регистров после
вызова функции... В моем случае оно
выглядит так:
EAX=00003039
А что такое шестнадцатеричное 3039?
Наберем:
:? 3039
И получим следующее:
00003039 0000012345 "09"
^ hex ^ dec ^ ascii
Как Вы видите (и, возможно, уже
догадались) это код, который Вы
ввели
в диалоговом окне. Ok, что теперь?
Посмотрим дальше:
MOV [0040A548], EAX ; Сохраняет рег. код
MOV EDX, EAX ; А также помещает его в EDX
3.1.3 Подсчитывание регистрационного
кода
=========================================
Мы достигли места, где
подсчитывается реальный
регистрационный код!
MOV ECX, FFFFFFFF ; Эти строчки
подсчитывают
SUB EAX, EAX ; длину строки
REPNZ SCASB ; .
NOT ECX ; .
DEC ECX ; ECX теперь содержит длину
MOVSX EAX, BYTE PTR [0040A680] ; Получает байт по
адр. 40A680h
IMUL ECX, EAX ; ECX = ECX * EAX
SHL ECX, 0A ; Сдвиг влево на 0Ah бит
ADD ECX, 0002F8CC ; Добавляет 2F8CC к
результату
MOV [0040A664], ECX
...И где он проверяется
CMP ECX, EDX ; Сравнивает числа
JZ 00402DA6 ; Прыгает, если равны
Когда Вы дотрассировали до
сравнения чисел, Вы можете
посмотреть, каким
должен был быть Ваш РЕАЛЬНЫЙ
регистрационный код:
:? ecx
В моем случае это дало:
000DC0CC 0000901324
То есть, правильный код для меня:
901324.
Нажмем F5 или Ctrl-D чтобы вернуться в
программу и попробуем еще раз, но
на этот раз с правильным кодом (в
десятичной форме). Работает!
4. СОЗДАНИЕ ГЕНЕРАТОРА КЛЮЧЕЙ ДЛЯ
COMMAND LINE 95
=================================================
Взглянем на алгоритм генерации
кода и попробуем перевести его на
язык Си.
Вот очень простая формула, по
которой подсчитывается ключ:
code = ((uppercase_first_char * length_of_string) << 0x0A)
+ 0x2f8cc;
Замечание #1: Не следует забывать,
что все символы в окне ввода имени
были приведены к верхнему регистру,
поэтому мы должны сделать то же.
Замечание #2: "<< 0x0A" означает
"умножние на 2 в степени 10"
Целиком программа на Си выглядит
так:
#include <string.h>
#include <stdio.h>
int main()
{
unsigned long code;
unsigned char buffer[0x1e];
printf("CommandLine95 Keymaker by ED!SON '96\n");
printf("Enter name: ");
gets(buffer);
strupr(buffer);
code = ( ((unsigned long)buffer[0] *
(unsigned long)strlen(buffer))
<< 0x0A) + 0x2f8cc;
printf("Your code is: %lu", code);
return 0;
}
Приятных сновидений!
4. КАК РАБОТАЮТ PUSH И CALL КОГДА
ПРОГРАММА ВЫЗЫВАЕТ ФУНКЦИЮ
============================================================
Снова взглянем на кусок кода из Task
Lock'а:
PUSH 32 ; Макс. длина строки
PUSH EAX ; Адрес текстового буфера
PUSH 000003F4 ; Идентификатор управления
PUSH DWORD PTR [ESI+1C] ; Идентификатор окна
диалога
CALL [USER32!GetDlgItemTextA] ; Получает текст
Когда Вы вызываете функцию GetDlgItemTextA
из программы на C, вызов
выглядит так:
GetDlgItemTextA(hwndDlg, 0x3F4, buffer, 0x32);
^ [ESI+1C] ^ EAX
PUSH сохраняет данные в области
памяти, называемой стеком. В
результате
каждого PUSH'а новый кусок данных
помещается в верхушку стека и затем
вызываемая функция проверяет, что
лежит в стеке и использует эти
данные
по своему усмотрению.
5. О ПРОГРАММАХ НА VISUAL BASIC
===============================
EXE файлы, производимые Visual Basic'ом, не
являются настоящими EXE. Они
просто содержат код для вызова
VBRUNxxx.DLL, который затем читает данные
из EXE и выполняет программу. Такое
устройство псевдо-EXE файлов
является
также причиной того, что программы
на Visual Basic'е такие медленные.
А так как EXE файлы не являются
настоящими EXE файлами, Вы не можете
трассировать и дизассемблировать
их - Вы найдете вызов функции из DLL
и кучу мусора. И когда Вы будете
трассировать такую программу, Вы
"заблудитесь" в DLL.
Решением этой проблемы является
декомпилятор. Существует
декомпилятор для
программ, написанных на Visual Basic'е
версий 2 и 3, созданный кем-то,
называющим себя DoDi. Эта программя
является шареварной и ее можно
найти
в InterNet'е (см. Приложение C). Для
программ, написанных на Visual Basic'е
версии 4 (VB для Windows 95), не существует
декомпилятора, насколько мне
известно, хотя я бы хотел, чтобы он
существовал. =)
(Комментарий Bad_guy'я): Начиная с версии 5
Visual Basic создаёт небольшие куски "чистого"
кода, т.е. полученные программы ломаются SoftIce'ом.
Примечание: Настоящие программисты
не пишут на Basic'е. =)
====================================================================
ПРИЛОЖЕНИЯ
====================================================================
A. КАК В SOFTICE ЗАГРУЖАТЬ СИМВОЛЬНЫЕ
ИМЕНА
===========================================
Чтобы проверить, загрузил ли SoftICE
символьные имена GetWindowText, Вы
должны войти в отладчик нажатием на
клавиши Ctrl-D и в окне команд ввести
следующее:
:exp getwindowtext
Если Вы не получили списка всех
функций GetWindowText, Вам нужно
отредактировать файл \SIW95\WINICE.DAT,
удалив символ комментария (';')
перед одной из строчек 'exp=', которые
следуют за текстом: "Examples of
export symbols that can be included for chicago" в
конце этого файла.
Вы можете удалить комментарии из
всех строчек 'exp=' или сохранить
немножко памяти, раскомментировав
только строчки с файлами kernel32.dll,
user32.dll и gdi32.dll, которые являются
самыми важными. После этого Вы
должны перегрузить компьютер.
B. СИНТАКСИС НЕКОТОРЫХ ФУНКЦИЙ
==============================
Вам будет легче понять, как
вызываются функции, о которых мы
говорили,
если Вы будете знать их описания (декларации):
int GetWindowText(int windowhandle, char *buffer, int maxlen);
int GetDlgItemText(int dialoghandle, int controlid, char *buffer,
int maxlen);
int GetDlgItemInt(int dialoghandle, int controlid, int *flag, int
type);
Если Вам нужна более подробная
информация, посмотрите в
руководстве
программиста Windows/Win32.
C. ГДЕ НАЙТИ ПРОГРАММЫ
======================
ПРОГРАММЫ ДЛЯ ВЗЛОМА
SoftICE/Win 2.oo:
http://www.geocities.com/SoHo/2680/cracking.html
Декомпилятор VB:
ftp://ftp.sn.no/user/balchen/vb/decompiler/
ПРОГРАММЫ, ИСПОЛЬЗОВАННЫЕ В
КАЧЕСТВЕ ПРИМЕРА
TaskLock: http://users.aol.com/Sajernigan/sgllck30.zip
CommandLine 95:
ftp://ftp.winsite.com/pub/pc/win95/miscutil/cline95.zip
D. КАК СВЯЗАТЬСЯ С АВТОРОМ
==========================
На IRC (EFNet): Каналы #Ucf96, #Cracking
E-mail: edison@ccnux.utm.my или an461165@anon.penet.fi
На моей WWW-страничке:
http://www.geocities.com/SoHo/2680/cracking.html
====================================================================
Материалы находятся на сайте http://cracklab.narod.ru/doc/
Что за бред, подумает читатель, прочитав название этой статьи. Как можно сгенерировать ключ, если алгоритм генерации полностью не известен? Но я гарантирую, что, прочитав эту статью, вы убедитесь, что и такое возможно... Итак приступим.
Мне понадобилось перевести несколько видеороликов в стандарт MPEG, а для сего я скачал с www.download.com XingMPEG Encoder 2.20 – во всех отношениях просто замечательную программу, кроме одного: это trial-версия (т.е. она работает только 30 дней), но главное – trial позволяет делать файлы не более 30 секунд. А поскольку большинство роликов заметно больше 30 секунд, мы займемся исправлением этого недоразумения.
Для начала с помощью SoftICE. При запуске программы появится окошко с логотипом фирмы и сообщением, что это не полная версия. Внизу окошка – бегунок, показывающий количество дней до конца халявы, а так же 3 кнопки: "Buy Now", "Try First" и "Cancel".
Нажимаем кнопку "Buy Now" и попадаем в окно регистрации, где заполним больше десятка полей всяческой ерундой. Пару раз щелкаем "Дальше". Попали в окошко, где надо вводить данные о кредитной карточке. Я заполнил поля так:
Тип карточки – American Express
Card Number – 1234 1234 1234 1234
Expiration – 11/11
Name on card – You!
Трижды щелкаем "Дальше", и попадем в окно с выбором платежа. Выберем "ORDER BY MAIL/FAX", т.к. все остальные отпадают по понятным причинам. Теперь, когда мы снова запустим программу и нажмем "Buy Now", мы попадем в само окно регистрации, где и необходимо ввести код, якобы присланный нам по почте после оплаты.
Теперь поставим в SoftICE контрольную точку на выполнение MessageBoxA(). Вводим в окно для кода любое число, но меньше 10 знаков (можно и 10, но тогда придется прокручивать страниц пять текста, чтобы найти команду перехода). Щелкаем "ОК" и попадаем в SoftICE. Жмем F12, "ОК" в окошке с сообщением о неверном коде, и попадаем обратно в SoftICE. Наблюдаем такую картину:
:10005635 call [user32!MessageBoxA]
:1000563B mov ecx, [10031774] <--- Мы здесь.
:10005641 or eax, -01
Прокрутим код немного вверх, пока не натолкнемся на строчки:
:1000560C repnz scasb
:1000560E not ecx
:10005610 dec ecx
:10005611 cmp ecx, 0A <---- Проверка длины.
:10005614 jz 10005655 <---- Сюда bpx.
:10005616 lea edx, [esp+10]
Отключим предыдущие контрольные точки, и поставим новую на выполнение команды jz 10005655 (просто двойным щелчком по этой строке), вернемся в программу и введем теперь точно 10 цифр в окно для кода (а можно просто поменять значение регистра флагов Z) и снова попытаемся зарегистрироваться. Произойдет остановка на jz 10005655 (JUMP), протрассируем (F10) немного программу, пока не дойдем до места:
:10005698 push ecx
:10005699 push edx
:1000569A push eax
:1000569B call 1000B950 <---- Остановимся тут.
:100056A0 add esp, 0C
Не выполняя команду call, посмотрим что ей передается:
d ecx – пусто
d edx – крупненькая константа = Er5286RteWa2314HmN
d eax – номер, у меня – 4872151134
Из всего этого можно сделать вывод, что следующая команда call запускает внешнюю функцию, которая сгенерирует правильный код.
Проверим это, выполнив call. Посмотрим, что теперь находится в ранее пустом ecx:
d ecx – регистрационный код, у меня – QLRHMLIRYR
На этом первая часть заканчивается. Теперь можно ввести код в окне регистрации – и полностью рабочий XingMPEG Encoder 2.20 у нас в руках.
Убрать регистрацию можно так:
А теперь о главном: как сделать генератор РН, не зная алгоритма его вычисления?
Для примера возьмём все тот же XingMPEG Encoder v2.20 (как найти правильный РН с помощью SoftICE я объяснять здесь не буду, об этом мы уже говорили в первой части, да и о нахождении большинства необходимых данных можно прочитать там же).
Поставив нужную контрольную точку, мы наткнёмся на процедуру генерации РН:
:10005698 51 push ecx
:10005699 52 push edx
:1000569A 50 push eax
:1000569B E8B0620000 call 1000B950
:100056A0 83C40C add esp, 0C
Обращаем внимание на то, что процедура эта находится в rsagnt32.dll. Также уделяем внимание EIP, из которого можно сделать вывод, что rsagnt32.dll грузилась по стандартному адресу 10000000. Так что несложно будет вычислить адрес и самой функции: 1000В950h – 10000000h = В950h. Самое время посмотреть, какие функции являются в rsagnt32.dll экспортируемыми (для этой цели я использовал DumpBin).
Вот собственно и есть эти функции:
Ordinal Hint RVA Name
1 0 00002A40 SAAddProductItem
2 1 00011590 SAChargeTax
3 2 00011580 SACheckEnable
4 3 00002B70 SACleanup
5 4 00002930 SAInitialize
6 5 0000E350 SAPurchaseOrderEnable
7 6 000085B0 SAPurchaseOrderSetFaxNumber
8 7 0000E360 SAPurchaseOrderSetInstParagraph
9 8 0000E3C0 SAPurchaseOrderSetOrderInfoParagraph
10 9 00010660 SAReceiptSetNoSerialNumber
11 A 00010600 SAReceiptSetParagraph
12 B 000115A0 SASelectTransMethod
13 C 000029E0 SASetHelpDir
14 D 000088E0 SASetMailInstruction
15 E 00008930 SASetNoWaitMail
16 F 00002980 SASetScreenText
17 10 00008580 SASetVendorName
18 11 000012E0 startSalesAgent
И что же мы видим? А ничего. Экспортируемой функции с RVA=0000В950 просто нет!
Вот теперь мы перейдём к самому интересному. А что если нам написать программку (я использовал С++), которая будет делать следующее:
:10005698 51 push ecx <----- Buffer
:10005699 52 push edx <----- Const
:1000569A 50 push eax <----- PersonalCode
:1000569B E8B0620000 call 1000B950 <----- Вызов ф-ции
:100056A0 83C40C add esp, 0C <----- Правка стека
Теперь к самой программе:
char* Const="Er5286RteWa2314HmN";
char Buffer[10];
char* PersonalCode="4872151134" //PersonalCode можно читать из rsagent.ini
// используя GetPrivateProfileString()
Саму же функцию нам придётся вызывать с помощью Ассемблера, т.к она не является экпортируемой, после вызова будет неправильно выставлен стек, что приведёт непосредственно к сбою системы.
_asm
{
push offset Buffer
mov eax, [Const]
push eax
mov eax, [PersonalCode]
push eax
call dword ptr [KeyMaker] // KeyMaker это и есть адрес функции, который мы вычислили
add esp, 0x0C
}
После всего этого в Buffer стоит правильный РН. Ну что, смог я вас убедить?
Для интересующихся предоставляю исходные коды генератора РН.
Материалы находятся на сайте http://cracklab.narod.ru/doc/