Archive for the ‘ Скрипты ’ Category

Доброе дело #0

Добрый день.

Дай, думаю, выложу исходники биржи трафика Вирвин — все равно ведь закрыта. Чего зря пропадать коду, может кому пригодится. Что и делаю сейчас, скачать можно здесь.

Также сообщаю для тех, кто бы хотел защитить свои биржи трафика, но посчитал сервис Эдбака слишком дорогим, что скоро состоится перезапуск и теперь сервис будет работать уже на бесплатной основе.

Удачи и до новых встреч.

P.S. Нашел хорошую партнерку с оплатой за действие (pay per action) — смотреть здесь.

Автозамена ключей Nod32 (запись #4)

Как я уже писал в предыдущей статье, я переписал программу для обновления ключей Nod32 на C#.

Но нет предела совершенству. Неделю назад я решил, что просто не имеет смысла хранить какой-либо ключ на сервере, кроме последнего. Из этого вытекает, что нет смысла в базе данных. Обновление ключа происходит при двойном клике на номер ключа в моей программе (пользователи и не подозревают, да и вероятность появления багов из-за кривых настроек нода существенно снижается).

Итак, индексный файл у меня содержит последний ключ и отдающий этот ключ код:

<?php

$avUserName = "EAV-54794372";
$avPassword = "0 214 224 233 229 240 207 242 57 100 77 173 128 200 44 117 154 49 94 188";
$avExpiried = "2017-02-20";

echo "OK\n".$avUserName."\n".$avPassword."\n".$avExpiried;

?>

И есть файл add.php, в котором содержится код, модифицирующий индексный файл:

<?php

$avUserName = AddSlashes($_POST["username"]);
$avPassword = AddSlashes($_POST["password"]);
$avExpiried = AddSlashes($_POST["expiried"]);

$file = @fopen("index.php", "w");
fwrite($file, "<?php\n\n");
fwrite($file, "\$avUserName = \"".$avUserName."\";\n");
fwrite($file, "\$avPassword = \"".$avPassword."\";\n");
fwrite($file, "\$avExpiried = \"".$avExpiried."\";\n\n");
fwrite($file, "echo \"OK\\n\".\$avUserName.\"\\n\".\$avPassword.\"\\n\".\$avExpiried;\n\n?>");
fclose($file);

?>

В обычном режиме программа просто берет ключ и устанавливает в систему. В случае двойного клика по номеру ключа программа обращается к файлу add.php и передает ему текущие значения ключа на компе, с которого она запущена. Вот собственно и все. Проще, пожалуй, некуда.

Скачать исходный код программы можно здесь.

Переезд сайта

Добрый день!

Сегодня наконец-то переезжаю на виртуальный сервер. По этой причине блог может быть недоступен в ночь с 8 на 9 марта.

Жаль, что модуль Витрины ссылок пока никто не купил, ну да ничего, я уже добавил на пару посещаемых сайтов о DataLife Engine (и работающих конечно же на этой CMS) информацию о возможности за небольшую плату получить очень неплохой модуль (поскорее бы опубликовали). Срочно нужно продать 10-12 его копий, чтобы получить 12$ * 10-12 копий = 144$ ≈ 3600-4200 рублей — чтобы в свою очередь купить нетбук. Так что придется постараться с распространением.

 

09.03.2011 0:33: Переезд полностью завершен.

LinkCase 1.0

Добрый день.

Пару дней назад мне поступил заказ на создание модуля «Витрина ссылок» с интеграцией в CMS DataLife Engine. Однако на следующий день заказчик передумал, тем не менее я решил дописать сей модуль.

Представляю вам «LinkCase 1.0 — Витрина ссылок для DLE». Вот пара скринов его работы:

Более подробное описание можно узнать в магазине Plati.ru. Цена модуля — 12$

Обещал C#? Будет C#

Добрый день. Помните программу для автозамены ключей Nod32? Если нет, посмотрите на 2 поста назад.

Освежили знания? Итак, я переписал ее на C# (заодно изменив и серверную часть). В конце статьи я приложу архив с программой и серверным скриптом. А сейчас хочу рассказать о некоторых тонкостях.

Я уже не помню, делал ли отдельный поток в версии на Delphi, но кажется, что нет. А в новой версии на C# сделал. Создал класс Checker, которому при создании передаются адрес для запроса к серверу, старый ключ и пароль к этому ключу. Таймер, который проверяет наличие новых ключей создает поток таким вот образом:

Checker checker = new Checker(server, username, password);
Thread thread = new Thread(new ThreadStart(checker.Check));
thread.Start();

Ну и собственно весь прикол потока.

Далее немаловажный момент. Я сейчас использую Windows 7 x64. И 4 часа я убил на выяснение того, почему же вся ветка реестра HKEY_LOCAL_MACHINE у меня в программе не читается, пока не оказалось, что 32-битные приложения не могут работать с ней напрямую. Собрав 64-битную версию, я получил то, чего хотел — возможность чтения/записи информации из ветки реестра, в которой НОД хранит информацию о ключе:

RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ESET\ESET Security\CurrentVersion\Plugins\01000400\Profiles\@My profile", true);
username = (string)regKey.GetValue("Username");

Для автозагрузки проги:

regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
if (regKey != null)
{
  regKey.SetValue("AVActive", Application.ExecutablePath);
}

Ну вот вроде и все с тонкостями. Ниже можно скачать исходники.

Скачать архив

P.S. В этой версии нет необходимости вручную добавлять ключи в базу. Когда серверный скрипт видит, что программа запущена не в первый раз и ключа, который она использует, отсутствует в базе, скрипт добавляет этот ключ в базу и в течение трех часов этот ключ оказывается установленным на все компьютеры, использующие программу.

Автозамена ключей Nod32 (запись #1)

Сегодня я опишу серверную часть моей системы. Отдать ключ даже проще, чем вытащить его параметр из системы. Самое интересно будет в следующей (-их) статьях.

Итак, привожу листинг работающего на сервере скрипта:

$dbhost = "localhost";	// Хост БД
$dbuser = "root";		// Имя пользователя БД
$dbpass = "";	// Пароль пользователя
$dbname = "key4nod";		// Имя БД
@mysql_connect("$dbhost", "$dbuser", "$dbpass") or die('Ошибка MySQL: не удалось подключиться к серверу базы данных');
@mysql_select_db("$dbname") or die('Ошибка MySQL: не удалось подключиться к базе данных');
$type = $_GET['t'];
if ($type == 4)
{
  $newid = rand(100000000,999999999);
  $query = mysql_query("SELECT * FROM `key` ORDER BY `id` desc LIMIT 2");
  $pcid = mysql_result($query, 1, "key");
  mysql_query("INSERT INTO `user` VALUES ('".$newid."', '".$pcid."', '0')");
  echo $newid;
  Exit;
}
# получаем код устройсва
$pcid = $_GET['id'];
$query = mysql_query("SELECT * FROM `user` WHERE `id` = '".$pcid."' LIMIT 1");
if (!mysql_num_rows($query)) die('Устройство с таким номером не найдено');
$oldkey = mysql_result($query, 0, "key");
if ($type == 1)
{
  $newid = rand(100000000,999999999);
  mysql_query("UPDATE `user` SET `id` = '".$newid."' WHERE `id` = '".$pcid."'");
  echo $newid;
}
elseif ($type == 2)
{
  $query = mysql_query("SELECT * FROM `key` WHERE `key` = '".$oldkey."' LIMIT 1");
  if (!mysql_num_rows($query)) die('Нет новых ключей');
    $oldid = mysql_result($query, 0, "id");
  $query = mysql_query("SELECT * FROM `key` WHERE `key` != '".$oldkey."' AND `id` > '".$oldid."' ORDER BY `id` desc LIMIT 1");
  if (!mysql_num_rows($query)) die('Нет новых ключей');
    echo mysql_result($query, 0, "key");
}
elseif ($type == 3)
{
  $key = $_GET['key'];
  $query = mysql_query("SELECT * FROM `key` WHERE `key` = '".$key."' LIMIT 1");
  mysql_query("UPDATE `user` SET `key` = '".$key."' WHERE `id` = '".$pcid."'");
  echo mysql_result($query, 0, "pass");
}
elseif ($type == 5)
{
  $key = $_GET['key'];
  $query = mysql_query("SELECT * FROM `key` WHERE `key` = '".$key."' LIMIT 1");
  echo mysql_result($query, 0, "binary");
}

Итак, что происходит. Для начала скрипт подключается к серверу базы данных и выбирает необходимую базу. Затем проверяется тип операции (1 — получить новый индекс устройства; 2 — получить ключ; 3 — получить пароль; 4 — зарегистрировать новое устройство; 5 — получить пароль в бинарном виде). И в зависимости от типа выполняем необходимое программе действие.

Не очень понятно, для чего нужны некоторые функции, да и вообще эта часть довольно скучная. Так что,забегая вперед, сразу опишу алгоритм работы программы.

Если программа запускается в первый раз (то есть, отсутствует файл настроек), то она посылает запрос типа 4 на сервер, в ответ он дает ей индекс и заносит в базу данных.

Затем программа посылает свой индекс, чтобы получить новый (так обеспечивается некоторая безопасность), следующие шаги — получение логина, пароля, и его бинарного представления. Если удалось записать информацию в реестр, то все хорошо, а если нет — тут и пригодится пароль в обычном виде.

Вкратце рассказал о том, что будет в следующей (-их) статье (-ях), а на сегодня это все. Удачи!

Автозамена ключей Nod32 (запись #0)

Добрый день. Это нулевая запись из трех, а может и больше, про автоматическую смену ключей для антивируса Nod32. С чего все началось? Мои родители — индивидуальные предприниматели, у них есть есть магазин, недавно там была проведена полная автоматизация — поставлен компьютер со специальным программным обеспечением и оборудованием (считыватель штрих-кода, кассовый аппарат), плюс есть офис. Понятное дело, как самый знаток в семье, я заведую всеми компьютерными делами. То есть, несколько компьютеров дома, объединенных в сеть с помощью маршрутизатора ASUS RT-N10, офисный и магазинный компьютеры — все на мне. Ясное дело, на них нужны антивирусы. Для этого дела покупается 2 выпуска журнала ComputerBild в месяц — и ключи распределяются, благодаря чему получается неплохая экономия. Так вот, раньше-то я бегал и устанавливал эти ключи в пределах одной квартиры, а теперь мне нужно ездить каждый месяц в торговый центр и офис просто чтобы обновить ключ… Не удивительно что я решил не тратить на это 2 часа, а написать программу, которая бы сама забирала ключ с моего сервера и устанавливала на компьютер, на котором она запущена. Сделал снимок реестра с помощью RegShot, установил другой ключ, сделал второй снимок — и обнаружил, что настройки у антивируса Nod32 хранятся тут:

HKEY_LOCAL_MACHINE\SOFTWARE\ESET\ESET Security\CurrentVersion\Plugins\01000400\Profiles\@My profile

Соответственно, имя пользователя хранится в параметре стокового типа Username, а пароль — бинарного типа Password. «Ага» — подумал я, и решил, что на сервере будет храниться имя пользователя и пароль именно в таком бинарном виде, чтобы было проще записывать на конечном компьютере.

В этой записи я рассказываю о программе, которая позволяет считать и скопировать в буфер пароль (так сказать, начинаю с самого простого, хотя ее я написал уже после основной — клиентской). Итак, начнем.

В разделе uses подключаем модули TRegistry (для работы с реестром) и ClipBrd (для работы с буфером обмена). На форму кидаем 2 кнопки TButton и поле ввода TMemo. На кнопках пишем «Найти» и «В буфер». в Memo1 в параметре Lines пишем «Здесь будет отображен результат работы» вместо «Memo_num» и устанавливаем атрибут ReadOnly в True чтобы нельзя было случайно удалить данные. Должно получиться что-то вроде этого:Набросок формы

Создадим событие для первой кнопки. Сделаем по ней двойной клик, объявим переменные и введем код, в результате чего получится примерно следующее:

procedure TForm1.Button1Click(Sender: TObject);
var
  Reg: TRegistry;
  Buf: array[0..20] of Byte;
  c,i: integer;
begin
  FillChar(Buf, SizeOf(Buf), 0);
  Reg := TRegistry.Create;
  Reg.RootKey := HKEY_LOCAL_MACHINE;
  try
    Reg.OpenKey('SOFTWARE\ESET\ESET Security\CurrentVersion\Plugins\01000400\Profiles\@My profile', True);
    c := (Reg.ReadBinaryData('Password', Buf, SizeOf(Buf)));
    Memo1.Lines.Strings[0]:=InttoStr(c)+' байт считано: ';
    for i := 0 to c - 1 do
      Memo1.Text:=Memo1.Text+InttoStr(Buf[i])+' ';
    Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;

Это означает, что сначала мы инициализируем переменную, затем переходим в раздел «HKEY_LOCAL_MACHINE» и идем туда, куда нам нужно, считываем оттуда переменную и выводим ее в поле.

Для кнопки «В буфер» пишем всего одну строку:

Clipboard.SetTextBuf(PChar(Memo1.Lines.Strings[1]));

Вот и все, теперь наш пароль будет копироваться в буфер и его будет легко вставить и использовать в БД:Результат работы программы - ключ Скачать мой вариант программы с исходниками можно по этой ссылке.

ЧПУ

Начал разработку CashFinder и решил поделиться с вами, дорогие читатели, скриптом ЧПУ. В моем варианте он позволяет создавать статические и динамические страницы, просто добавляя их адрес, название и текст или путь к модулю в соответствующие таблицы базы данных. Также можно получать параметры из адреса, к примеру, id просматриваемой новости (http://ваш_сайт.ру/news/1/)

Итак, для начала в файле .htaccess нужно прописать:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

Затем в файле index.php пишем:

$page_url = $_SERVER['REQUEST_URI'];
$page_url = trim($page_url, '/');
$page_url = strtolower($page_url);
if (!$page_url) $page_url = 'index';
$params = explode('/', $page_url);
$i = count($params);
while ($i > 0)
{
  $query = mysql_query("SELECT * FROM `module` WHERE `url`='".$page_url."'");
  if (mysql_num_rows($query))
  {
    $page_name = mysql_result($query, 0, 'name');
    $page_file = mysql_result($query, 0, 'file');
    break;
  }
  else
  {
    $query = mysql_query("SELECT * FROM `page` WHERE `url`='".$page_url."'");
    if (mysql_num_rows($query))
    {
      $page_name = mysql_result($query, 0, 'name');
      $page_text = nl2br(mysql_result($query, 0, 'text'));
      break;
    }
    else
    {
      $page_url = str_replace('/'.$params[$i-1], '', $page_url);
      $page_par = $params[$i];
    }
  }
  $i--;
}
$page_url = implode("/", $params);
if (!$page_name)
{
  $page_text = 'Ошибка 404' ;
  $page_name = 'Страница не найдена';
}

Итак, сначала получаем адрес страницы и записываем в переменную $page_url. Затем убираем слеши и приводим все к нижнему регистру, не забыв, что если запрос пустой, значит это — главная страница.

Создаем массив с отдельными частями адреса и начинаем искать в БД его примерно по такому принципу: к примеру, адрес страницы user/edit/34. Сначала в базе ищется полностью адрес. Если не найден, удаляется последний параметр и $page_url становится равным user/edit. И так ищем пока что-нибудь не найдем (выход из цикла с помощью break) или пока не перепробуем все варианты.

Если ничего не найдено, то записываем в необходимые переменные информацию об ошибке, если найдено — то обрабатываем, как нам нужно и выводим (в зависимости от того, найдена ли страница — выводим содержимое или файл модуля — инклудим)

Вот и все, человеко-понятный урл готов!

Geo IP конвертер

Добрый день! Хоть я и очень запарился, делая PinkContext и времени у меня уже нет, я все же собрался с мыслями, сел и написал этот пост.

Как я и обещал, сегодня я пишу о том, как сконвертировать GeoIP базу от MaxMind и как ей потом пользоваться. Итак, сразу к делу, вот листинг конвертера:

require_once("config.php");
$file = fopen("GeoIPCountryWhois.csv", "r");
flock($file, 1);
$i = 0;
while (!feof($file))
{
	$mass = fgetcsv($file, 1024);
	$begin[$i] = $mass[2];
	$end[$i] = $mass[3];
	$code[$i] = $mass[4];
	$i++;
}
$geoquery = mysql_query("SELECT * FROM `geoip`");
$c = mysql_num_rows($geoquery);
for ($i = $c; > count($begin); $i++)
{
	mysql_query("INSERT INTO `geoip` VALUES ('".$begin[$i]."', '".$end[$i]."', '".$code[$i]."')");
}
flock($file, 3);
fclose($file);
if ($i == count($begin)) echo "Завершено";

А теперь опишу как же все это работает. Во-первых, подключаемся к базе данных, используя общий файл настроек — config.php. Затем открываем файл базы и пока не дойдем до конца считываем его циклом в массив. После этого смотрим, сколько уже записей в базе (на случай, если с первого раза база не сконвертировалась полностью из-за ограничений на время исполнения) и начиная с места последней записи вставляем новые значения.

В итоге, когда скрипт полностью завершит свою работу, он выведет «Завершено».

Как же использовать эту базу? Для определения страны с ее помощью я сделал небольшую функцию:

function geoip($ip)
{
$params = explode(".", $ip);
$adr = 16777216*$params[0] + 65536*$params[1] + 256*$params[2] + $params[3];
$query = mysql_query("SELECT * FROM `geoip` WHERE '".$adr."' BETWEEN `begin` AND `end` LIMIT 1");
if (mysql_num_rows($query))	$code = mysql_result($query, 0, "code"); else $code = "";
return $code;
}

Как видно, ей передается IP адрес и на выходе она возвращает код страны (если ничего не найдено результат — пустая строка). Вот и все, база готова  использованию…

Подошел к концу десятый пост моего блога. Желаю вам и себе удачи во всех начинаниях!

P.S. После пятидесятой записи всех ждет полезный сюрприз

PinkContext (запись #1)

Вот и запущена в тестовом режиме система контекстной рекламы с оплатой за показы PinkContext. На данный момент открыта регистрация только вебмастеров.

Сегодня я хочу написать о том, как я переконвертировал пользователей из проекта 7pop в PinkContext.

Для начала в файле конвертера делается запрос в базу данных с пользователями и выбираются оттуда все с положительным балансом (предварительно конечно подключив файлы с настройками подключения к БД):

$query = mysql_query("SELECT * FROM `users` WHERE `balans` != 0 ORDER BY `id`");

Затем циклом все пользователи записываются в новую базу данных:

for ($i = 0; < mysql_num_rows($query); $i++)

А вот дальше начинаются чудеса. Нужно оповестить каждого пользователя о том, что открыта новая система и что он автоматически в ней зарегистрирован с его данными из старой системы. «А вдруг он не помнит свои старые данные» — вот главная проблема. Значит нужно отправить ему его логин и пароль на электорнную почту. Как же узнать пароль, ведь он захеширован? Значит нужно создать новый. Вот как это сделал я:

$id = $_GET["id"];
$text = UrlDecode($_GET["text"]);
$title = UrlDecode($_GET["title"]);
$query = mysql_query("SELECT * FROM `user` WHERE `id` = '".$id."'");
if (!mysql_num_rows($query)) die('Пользователя с id '.$id.' не существует');
$login = mysql_result($query, 0, "login");
$email = mysql_result($query, 0, "email");
if (!$login) $login = $email;
if (preg_match('/%username%/', $text)) $text = preg_replace('/%username%/', $login, $text);
if (preg_match('/%password%/', $text))
{
  $password = RandStr(8);
  $text = preg_replace('/%password%/', $password, $text);
  $password = md5($password);
  $query = mysql_query("UPDATE `user` SET `pass` = '".$password."' WHERE `id` = '".$id."'");
}
$headers = 'Content-type: text/html; charset=utf-8 '.'\r\n';
$headers .= 'From: '.$site_mail.' '.'\r\n';
mail($email, $title, $text, $headers);

Что же этот скрипт делает? Для начала он забирает из основного модуля 3 переменных — id пользователя, которому нужно отправить сообщение, заголовок сообщения и текст сообщения. После этого лезет в БД и запрашивает данные выбранного пользователя, попутно проверяя наличие его в базе. В моем случае в предыдущей базе у пользователей не было ников, поэтому можно заходить и с помощью электронной почты и с помощью ника.

Затем скрипт ищет специальные теги %username% и %password%. Если он встречает первый тэг, то просто заменяет его на имя пользователя. Если второй, то генерирует пароль, заменяет тэг на пароль, хеширует пароль и меняет его для выбранного пользователя в БД. И уже потом отправляет письмо конечному получателю.

Вот функция для генерации случайной строки:

function RandStr($pass_len)
{
  $allchars = "abcdefghijklnmpqrstuvwxyzABCDEFGHIJKLNMPQRSTUVWXYZ123456789";
  $string = "";
  mt_srand ((double) microtime() * 1000000);
  for ($i = 0; $i < $pass_len; $i++)
  {
    $string .= $allchars{mt_rand (0,strlen($allchars))};
  }
  return $string;
}

А в следующий раз я напишу, как сконвертировать GeoIP базу от MaxMind в базу данных MySQL (так как такие вопросы иногда возникают у начинающих программистов)