PDA

Просмотр полной версии : [Руководство] Привязка к железу


RChesteR
27.08.2011, 15:44
Всем привет, решил набросать небольшой мануал для новичков по реализации банальной привязки ПО к железу компьютера. Реализовывать будем на VB.NET. Так же нам потребуется сервер с поддержкой PHP и MySQL, для тестов на локальной машине подойдет Denwer, именно его я и использовал. Думаю с его установкой и настройкой вы справитесь сами)

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

Для сервера обязательное использование SSL.
Передача данных только POST методом
Приложение естественно необходимо пропускать через обфускатор, при этом шифровать все строки.

Перед началом программирования составим небольшой алгоритм действий.

Алгоритм для локального приложения:

Генерируем случайным образом ID нашего приложения (Для каждой сборки свой уникальный ID)
Собираем данные о железе компьютера, комбинируем все данные и шифруем алгоритмом MD5
Посылаем запрос на сервер с ID нашего приложения, в случае если ID не зарегистрирован в базе, добавляем строку в базу данных - информацию о железе, и другой информации (IP к примеру)
В случае если ID приложения находится в базе, передаем данные о железе на сервер, и сверяем с данными из базы (не забываем про MD5), если данные совпадают, разрешаем работу приложения, иначе в блэк лист)

Алгоритм для сервера:

Все просто, принимаем данные от пользователя, и сверяем их с данными из MySQL базы. Все в основном описано в первом алгоритме :)

Кодировать мы начнем с сервера :)

Для начала создадим новую MySQL базу данных, и импортируем для создания таблицы туда следующий запрос:

CREATE TABLE `<Имя базы данных>`.`data` (
`ID` INT NOT NULL ,
`IP` TEXT NOT NULL ,
`Text` TEXT NOT NULL
) ENGINE = MYISAM ;
19179
"<Имя базы данных>" - заменяем на свое.

Далее создадим index.php, откроем его любым текстовым редактором и начнем понемногу писать (код максимально возможно прокомментирован):
<?php
# Конфиг для MySQl
$mysql['server'] = "localhost"; # MySQL сервер (обычно localhost)
$mysql['login'] = ""; # Логин от MySQL
$mysql['password'] = ""; # Пароль от MySQL
$mysql['database'] = ""; # База данных

# Получаем данные от программы GET методом
$id =(int)$_GET['id']; # Собственно уникальный ID приложения
$data = md5($_GET['data']); # Данные о железе, шифруем в MD5

# Получаем IP адрес клиента
$ip = $_SERVER['REMOTE_ADDR'];

# Подключаемся к MySQL
$db = mysql_connect($mysql['server'], $mysql['login'], $mysql['password']);
if (!$db) {
# В случае ошибки прерываем работу скрипта
die();
}
# Выделяем нашу базу
mysql_select_db($mysql['database'], $db);

# Выдергиваем ID из базы
$result = mysql_query("SELECT id FROM data WHERE id='".$id."'");
$text = mysql_fetch_array($result);
# Сверяем полученный ID и ID записанный в базе
if($text['id'] != $id) {
# Если записи нету, добавляем информацию о проге и железе в базу
mysql_query("INSERT INTO data (id, ip, text) VALUES ('".$id."','".$ip."','".$data."')");
die();
}
else {
# В случае если ID существует в базе, проверяем данные о железе клиента, с данными из базы
# Получаем информацию о железе по ID
$query = mysql_query("SELECT text FROM data WHERE id='".$id."'");
$text = mysql_fetch_array($query);
# Сверяем информацию из базы с полученными данными
if($text['text'] == $data){
# Если совпадают, пропускаем
die("Access Allowed");
}
else {
# Иначе фейл
die("Access Denied");
}
}
?>
По сути серверная часть закончена, можно заливать данный файл на хостинг, и настраивать базу данных :)

Ну, а теперь перейдем к локальному приложению, как уже наверное стало ясно, передавать данные мы будем GET методом (Не самое лучшее решение, но для обучающих целей самое то ;))

Привязывать прогу мы будем старым, боянистым способом, т.е. по MAC адресу сетевой карты, даже набросал небольшую функцию для этого

Public Function GetMACAddress() As String
Dim mc As New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim moc As ManagementObjectCollection = mc.GetInstances()
Dim MACAddress As String = String.Empty
For Each mo As ManagementObject In moc
If MACAddress = String.Empty Then
If CBool(mo("IPEnabled")) = True Then
MACAddress = mo("MacAddress").ToString()
End If
End If
mo.Dispose()
Next

MACAddress = MACAddress.Replace(":", "")
Return MACAddress
End Function


И не забываем:

Imports System.Management

Иначе не скомпилируется ;)

После того как мы выдрали системную информацию, необходимо передать ее на сервер, инструментов в .NET'е для этого огромное количество, от сокетов до [Ссылки могут видеть только зарегистрированные и активированные пользователи] но т.к. мы используем простенький GET метод общения с сервером, нам хватит обыкновенного WebClient'a. Общая реализация такой функции для проверки:

Public Function gets(ByVal id As Integer, ByVal data As String)
Dim wc As New WebClient
Dim i As Byte = 0
start:
Try
Select Case wc.DownloadString("[Ссылки могут видеть только зарегистрированные и активированные пользователи]" & id & "&data=" & data)
Case ""
i += 1
If i = 3 Then
Return False
Else
GoTo start
End If
Case "Access Allowed"
Return True
Case "Access Denied"
Return False
End Select
Catch
Return False
End Try
End Function


Собственно у функции два аргумента: уникальный номер приложения (Для каждой сборки должен быть свой), и передаваемые параметры железа. Так же имеется небольшой счетчик, в случае 3-х неудачных попыток загрузки результата, возвращается значение False. Так же не забываем импортировать Net

А вот пример использования сие чуда:

If gets(312352, GetMACAddress()) Then
MsgBox("Все ок, можно пользоватся программой :)")
Else
MsgBox("Программа предназначена для другого ПК")
Me.Close()
End If

Привязка в действии:
19178

Kotaries
05.06.2013, 15:12
Один раз отснифать что шлет прога, и потом винхексом подменить адрес твоего сервера на свой, который будет всегда говорить что все ок, и привет, программа свободна..

Nickitee
05.06.2013, 22:02
Один раз отснифать что шлет прога, и потом винхексом подменить адрес твоего сервера на свой, который будет всегда говорить что все ок, и привет, программа свободна..
RSA подпись + случайный токен по времени тебе в помощь.

WOLF9595
06.01.2017, 16:20
RSA подпись + случайный токен по времени тебе в помощь.

А твой гайд, я полагаю, как раз таки использует это?
Или там только RSA без токена по времени?