SITE LOGO Понедельник, 23.12.2024, 00:08
Приветствую Вас Гость | RSS
Меню сайта

Разделы новостей
Основы [9]
Хакинг [5]
Руководство для начинающих [6]
Взлом UNIX [9]
Взлом Microsoft Windows 2000 [12]
Хакерские трюки [36]
Программы [6184]

Наш опрос
Оцените мой сайт
Всего ответов: 579

Начало » 2007 » Май » 17 » Как ломать приложения Windows
Как ломать приложения Windows
Ломать программы Windows в большинстве случаев даже проще, чем ломать программы Dos. В Windows сложно что-нибудь скрыть от того, кто ищет, особенно если программа использует стандартные функции Windows.

Первая (и часто единственная) вещь, которая вам потребуется, — это SoftICE/Win 2.oo, мощный отладчик от фирмы NuMega.

Обзор SoftICE/WIN 2.00

Ниже приведен состав окна SoftICE:

Регистры

R — правка значения регистров.

Окно данных

D — просмотр памяти.

E — правка памяти.

Окно кода

U — просмотр кода по адресу.

A — вставка кода.

Окно команд

Здесь вы набираете команды.

Другие важные клавиши (в стандартной настройке):

H/F1 — помощь;

F5/Ctrl+D — запуск программы (или продолжение прерванной программы);

F8 — пошаговая отладка с заходом в тело функции;

F10 — пошаговая отладка без захода в тело функции;

F11 — выйти из функции (будет работать только до первого PUSH в функции).

Поиск регистрационных кодов

Возможно, наилучший способ попрактиковаться — это найти где-нибудь shareware-программку и попытаться зарегистрировать ее.

Task Lock 3.00

Простая защита на основе серийного номера: номер не зависит ни от каких факторов.

Регистрация заключается в заполнении регистрационного номера в диалоговом окошке, которое появляется, когда вы выбираете меню “Register к Register...”. Существует два типа регистрации: для индивидуального использования и для использования в “конторе” (в оригинале — site license). Поэтому очень вероятно, что в программе будет две проверки регистрационных кодов.

Регистрационные коды чаще всего вводятся в обычных строчках ввода типа Windows Edit. Чтобы проверить код, программа должна прочитать содержимое строки ввода при помощи одной из функций:

16-бит

GetWindowText

GetDlgItemText

32-бит

GetWindowTextA, GetWindowTextW

GetDlgItemTextA, GetDlgItemTextW

Последняя буква в названии 32-битных функций говорит о том, какие строки использует эта функция: однобайтовые или двухбайтовые. Двухбайтовые строки используются очень редко.

Возможно, что вы уже уловили мысль, что “Если бы можно было прерваться по вызову GetWindowText...” — и вы можете это сделать!!! Но сперва вы должны убедиться, что символьные имена (имена функций) загружены SoftICE'ом.

Чтобы установить “ловушку” (на самом деле это называется точкой останова, или брейкпойнтом) в 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

Ну что ж, попробуем еще раз...

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

Вот и все... Надеемся, что у вас все получится!

Command Line 95

Программа легкой регистрации “имя-код” и создания генератора ключей — хороший пример, с легким алгоритмом генерации кода.

 

Вы осмотрели программу и увидели, что это 32-битное приложение, требующее имя и код в окне регистрации. Поехали!

Мы поступаем так же, как и с 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

Как вы видите (и, возможно, уже догадались), это код, который вы ввели в диалоговом окне. OК, что теперь? Посмотрим дальше:

MOV [0040A548], EAX ; Сохраняет рег. код

MOV EDX, EAX ; А также помещает его в EDX

Мы достигли места, где подсчитывается реальный регистрационный код!

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, чтобы вернуться в программу, и попробуем еще раз, но на этот раз с правильным кодом (в десятичной форме). Работает!

Создание генератора ключей дляCommandLine95

Взглянем на алгоритм генерации кода и попробуем перевести его на язык Си.

Вот очень простая формула, по которой подсчитывается ключ:

code = ((uppercase_first_char * length_of_string) << 0x0A) + 0x2f8cc;

Замечание 1: Не следует забывать, что все символы в окне ввода имени были приведены к верхнему регистру, поэтому мы должны сделать то же.

Замечание 2: << 0x0A означает умножние на 2 в степени 10.

Целиком программа на Си выглядит так:

#include

#include

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;

}

Как работают 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'а новый кусок данных помещается

в верхушку стека, и затем вызываемая функция проверяет, что лежит встеке, ииспользует эти данные по своему усмотрению.

О программах на VISUAL BASIC

EXE-файлы, производимые Visual Basic'ом, не являются настоящими EXE. Они просто содержат код для вызова VBRUNxxx.DLL, который затем читает данные из EXE и выполняет программу. Такое устройство псевдо-EXE-файлов является также причиной того, что программы на Visual Basic'е такие медленные.

А так как EXE-файлы не являются настоящими EXE-файлами, вы не можете трассировать и дизассемблировать их — вы найдете вызов функции из DLL и кучу мусора. И когда вы будете трассировать такую программу, вы “заблудитесь” в DLL.

Решением этой проблемы является декомпилятор. Существует декомпилятор для программ, написанных на Visual Basic'е версий 2 и 3, созданный кем-то, называющим себя DoDi.

Как в 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, которые являются самыми важными. После этого вы должны перегрузить компьютер.

Синтаксис некоторых функций

Вам будет легче понять, как вызываются функции, о которых мы говорили, если вы будете знать их описания (декларации):

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);

Категория: Хакерские трюки | Просмотров: 2281 | Добавил: hack-zone | Рейтинг: 0.0 |
Всего комментариев: 3
3 topsinfipsy  
0
http://www.sarvajal.com - viagra

2 Odoffsporeire  
0
http://gfkdjghfkgjjkhj.com - gfkdjghfkgjjkh

1 Breaker  
0
А ваш сайт называется Site Logo?

Имя *:
Email *:
Код *:
Форма входа

Календарь новостей
«  Май 2007  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031

Поиск по новостям

Друзья сайта

Статистика

Copyright MyCorp © 2006Бесплатный конструктор сайтов - uCoz