Какой код у программы for Windows

Delphi , Программа и Интерфейс , Исследование программ

Как ломать программы Windows

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

A. Как в SoftICE загружать символьные имена (имена функций etc)
B. Синтаксис функций GetWindowText, GetDlgItemText и GetDlgItemInt
C. Где найти программы
D. Как связаться с автором

1. ВВЕДЕНИЕ В ЛОМАНИЕ WINDOWS-ПРОГРАММ

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

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

What a $10,000 INFRASTRUCTURE looks like ‍ #code #programming #software #tech #technology

URL всех программ, которые Вам понадобятся, приведены в приложении C.

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. Чтобы проверить код, программа должна прочитать содержимое строки ввода при помощи одной из функций:

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. Вы можете проверить наличие брейкпоинтов командой:

Читайте также:
Установить пароль на установку программ Windows 8

В результате Вы увидите что-нибудь типа:

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 Прерывание программы

Коды продуктов

Код продукта — это GUID, который является основной идентификацией приложения или продукта. Дополнительные сведения см. в описании свойства ProductCode . Если в продукт вносятся значительные изменения, код продукта также следует изменить, чтобы отразить это. Однако не требуется, чтобы код продукта был изменен, если изменения продукта являются относительно незначительными.

Читайте также:
Windows 7 как прописать программу в реестре

32-разрядные и 64-разрядные версии пакета приложения должны иметь разные коды продуктов. Если какой-либо 32-разрядный компонент приложения перекомпилируется в 64-разрядный компонент, необходимо назначить новый код продукта.

Если сервер, предоставляемый в таблице PublishComponent , перекомпилируется с 32-разрядных на 64-разрядные, идентификатор GUID в этой таблице также может потребоваться изменить, чтобы 32-разрядные и 64-разрядные клиенты могли определить соответствующую категорию квалифицированных компонентов. В этом случае код продукта также необходимо изменить.

Обратите внимание, что буквы в идентификаторах GUID кода продукта должны быть прописными. Служебные программы, такие как GUIDGEN, создают идентификаторы GUID, содержащие строчные буквы. Строчные буквы в этих guid необходимо изменить на прописные буквы, чтобы они использовались в качестве кода продукта или кода пакета. Дополнительные сведения см. в разделе «Изменение кода продукта».

Код пакета — это GUID, определяющий конкретный пакет установщика Windows. Код пакета связывает файл .msi с приложением или продуктом, а также может использоваться для проверки источников. Коды продуктов и пакетов не взаимозаменяемы. Два неидентических .msi файлов никогда не должны иметь один и тот же код пакета.

Хотя обычно отправляется приложение с одинаковым кодом пакета и кодом продукта, эти два значения могут отличаться при обновлении приложения. Дополнительные сведения см. в разделе «Коды пакетов».

Источник: learn.microsoft.com

Программирование на C, C# и Java

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы

Калькулятор Windows Forms на языке C#

Некогда мы уже создавали подобный калькулятор, но он был довольно простенький и не имел общего TextBox’a для всех чисел.

В данной статье же мы создадим более усовершенствованный калькулятор Windows Forms. Итак, выглядеть у нас он будет вот так:

Калькулятор Windows Forms на языке C#

Здесь у нас 19 кнопок Button, 1 Textbox и ещё 1 пустой Label (на рисунке он выделен). Применение его будет описано ниже.

Итак, создаём такую или похожую форму. Мы увеличили ширину TextBox’a, используя MultiLine:

Калькулятор Windows Forms на языке C#

Также в Свойствах мы увеличили размер шрифта в TextBox’e и Label’e до 12 пт.

Калькулятор Windows Forms на языке C#

Теперь делаем так, чтобы при нажатии на цифровые кнопки, в TextBox’e появлялась соответствующая цифра.

Для этого дважды кликаем на кнопке «0» и в открывшемся коде пишем:

private void button17_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 0 ;

Проверяем, несколько раз нажав на кнопку «0» у нас в форме.

Калькулятор Windows Forms на языке C#

Работает. Делаем то же самое с остальными цифровыми кнопками:

private void button13_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 1 ;
private void button14_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 2 ;
private void button15_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 3 ;
private void button9_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 4 ;
private void button10_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 5 ;
private void button11_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 6 ;
private void button5_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 7 ;
private void button6_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 8 ;
private void button7_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + 9 ;

Таким же образом кликаем дважды на кнопку «.» в форме. Она будет использоваться для создания десятичной дроби. Пишем следующий код:

private void button18_Click ( object sender , EventArgs e )
textBox1 . Text = textBox1 . Text + «,» ;

Кнопки нажимаются, в TextBox’e отображаются нажатые цифры. Теперь надо научить программу производить с ними какие-либо операции. Как видно из формы, наш калькулятор сможет производить стандартные математические операции: сложение, вычитание, умножение и деление. Для начала мы создадим в самом начале программы несколько переменных, которые нам для этого понадобятся:

float a , b ;
bool znak = true ;

Первым двум переменным будут присваиваться значения, набранные пользователем в калькуляторе. В последствии с ними будут производиться нужные математические операции. Тип float — это тип с плавающей точкой, позволяющий работать с десятичными дробями, что нам, безусловно, нужно при наличии кнопки «.» .

Благодаря второй переменной мы будем давать программе указания, какую именно операцию производить с переменными, описанными выше. Здесь нам не нужна дробь, поэтому обойдёмся целочисленным типом int.

