Сегодня мы зарегистрируем программу CDRWin 4.0. Анализировать будем файл cdrwin.exe размером 1024000
байт. Запускаем программу и видим, что это демонстрационный режим, в котором все операции с записью будут происходить на 1-ой скорости. Значит нужно зарегистрироваться, нажимаем кнопку Unlock Program и вводим любой мусор, и нажимаем Unlock. Выскакивает окно "Bad key format" (Неверный формат ключа).
Запускаем Win32DASM - дисассемблируем cdrwin.exe.
Найдём то место в программе, где выскакивает окно с ошибкой ключа. Для этого выбираем в меню Refs\String Data References и находим строку
String Resource ID=00202: "Bad key format"
двойным щелчком находим это место в программе
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
:0041DED7(C), :0041DF01(C)
* Possible Reference to String Resource ID=00255: "Invalid disc count specified."
:0041DF74 6AFF push FFFFFFFF
:0041DF76 6A00 push 00000000
* Possible Reference to String Resource ID=00202: "Bad key format"
:0041DF78 68CA000000 push 000000CA
:0041DF7D E812350500 call 00471494
На этот кусок кода можно попасть из двух мест, а именно 0041DED7, 0041DF01. Выбираем Goto\Goto Code Location и вводим первый адрес. Чуть выше видим такую строку
* Possible StringData Ref from Data Obj ->"%lx-%lx-%lx-%lx"
Эта функция используется для форматирования текстовой строки. После знака % идут служебные символы, узнать о них можно в файле win32.hlp в функции wsprintf.
Ключ %lx означает, что здесь должно находиться длинное целое шестнадцатеричное число в нижнем регистре.
Как видим этих чисел должно быть четыре, разделённые знаком минус. Теперь Unlock key и Check key нужно ввести в этом формате. Если ввели всё правильно, то должно появиться другое окно с ошибкой, а именно "Error: Unlock keys have been enterred incorrectly" (Ошибка: Отпирающий ключ был введён неверно). Это означает, что первую стадия проверки мы прошли, осталось самое сложное, чтобы Check key удовлетворял Unlock
key.
Глядя на продолжение программы, мы видим проверку второго ключа, а за ним:
:0041DF16 E8256B0000 call 00424A40
по этому адресу происходит проверка наших ключей.
Примечание: в скобках приведены примеры для лучшего понимания.
Допустим, вы ввели
Unlock key:1-2-3-4
Check key :5-6-7-8
В памяти наши введённые ключи представлены в таком порядке
ссылка | значение по адресу ссылки |
ecx=[esp+10] | 00000008 |
esi=[esp+18] | 00000004 |
[esi+0] | 00000004 |
[esi+4] | 00000003 |
[esi+8] | 00000002 |
[esi+C] | 00000001 |
[esi+10]=[ecx+0] | 00000008 |
[esi+14]=[ecx+4] | 00000007 |
[esi+18]=[ecx+8] | 00000006 |
[esi+1C]=[ecx+C] | 00000005 |
:00424A40 8B4C2410 mov ecx, dword ptr [esp+10]
:00424A44 53 push ebx
:00424A45 55 push ebp
:00424A46 56 push esi
:00424A47 8B742418 mov esi, dword ptr [esp+18] ; esi=4
:00424A4B 8B19 mov ebx, dword ptr [ecx] ;
ebx=8
:00424A4D 57 push edi
:00424A4E 8B3E mov edi, dword ptr [esi] ; edi=4
:00424A50 8B4604 mov eax, dword ptr [esi+04] ; eax=3
:00424A53 8BD7 mov edx, edi ;
edx=4
:00424A55 33D0 xor edx, eax ; edx=edx xor eax (4 xor 3=7)
:00424A57 3BDA cmp ebx, edx ;
сравнивается наше введённое 8 и полученные 7
:00424A59 7525 jne 00424A80 ; если не равны, то переходим на указанную метку, т.е. ключ не правильный
:00424A5B 8B5608 mov edx, dword ptr [esi+08] ; edx=2
:00424A5E 8BDA mov ebx, edx ; ebx=2
:00424A60 33D8 xor ebx, eax ; edx=ebx xor eax (2 xor 3=1)
:00424A62 8B4104 mov eax, dword ptr [ecx+04] ; eax=7
:00424A65 3BC3 cmp eax, ebx ; сравнивается наше введённое 7 и полученные 1
:00424A67 7517 jne 00424A80 ; если не равны, то переходим на указанную метку, т.е. ключ не правильный
:00424A69 8B460C mov eax, dword ptr [esi+0C] ; eax=1
:00424A6C 8BD8 mov ebx, eax ; ebx=1
:00424A6E 33DA xor ebx, edx ; ebx=ebx xor edx (1 xor 2=3)
:00424A70 8B5108 mov edx, dword ptr [ecx+08] ; edx=6
:00424A73 3BD3 cmp edx, ebx ; сравнивается наше введённое 6 и полученные 3
:00424A75 7509 jne 00424A80 ; если не равны, то переходим на указанную метку, т.е. ключ не правильный
:00424A77 8B510C mov edx, dword ptr [ecx+0C] ; edx=5
:00424A7A 33C7 xor eax, edi ; eax=eax xor edi (1 xor 4=5)
:00424A7C 3BD0 cmp edx, eax ; сравнивается наше введённое 5 и полученные 5
:00424A7E 7413 je 00424A93 ; если равны, то переходим на указанную метку, т.е. ключ правильный
Краткое резюме:
8 cmp (4 xor 3)
7 cmp (3 xor 2)
6 cmp (2 xor 1)
5 cmp (1 xor 4)
Чтобы эти условия выполнялись, Check key должен быть 5-3-1-7.
:00424A9E E8FD040000 call 00424FA0 ; Здесь происходит проверка Unlock key с Name & Company
Включает в себя:
:00424FA0 8B44240C mov eax, dword ptr [esp+0C] ;
[eax]=00000004
:00424FA4 8B542404 mov edx, dword ptr [esp+04] ; по адресу edx находится введённое вами имя
:00424FA8 53 push ebx
:00424FA9 55 push ebp
:00424FAA 8B18 mov ebx, dword ptr [eax] ; ebx=4
:00424FAC 57 push edi
:00424FAD 8BFA mov edi, edx ; edi=первый символ вашего имени
:00424FAF 83C9FF or ecx, FFFFFFFF ; ecx=FFFFFFFF
:00424FB2 33C0 xor eax, eax ; eax=0
:00424FB4 F2 repnz ; цикл ПОКА флаг нуля не будет поднят (пока не равно 0)
:00424FB5 AE scasb ; сравнивает байт (последний символ команды B) по адресу es:edi и прибовляет edi+1
:00424FB6 F7D1 not ecx ; инвертирует ecx (ecx=FFFFFFFF-ecx), длинна имени + символ 00
:00424FB8 49 dec ecx ; вычитаем из ecx 1 (минус нулевой символ)
:00424FB9 83F906 cmp ecx, 00000006 ; сравниваем ecx с 6
:00424FBC 726B jb 00425029 ; переход если ecx<6 , т.е. имя не удовлетворяет
:00424FBE 8B6C2414 mov ebp, dword ptr [esp+14] ; по адресу edp находится введённое вами E-Mail
:00424FC2 83C9FF or ecx, FFFFFFFF ; ecx=FFFFFFFF
:00424FC5 8BFD mov edi, ebp ; edi ссылается на ваш E-Mail (нужно для операнда
scasb)
:00424FC7 F2 repnz ; цикл ПОКА флаг нуля не будет поднят (пока не равно 0)
:00424FC8 AE scasb ; сравнивает байт (последний символ команды B) по адресу es:edi и прибавляет edi+1
:00424FC9 F7D1 not ecx ; инвертирует ecx (ecx=FFFFFFFF-ecx), длинна имени + символ 00
:00424FCB 49 dec ecx ; вычетаем из ecx 1 (минус нулевой символ)
:00424FCC 83F906 cmp ecx, 00000006 ; сравниваем ecx с 6
:00424FCF 7258 jb 00425029 ; переход если ecx<6, т.е. е-почта не удовлетворяет
:00424FD1 F7C3FFFF0000 test ebx, 0000FFFF ; напомню ebx=00000004 (команда вычитает из ebx 0000FFFF, выставляет флаги но результат не сохраняет
:00424FD7 7450 je 00425029 ; в данном случаи проверяется чтобы младшие 2 байта четвёртого ключа Unlock key должны быть не равны 0
:00424FD9 F7C30000FFFF test ebx, FFFF0000
:00424FDF 7448 je 00425029 ; в данном случаи проверяется чтобы старшие 2 байта четвёртого ключа Unlock key должны быть не равны 0
Затем программа преобразовывает Name & Company и получает два четырёх битных числа. Преобразование происходит с использованием её собственных матриц, поэтому подробно рассматривать не будем.
Затем программа из полученных чисел формирует одно, которое затем сравнивает с четвёртым ключом Unlock key.
:00424FE1 56 push esi
:00424FE2 6A02 push 00000002
:00424FE4 52 push edx
:00424FE5 E846000000 call 00425030 ; в зависимости от введённого вами NAME функция возвращает в eax определённое число (Допустим
eax=12345678)
:00424FEA 6A02 push 00000002
:00424FEC 55 push ebp
:00424FED 8BF0 mov esi, eax ; esi=eax
(esi=12345678)
:00424FEF E83C000000 call 00425030 ; в зависимости от введённого вами E-MAIL функция возвращает в eax определённое число (Допустим
eax=90ABCDEF)
:00424FF4 8BC8 mov ecx, eax ; ecx=eax
(ecx=90ABCDEF)
:00424FF6 8BD0 mov edx, eax ; edx=eax
(edx=90ABCDEF)
:00424FF8 81E10000FF00 and ecx, 00FF0000 ; ecx=00??0000 (как бы накладываем маску с прорезью в место FF, а всё что закрыли - равно 0. После выполнения
ecx=00AB0000)
:00424FFE 83C410 add esp, 00000010
:00425001 C1EA10 shr edx, 10 ; побитно сдвиг вправо становится
edx=000090AB)
:00425004 0BCA or ecx, edx ; соединяют(не складывают) ecx и edx (ecx=00AB0000 и edx=000090AB, после выполнения
ecx=00AB90AB)
:00425006 8BD0 mov edx, eax ; edx=eax
(edx=90ABCDEF)
:00425008 81E200FF0000 and edx, 0000FF00 ; (edx=0000CD00)
:0042500E C1E010 shl eax, 10 ; побитно сдвиг влево (становится
edx=CDEF0000)
:00425011 0BD0 or edx, eax ; edx=CDEFCD00
:00425013 33C0 xor eax, eax ; eax=0
:00425015 C1E908 shr ecx, 08 ; ecx=0000AB90
:00425018 C1E208 shl edx, 08 ; edx=EFCD0000
:0042501B 0BCA or ecx, edx ; ecx=EFCDAB90
:0042501D 33CE xor ecx, esi ; ecx=ecx xor esi (EFCDAB90^12345678=), вставив это калькулятор мы получим ответ
ecx=FDF9FDE8
:0042501F 5E pop esi
:00425020 3BCB cmp ecx, ebx ; полученный ecx сравнивают с нашим введённым
ebx=00000004
Здесь мы видим, что четвёртый ключ Unlock key'я зависит от введённого нами имени и почты. Теперь начинаем сначала:
1. Вводим свое имя
2. E-MAIL
3. ????????-????????-????????-хххххххх
4. ????????-????????-????????-???????? ; удовлетворяющих условию XOR
Ставим бреакпоинт (клавиша F2) на адрес 42501D, после её выполнения у нас в регистре ECX будет четвёртый ключ Unlock key (который хххххххх). Теперь снова пересчитываем ключи с уже полученным хххххххх. У меня получились такие:
Bazanov Ivan
Home Office
123c432a-6a5fce47-8acf43ea-4758411e
55640234-78638D6D-E0908DAD-CD9702F4
И вот потирая ручки жмём Unlock, но программа ругается, что срок годности твоего ключа вышел год назад. Анализируем дальше:
:00424ABA 8B1E mov ebx, dword ptr [esi] ;
ebx=4758411Е (4 ключ Unlock key)
:00424ABC C1EB10 shr ebx, 10 ; сдвигаем на 4 символа вправо(00004758)
:00424ABF 66335E04 xor bx, word ptr [esi+04] ; хорим с 3 ключом (только младшие 2 байта [esi+04]=43ea),(bx=04В2)
:00424AC3 81E3FFFF0000 and ebx, 0000FFFF ; берём только младшие 2 байта(ebx=000004В2)
:00424AC9 8D43F1 lea eax, dword ptr [ebx-0F] ; eax=ebx-0F(eax=000004A3)
:00424ACC 3DC8040000 cmp eax, 000004C8 ; eax должен равняться 4С8
Применим reverse engineering (пойдём в обратном порядке и получим 3 ключ):
eax=4c8
eax=eax+0F=4D7
xor 4D7, 4758 = 438F ; т.е. младшие 2 байта 3 ключа Unlock key должны быть равны 438F, а старшие 2 байта могут быть любые.
Снова пересчитываем ключи, для скорости вставляем это в калькулятор без скобок (8acf438f^4758411e=), не забудь переключить калькулятор в НЕХ режим (клавиша F5). Это аналогично 8acf438f XOR 4758411e. Получаем новые ключи.
123c432a-6a5fce47-8acf438f-4758411e
55640234-78638D6D-E0908DC8-CD970291
Вот на этом вроде и всё. А вот и нет, при следующем запуске программы она говорит, что зарегистрирована пиратским ключом и отказывается работать вовсе. Значит наши введённые данные где-то сохранились. Поиск в реестре ничего не дал, значит они находятся в каком-то файле. Взглянув на файлы находившиеся в каталоге установленной программы приходим к выводу, что файл Cdrwin.da тот что нам нужен, т.к.
INSTALL.LOG - логи установки
Cdrwin.exe - сама программа
Cdrwin.dat - неизвестный файл
Cdrwin.hlp - файл помощи
Cdrwin.cnt - файл индекса справки
Cleanup.exe - программа UnInstell
Находим ссылки на строку содержащую названия этого файла:
* Possible StringData Ref from Data Obj ->"CDRWIN.DAT"
:004034F6 68C4524A00 push 004A52C4
:004034FB C645FC01 mov [ebp-04], 01
:004034FF E80C130200 call 00424810 ; эта процедура открывает и считывает данные из файла
:00403504 83C40C add esp, 0000000C
:00403507 895DFC mov dword ptr [ebp-04], ebx
:0040350A E861220200 call 00425770 ; возвращает в eax ответ
:0040350F 85C0 test eax, eax ; если eax не равен 0
:00403511 7542 jne 00403555 ; то переходим по указанной метке
Кусок функции по адресу 425770:
:00425793 E8781A0200 call 00447210 ;
эта функция возвращает число в eax
:00425798 C1E810 shr eax, 10 ; сдвигает его на 4 символа в право
:0042579B 33D2 xor edx, edx ; edx=0
:0042579D 663905262D4B00 cmp word ptr [004B2D26], ax ; сравнивает сдвинутое число с двумя старшими байтами нашего 3 ключа Unlock key
:004257A4 0F94C2 sete dl
:004257A7 8BC2 mov eax, edx
:004257A9 83C424 add esp, 00000024
:004257AC C3 ret
В моём случаи ах=ACD2, значит, третий ключ будет ACD2438F. Чтобы была возможность ввести ключи снова, восстанови файл Cdrwin.dat. Для этого напиши в командной строке pkunzip -e cdr40a-e.exe cdrwin.dat. Опять генерим ключи, в итоге получились такие:
Bazanov Ivan
Home Office
123C432A-6A5fCE47-ACD2438F-4758411E
55640234-78638D6D-C68D8DC8-EB8A0291
С точки зрения закона эта операция является ПОДДЕЛКОЙ, и не может претендовать более чем статья в образовательных целях.