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 КОГДА ПРОГРАММА ВЫЗЫВАЕТ ФУНКЦИЮ
Снова | взглянемPUSHPUSHPUSHPUSHCALL | на кусок кода из Task Lock'а:32EAX000003F4DWORD PTR [ESI+1C] [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), не существует декомпилятора, насколько мне известно, хотя я бы хотел, чтобы он существовал. =)
Примечание: Настоящие программисты на пишут на 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