Последняя переменная znak нам понадобится для того, чтобы менять знаки у введённых чисел. Тип bool может иметь два значения — ture и false. Мы представим, что если znak имеет значение true в программе, то это означает, что у числа знак +, если false — число отрицательное и перед собой имеет знак —. Изначально в калькуляторе вбиваются положительные числа, поэтому мы сразу присвоили переменной значение true.

Читайте также:
Список программ после установки Windows 10

Далее мы дважды нажимаем на кнопку «+», обозначающую сложение, на форме и пишем следующий код:

private void button4_Click ( object sender , EventArgs e )
a = float . Parse ( textBox1 . Text ) ;
textBox1 . Clear ( ) ;
label1 . Text = a . ToString ( ) + «+» ;
znak = true ;

В строке 3 мы присваиваем первой переменной a то, что будет написано в TextBox’e (а именно число, которое введёт пользователь перед тем, как нажать кнопку «+»).

Затем TextBox очищается, число, введённое пользователем, в нём пропадает (но остаётся в переменной a)

Переменной count присваивается число 1, которая потом укажет программе, что именно операцию сложения надо будет произвести с числами.

Затем в Label записывается число из переменной a (то самое, которое изначально ввёл пользователь) и знак плюса. Выглядеть в форме это будет так, как описано ниже.

Пользователь вводит какое-либо число:

Калькулятор Windows Forms на языке C#

Затем нажимает на кнопку «+» и после этого видит:

Калькулятор Windows Forms на языке C#

Кроме того, как бы не было странным с первого взгляда, мы присваиваем переменной znak значение true, хотя выше, в начале кода, мы и так присваивали это же значение. Подробнее данную переменную мы опишем ниже, но смысл в том, что мы присваиваем значение true, когда хотим сделать введённое число отрицательным, если оно положительно, а значение false, когда хотим сделать число положительным, если оно отрицательное. Изначально у нас вводятся положительные числа, сначала первое, потом второе. И если первое число мы сделаем отрицательным, то значение у znak перейдёт в false и тогда получится, что второе слагаемое как бы отрицательное (на практике, просто чтобы поставить перед ним минус, придётся нажать дважды на соответствующую кнопку, чтобы с false значение перешло в true, а затем обратно с true в false, и появился знак минуса).

Подобным образом заполняем код для кнопок «-«, «*» и «/»:

private void button8_Click ( object sender , EventArgs e )
a = float . Parse ( textBox1 . Text ) ;
textBox1 . Clear ( ) ;
label1 . Text = a . ToString ( ) + «-» ;
znak = true ;
private void button12_Click ( object sender , EventArgs e )
a = float . Parse ( textBox1 . Text ) ;
textBox1 . Clear ( ) ;
label1 . Text = a . ToString ( ) + «*» ;
znak = true ;
private void button16_Click ( object sender , EventArgs e )
a = float . Parse ( textBox1 . Text ) ;
textBox1 . Clear ( ) ;
label1 . Text = a . ToString ( ) + «/» ;
znak = true ;

Разница лишь в значении переменной count и в том, какой знак добавляется в Label’e.

Далее нам понадобится создать функцию, которая будет применять нужные нам математические операции к числам. Назовём её calculate. Но перед этим мы кликнем дважды на кнопку «=» на форме и в коде к ней мы запишем:

private void button19_Click ( object sender , EventArgs e )
label1 . Text = «» ;

То есть, при нажатии пользователем на кнопку «=», как раз выполнится наша функция подсчёта calculate, и, заодно, очистится Label, так как результат мы в будущем коде выведем в TextBox.

Теперь-таки создаём нашу функцию calculate и пишем следующий код:

private void calculate ( )
switch ( count )
b = a + float . Parse ( textBox1 . Text ) ;
textBox1 . Text = b . ToString ( ) ;
b = a — float . Parse ( textBox1 . Text ) ;
textBox1 . Text = b . ToString ( ) ;
b = a * float . Parse ( textBox1 . Text ) ;
textBox1 . Text = b . ToString ( ) ;
b = a / float . Parse ( textBox1 . Text ) ;
textBox1 . Text = b . ToString ( ) ;

Здесь мы используем конструкцию switch-case.

Switch — это оператор управления. Он может включать в себя несколько case’ов. Case — метки, от значения которых зависит, какие операции будут происходить.

Строка switch(count) означает, что именно от значения count будет зависеть, какое действие будет происходить в коде switch’a.

Итак, если count=1 (в коде case 1:), то произойдёт следующее:

После того, как пользователь нажал «+», он, естественно, должен ввести второе слагаемое, что он и делает по стандартному сценарию, а затем нажать кнопку «=» (и в ней, как мы помним, как раз выполнится наша функция).

Как только кнопка «=» будет нажата, программа сложит число из переменной a с тем вторым слагаемым, которое записал пользователь в TextBox, и запишет результат в переменную b (строка 6 кода функции). В строке 7 программа выведет в TextBox результат сложения — переменную b.

Оператор break (строка 8) завершает исполнение кода switch при выполнении кода метки case 1, так как больше нам в нём делать нечего.

Точно так же строится алгоритм при case 2, case 3 и case 4 с той разницей, что в них происходит не сложение, а вычитание, умножение и деление соответственно.

Оператор default срабатывает, если вдруг что-то пойдёт не по плану и count примет какое-либо иное значение, не описанное в switch. Тогда срабатывает лишь оператор break.

Львиная доля программы готова. Нам надо лишь написать код для трёх оставшихся нетронутыми до этого время кнопок.

Дважды жмём в форме на кнопку «С». Она будет очищать все записи из TextBox’a и Label’a.

Код у неё элементарный:

Источник: vscode.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru