_ __________ _ ______ __________ _ __________ __/ _______________ _ __/ ___ \/ ________ _ ---------. _ ___ _/__/ _____) __________ \ / \zACK | / ___/_________ __/ _______/_______\/ \ | / / / /_____ / \___ / .......... ........... /______ / __ _ /_________/ /___.::::::::::: ::::::::::::: /_________/ /_________/ __::::::_____ :::' | ::::::...... .:::' : · T · E · A · M · 5 · 3 · `:::::::::::: ..:::::::: | ::: ::: `--------------------------->> >> >> .:::::: ::: .:::::: ::: TUTORiALS.PACK.NUMBER.ELEVEN ::::::: ::: ::::::: ::: ::::::::::::: ::::::::::::: `::::::::::' `::::::::::' Взлом Mirc 6.1 путём нахождения серийного номера Автор......: sLeEpY [FWA/NWA/FTPR8Z] Перевод....: NightCat [TEAM-53] URL........: http://www.mirc.com Сложность..: новичок Инструменты: softice, W32dasm 8.93 Эта программа была взломана и закейгенена уже просто мегатриллион раз, но именно её я рекомендую для исследования, т.к. в процессе вы можете почерпнуть очень много знаний касательно ассемблера. Довольно интересно, как эта программа берёт ваше имя и высчитывает серийный номер. Я не буду слишком углубляться, т.к. закейгенить её я пока не могу, зато я покажу вам, как высчитать верный номер для вашего имени. Так же, как и в предыдущих (и последующих - прим. NightCat) версиях это будет код из двух частей разделённый "-". OK, попробуем зарегать программу... Нажмите кнопку регистрации и... нам не повезло, вот наше сообщение об ошибке: "The registration name and number you have entered do not match." Нам понадобится листинг, вы можете сделать его при помощи w32dasm. Я это сделалv потому что это даст вам пару идей, откуда начать. Давайте найдём в листинге сообщение о верном ключе: ----------------------------------------------------------------------------- * Possible Reference to String Resource ID=01911: "Your registration has been successfully." :004C3CAD 6877070000 push 00000777 ----------------------------------------------------------------------------- Скролим вверх пока не увидим джамп ведущий к "плохому" сообщению: ----------------------------------------------------------------------------- :004C3C24 0F84B7000000 je 004C3CE1 ----------------------------------------------------------------------------- А вот и код, окружающий этот джамп: ----------------------------------------------------------------------------- * Reference To: USER32.SendDlgItemMessageA, Ord:0000h | :004C3C0E E8FFB50800 Call 0054F212 :004C3C13 6837D75600 push 0056D737 :004C3C18 6850D35600 push 0056D350 :004C3C1D E88FFBFFFF call 004C37B1 <- очень важный вызов :004C3C22 85C0 test eax, eax :004C3C24 0F84B7000000 je 004C3CE1 <- наш джамп :004C3C2A C605AAD3560000 mov byte ptr [0056D3AA], 00 :004C3C31 BE6C3C5700 mov esi, 00573C6C :004C3C36 BF50D35600 mov edi, 0056D350 :004C3C3B 33C0 xor eax, eax :004C3C3D 83C9FF or ecx, FFFFFFFF :004C3C40 F2 repnz :004C3C41 AE scasb :004C3C42 F7D1 not ecx :004C3C44 2BF9 sub edi, ecx :004C3C46 87F7 xchg edi, esi :004C3C48 8BC7 mov eax, edi :004C3C4A 8BD1 mov edx, ecx :004C3C4C C1E902 shr ecx, 02 :004C3C4F F3 repz :004C3C50 A5 movsd :004C3C51 8BCA mov ecx, edx :004C3C53 83E103 and ecx, 00000003 :004C3C56 F3 repz :004C3C57 A4 movsb :004C3C58 6837D75600 push 0056D737 :004C3C5D 6850D35600 push 0056D350 :004C3C62 E8BCFEFFFF call 004C3B23 :004C3C67 6A00 push 00000000 * Possible Ref to Menu: MenuID_003C, Item: "Register..." | : :пропустим несколько строк... : * Possible Reference to String Resource ID=01912: "Registration" | :004C3CA0 6878070000 push 00000778 :004C3CA5 E80D8AF6FF call 0042C6B7 :004C3CAA 50 push eax :004C3CAB 6A00 push 00000000 * Possible Reference to String Resource ID=01911: "Your registration has been entered successfully." | :004C3CAD 6877070000 push 00000777 ----------------------------------------------------------------------------- * Reference To: USER32.SendDlgItemMessageA, Ord:0000h Именно на эту API-функцию мы поставим брейкпоинт в SI. BPX SendDlgItemMessageA Теперь, когда вы прервались, вы можете заменой одного джампа зарегистрировать программу с любым СН. Но нам это не нужно. Мы за кодом пришли! Давай проверим наш вызов: :004C3C1D E88FFBFFFF call 004C37B1 <--- Вот этот ----------------------------------------------------------------------------- * Referenced by a CALL at Addresses: |:004C394F , :004C3A23 , :004C3C1D | :004C37B1 55 push ebp <-начало :004C37B2 8BEC mov ebp, esp :004C37B4 53 push ebx :004C37B5 56 push esi : :несколько пропущенных строк : :004C3831 5F pop edi :004C3832 5E pop esi :004C3833 68D43D5700 push 00573DD4 <-записываем имя и номер :004C3838 57 push edi <-этими двумя строками :004C3839 E880FEFFFF call 004C36BE <-еще один важный вызов (2)! :004C383E 85C0 test eax, eax :004C3840 740A je 004C384C <-bad jump :004C3842 B801000000 mov eax, 00000001 <-грузим 1 в eax, это хорошо! :004C3847 E991000000 jmp 004C38DD <-прыгаем ----------------------------------------------------------------------------- :004C38DD 5F pop edi <-и приземляемся тут :004C38DE 5E pop esi :004C38DF 5B pop ebx :004C38E0 5D pop ebp :004C38E1 C20800 ret 0008 <-возвращаемся в 004C3C22 ----------------------------------------------------------------------------- Теперь давайте посмотрим на наш второй вызов (2) :004C3839 E880FEFFFF call 004C36BE ----------------------------------------------------------------------------- :004C36BE 55 push ebp :004C36BF 8BEC mov ebp, esp :004C36C1 83C4F4 add esp, FFFFFFF4 :004C36C4 53 push ebx : :несколько пропущенных строк : :004C36C7 8B750C mov esi, dword ptr [ebp+0C] <-сохраняем наше имя :004C36CA FF7508 push [ebp+08] :004C36CD E84ECA0700 call 00540120 :004C36D2 59 pop ecx :004C36D3 83F805 cmp eax, 00000005 <-сравниваем длину имени с 5 :004C36D6 7307 jnb 004C36DF <-прыгаем :004C36D8 33C0 xor eax, eax <-xor eax и регистрация обламывается :004C36DA E9C9000000 jmp 004C37A8 <-возвращаемся к прерыванию регистрации * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C36D6(C) | :004C36DF 6A2D push 0000002D <-записываем "-" в стек :004C36E1 56 push esi :004C36E2 E899C90700 call 00540080 <- проверяем есть ли в серийнике"-" :004C36E7 83C408 add esp, 00000008 :004C36EA 8BD8 mov ebx, eax :004C36EC 85DB test ebx, ebx :004C36EE 7507 jne 004C36F7 :004C36F0 33C0 xor eax, eax :004C36F2 E9B1000000 jmp 004C37A8 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C36EE(C) | :004C36F7 C60300 mov byte ptr [ebx], 00 :004C36FA 56 push esi :004C36FB E874580800 call 00548F74 :004C3700 59 pop ecx :004C3701 8945FC mov dword ptr [ebp-04], eax <- "? eax" и увидим ложный :004C3704 C6032D mov byte ptr [ebx], 2D серийник "0000012345" :004C3707 43 inc ebx :004C3708 803B00 cmp byte ptr [ebx], 00 :004C370B 7507 jne 004C3714 :004C370D 33C0 xor eax, eax :004C370F E994000000 jmp 004C37A8 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C370B(C) | :004C3714 53 push ebx :004C3715 E85A580800 call 00548F74 :004C371A 59 pop ecx :004C371B 8945F8 mov dword ptr [ebp-08], eax <- "? eax" и увидим ложный :004C371E FF7508 push [ebp+08] серийник "0000067890" :004C3721 E8FAC90700 call 00540120 :004C3726 59 pop ecx :004C3727 8945F4 mov dword ptr [ebp-0C], eax <- "? eax" и увидим длину : имени "0000000006" :lines of code (sleepy = 6 символов) : :004C375A 3B5DFC cmp ebx, dword ptr [ebp-04] <- "? EBX" и увидим первую :004C375D 7404 je 004C3763 часть настоящего номера : "0000003840" :lines of code : :004C379A 3B5DF8 cmp ebx, dword ptr [ebp-08] <- "? EBX" и увидим вторую часть настоящего кода "0000410467" :004C379D 7404 je 004C37A3 <-прыгаем, если все условия для регистрации выполнены :004C379F 33C0 xor eax, eax <-xor eax и обламываемся :004C37A1 EB05 jmp 004C37A8 <-прыгаем к прерыванию регистрации ----------------------------------------------------------------------------- Самое прикольное это то, что функция CMP, которая использовалась в предыдущих версиях теперь не используется, это конечно недостаток, т.к. мы можем увидеть наш код. Сmp лишь сравнивает настоящий серийник с кучей мусора, а вот в предыдущих версиях там сразу сравнивался верный и неверный серийные номера. Но с тех пор, как защита чуть улучшилась теперь код сравнивается сразу в алгоритме. Мы помним, что первая и вторая часть нашего фальшивого серийника хранились в [ebp-04] & [ebp-08] но в потом там будет просто мусор, так что нам нужно искать сравнение [ebp-04] & [ebp-08], чтобы узнать, где хранится настоящий код. Давайте проверим алго. :004C3701 8945FC mov dword ptr [ebp-04] :004C371B 8945F8 mov dword ptr [ebp-08] "? ebp-04" показывает 0000012345 "? ebp-08" показывает 0000067890 :004C375A 3B5DFC cmp ebx, dword ptr [ebp-04] :004C379A 3B5DF8 cmp ebx, dword ptr [ebp-08] но в настоящем сравнении вот, что показывается: "? ebp-04" показывает 0009302208 "? ebp-08" показывает 0009302204 Так что идёт сравнение с мусором, Я даже занопил эти две строки сравнения и затем ввёл валидный серийный номер, который нашёл и это доказывает, что эти две строки, видимо, остались от прошлого алго. Итак, соединяем два куска кода и получаем: user: sleepy reg.: 3840-410467 Введите это в окно регистрации и вы зарегистрированы! А теперь со скорость спринтера быстро пробежимся, Ctrl+D, BPX SendDlgItemMessageA Теперь идём к диалогу регистрации и вводим любую инфу. я ввёл: user: sleepy reg.: 12345-67890 Идём по коду (F10) по тех пор пока не дойдём до MIRC!.text+000C2C0E. Теперь -> BC *, и ставим новый брейкпоинт на 4C375A и 4C379A. BPX 4C379A BPX 4C375A Ctrl+D, бумс. приземлились -> "? EBX" записали... Ctrl+D, бумс. приземлились -> "? EBX" записали... Вот и конец этого длинного туториала! Увидимся! пишите, если будет скучно :) - sleepy@linuxwaves.com gReEtz: MiNioN, GreycZ, KlutCh, KiNgEr, MidNight, FWA, NWA, FTPiRatEz! HAR! BEASTFXP! More Greetz: tHEHermit @ cracking4newbies.