# defender-security/3.1.0/src/behavior/scan/malware-quick-scan.php

Defender Security – Malware Scanner, Login Security &amp; Firewall, version 3.1.0. 162 lines.

- Page: https://pluginprobe.com/plugins/defender-security/3.1.0/code/src/behavior/scan/malware-quick-scan.php
- Raw: https://pluginprobe.com/plugins/defender-security/3.1.0/raw/src/behavior/scan/malware-quick-scan.php
- Modified: 2022-06-13T09:01:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/defender-security/3.1.0/code/src/behavior/scan/malware-quick-scan.php#L10-L20`.

```php
<?php

namespace WP_Defender\Behavior\Scan;

use Calotes\Component\Behavior;
use WP_Defender\Traits\IO;

/**
 * This will fast travel all yara rules to quickly get files seem suspicious, this is catchy.
 *
 * Class Malware_Quick_Scan
 * @package WP_Defender\Behavior\Scan
 */
class Malware_Quick_Scan extends Behavior {
	use IO;

	private $content;

	/**
	 * @param $file
	 * @param $rules
	 *
	 * @return array|void
	 */
	public function do_quick_scan( $file, $rules ) {
		if ( ! file_exists( $file ) ) {
			return;
		}
		$content       = file_get_contents( $file );
		$this->content = $content;
		$total_issues  = 0;
		$qs_detail     = [];
		foreach ( $rules as $rule ) {
			$strings      = $rule['strings'];
			$local_issues = [
				'identifier' => $rule['identifier'],
				'catches'    => []
			];
			foreach ( $strings as $string ) {
				$offset = false;
				if ( $string['type'] == 0 ) {
					$offset = strpos( $content, $string['text'] );
					$text   = $string['text'];
				} else {
					$pattern  = "/{$string['text']}/";
					$is_match = preg_match_all( $pattern, $content, $matches,
						PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE );
					if ( $is_match ) {
						$offset = $matches[0][0][1];
						$text   = $matches[0][0][0];
					}
				}
				if ( false === $offset ) {
					continue;
				}
				$local_issues['catches'] [] = [
					'id'     => $string['id'],
					'text'   => $text,
					'offset' => $offset
				];
			}
			if ( empty( $local_issues['catches'] ) ) {
				continue;
			}

			if ( $this->condition_valid( $local_issues['catches'], $rule ) ) {
				$total_issues ++;
				$qs_detail[] = $local_issues;
			}
		}

		return [ $total_issues, $qs_detail ];
	}

	/**
	 * Parse the condition to see if this is an issue or not.
	 *
	 * @param $found
	 * @param $rule
	 *
	 * @return bool
	 */
	private function condition_valid( $found, $rule ) {
		$condition = explode( 'and', $rule['condition'] );
		$count     = 0;
		foreach ( $condition as $item ) {
			$patterns = [
				'x_of_them' => '/([a-z0-9]+)\s*of\s*(.*)/',
				'id_at_pos' => '/(\$[a-zA-Z0-9]+)\s*at\s*(\d+)/',
				//'not_x'     => '/not\s*(\$[a-z0-9]+)/'
			];
			foreach ( $patterns as $func => $pattern ) {
				if ( preg_match( $pattern, $item, $match ) ) {
					$count ++;
					$ret = $this->$func( $found, $match, $rule );
					if ( false === $ret ) {

						return false;
					}
				}
			}
		}
		if ( $count === 0 ) {
			$this->log( $rule['identifier'], 'malware_scan.log' );
			$this->log( var_export( $found, true ), 'malware_scan.log' );

			return false;
		}

		return true;
	}

	/**
	 * This will parse the condition x of y.
	 *
	 * @param $found
	 * @param $match
	 * @param $rule
	 *
	 * @return bool
	 */
	private function x_of_them( $found, $match, $rule ) {
		$num = $match[1];
		$num = 'all' === $num ? count( $rule['strings'] ) : $num;
		$num = 'any' === $num ? 1 : $num;

		if ( '(s*)' == $match[2] ) {
			// Hard code in this situation.
			$num -= 1;
		}
		//$this->log( sprintf( 'num %s', $num ), 'malware_scan.log' );
		//$this->log( sprintf( 'count %s', count( $found ) ), 'malware_scan.log' );

		return (is_array($found) || $found instanceof \Countable ? count( $found ) : 0) >= $num;
	}

	/**
	 * @param $found
	 * @param $match
	 * @param $rule
	 *
	 * @return bool
	 */
	private function id_at_pos( $found, $match, $rule ) {
		// Get the text to check.
		foreach ( $found as $item ) {
			if ( $item['id'] === $match[1] ) {
				return strpos( $this->content, $item['text'] ) == $match[2];
			}
		}

		return false;
	}

	private function not_x( $found, $match, $rule ) {
		$this->log( 'not x', 'malware_scan.log' );
		$this->log( var_export( $match, true ), 'malware_scan.log' );

		return true;
	}
}

```
