ai-bolit-bl.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. // Enable logging
  3. define('LOG', true);
  4. define('LOG_FILE', 'aibolit-bl-generator.log');
  5. date_default_timezone_set('Europe/Moscow');
  6. define('DB_FILE', 'AIBOLIT-BINMALWARE.db');
  7. define('MAX_SIZE_TO_SCAN', 600 * 1000);
  8. if ($argc != 2) {
  9. die("Usage: php $argv[0] <root_folder>\n\n");
  10. }
  11. $db = load_db(DB_FILE);
  12. if (LOG) _log_("\nStart " . date("d/m/Y H:i:s", time()));
  13. scan_directory_recursively($argv[1]);
  14. save_db($db, DB_FILE);
  15. if (LOG) _log_("Finish " . date("d/m/Y H:i:s", time()), true);
  16. exit;
  17. function scan_directory_recursively($directory, $filter = FALSE)
  18. {
  19. echo "Scan: " . $directory . "\n";
  20. $handle = @opendir($directory);
  21. if ($handle === false) return;
  22. while (false !== ($file = readdir($handle)))
  23. {
  24. if ($file == '.' || $file == '..') continue;
  25. $path = $directory . '/' . $file;
  26. $type = filetype($path);
  27. if ($type == 'dir') scan_directory_recursively($path);
  28. if ($type == 'file') {
  29. if (filesize($path) > MAX_SIZE_TO_SCAN) continue;
  30. $hash = _hash_($path);
  31. $ok = insert_into_db(pack("H*", $hash));
  32. if (LOG) _log_( ($ok ? "new" : "dup") . " $hash|$path" );
  33. }
  34. }
  35. closedir($handle);
  36. }
  37. function _hash_($file)
  38. {
  39. $content = file_get_contents($file);
  40. return sha1($content);
  41. }
  42. function insert_into_db($item)
  43. {
  44. global $db;
  45. $str =& $db[ord($item[0])];
  46. $item_size = strlen($item);
  47. if ( $item_size == 0 ) return false;
  48. $first = 0;
  49. $last = floor(strlen($str)/$item_size);
  50. /* Если просматриваемый участок непустой, first < last */
  51. while ($first < $last) {
  52. $mid = $first + (($last - $first) >> 1);
  53. $b = substr($str, $mid * $item_size, $item_size);
  54. if (strcmp($item, $b) <= 0)
  55. $last = $mid;
  56. else
  57. $first = $mid + 1;
  58. }
  59. $b = substr($str, $last * $item_size, $item_size);
  60. if ($b == $item) {
  61. /* Искомый элемент уже добавлен. */
  62. return false;
  63. } else {
  64. /* Искомый элемент не найден.
  65. * Вставляем со сдвигом в позицию - last.
  66. */
  67. $str = substr_replace($str, $item, $last * $item_size, 0);
  68. return true;
  69. }
  70. }
  71. function load_db($file)
  72. {
  73. $db = array_fill(0, 256, '');
  74. $fp = fopen($file, 'rb');
  75. if (false === $fp) return $db;
  76. $header = unpack('V256', fread($fp, 1024));
  77. foreach ($header as $key => $size) {
  78. if ($size > 0) $db[$key-1] = fread($fp, $size);
  79. }
  80. fclose($fp);
  81. return $db;
  82. }
  83. function save_db($db, $file)
  84. {
  85. $header = array();
  86. foreach ($db as $key => $value) {
  87. $header[$key] = pack('V', strlen($value));
  88. }
  89. $fp = fopen($file, 'wb') or die("Cannot create $file.");
  90. fwrite($fp, implode($header));
  91. foreach ($db as $s) {
  92. fwrite($fp, $s);
  93. }
  94. fclose($fp);
  95. }
  96. function _log_($line, $flush = false)
  97. {
  98. static $l_Buffer = '';
  99. $l_Buffer .= $line . "\n";
  100. if ($flush || strlen($l_Buffer) > 32000)
  101. {
  102. file_put_contents(LOG_FILE, $l_Buffer, FILE_APPEND);
  103. $l_Buffer = '';
  104. }
  105. }