Location: PHPKode > scripts > Malware Scanner > scanner.php
<?php

/*
	Malware_Scanner 1.5 BETA, No malware codes after day !
	Copyright (C)  Ahmed Hosny < http://AhmedHosny.com >
	Copyright (C)  SpanLayer < http://SpanLayer.com >
												
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.						
													
	This program is distributed in the hope that it will be useful,	
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.					

	You should have received a copy of the GNU General Public License	
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

class malware_scanner {
	
	# Input
	public $path;			// Path to scan ( Recursive ).
	public $signatures;		// Signatures array.
	private $conditions;	// Conditions to match.
	
	# Options
	public $auto_chmod;		// Auto chmod() when fail to read or write to a file.
	
	# Output
	public $infected;		// List of infected files.
	public $repaired;		// List of repaired files.
	public $errors;			// List of files have errors ( Repair, Read, Write ).
	public $log;			// Detailed log.
	
	/* @@ Constructor.
	 */
	function __construct()
	{
		if(empty($this->path))
			$this->path = $_SERVER['DOCUMENT_ROOT'];
			
		//if(!is_array($this->signatures) OR count($this->signatures) == 0)
			//die("Error: No signatures defined !");
	}
	
	/* @@ Log a message regard some file.
	 * ## $message: Message to log
	 * ## $file: File path.
	 */
	function log($message, $file)
	{
		$this->log[$file][] = $message;
	}
	
	/* @@ Set a condition to consider while running scan.
	 * ## $node_type: 'file' or 'dir'
	 * ## $node_regexp: $node_type that mathches this regexp would be affected by the condition
	 * ## $action: TRUE or FALSE
	 */
	function set_condition($node_type, $node_regexp, $action)
	{
		$this->conditions[$node_type][] = Array("regexp"=>$node_regexp, "action"=>$action);
	}
	
	/* @@ Check conditions set regard some file type and name.
	 * ## $node_type: 'file' or 'folder'
	 * ## $node_name: File Name or Folder Name
	 */
	function check_conditions($node_type, $node_name)
	{
		// Check for conditions for this node type ..
		if(count($this->conditions[$node_type]) > 0)
		{
			foreach($this->conditions[$node_type] as $condition)
			{
				if(preg_match($condition['regexp'], $node_name))
				{
					if(!$condition['action'])
						return FALSE;
				}
			}
		}
		
		return TRUE;
	}
	
	/* @@ Scan all files and folders recursively.
	 * ## $path: Path to scan.
	 */
	function scan($path = "")
	{
		if(empty($path))
			$path = $this->path;
			
		$nodes = scandir($path);

		foreach($nodes as $node)
		{
			if(is_dir($path ."/". $node) && $node != "." && $node != ".." && $this->check_conditions("folder", $node))
			{
				$this->scan($path . "/" . $node);
			}
			else if(is_file($path ."/". $node) && $this->check_conditions("file", $node))
			{
				$this->scan_file($path . "/" . $node);
			}
		}
	}
	
	/* @@ Scan file for malware signatures.
	 * ## $file: File path.
	 */
	function scan_file($file)
	{
		$this->log("Scanning", $file);
		
		if(!is_readable($file))
		{
			if($this->auto_chmod)
			{
				$this->log("Trying to chmod", $file);
				
				$chmod_res = @chmod($file, "0777");
				
				if(!$chmod_res)
					$this->log("Can't chmod", $file);
				else
					$this->log("chmod to 0777", $file);
			}
				
			if(!$chmod_res)
			{
				$this->log("Can't read", $file);
				$this->errors[] = $file;
				
				return FALSE;
			}
		}
		
		$f = fopen($file, "r");
		$res = @fread($f, filesize($file));
		//if(strpos($res, SIGNATURE) > -1)
		foreach($this->signatures as $signature_index=>$signature)
		{
			if(preg_match($signature, $res))
			{
				$this->log("Found signature #$signature_index", $file);
				$this->infected[] = $file;
				
				$this->repair_file($file, $signature_index);
			}
			else
			{
				$this->log("Clean", $file);
			}	
		}
		
		fclose($f);
	}
	
	/* @@ Repair infected file.
	 * ## $file: File path to repair.
	 * ## $signature_index: Index of signature to repair the file from.
	 */
	function repair_file($file, $signature_index)
	{
		if(!is_writable($file))
		{
			if($this->auto_chmod)
			{
				$this->log("Trying to chmod", $file);
				
				$chmod_res = @chmod($file, "0777");
				
				if(!$chmod_res)
					$this->log("Can't chmod", $file);
				else
					$this->log("chmod to 0777", $file);
			}
			
			if(!$chmod_res)
			{
				$this->log("Can't write", $file);
				$this->errors[] = $file;
				
				return FALSE;
			}
		}
		
		$res = file_get_contents($file);
		
		$this->log("Trying to repair", $file);
		
		if(preg_match($this->signatures[$signature_index], $res))
			$new_res = preg_replace($this->signatures[$signature_index], "", $res);
		
		file_put_contents($file, $new_res);
		
		$res = file_get_contents($file);
		
		if(!preg_match($this->signatures[$signature_index], $res))
		{
			$this->log("Repaired", $file);
		}
		else
		{
			$this->log("Failed to repair", $file);
			$this->errors[] = $file;
		}
	}

}

?>
Return current item: Malware Scanner