rendered paste body<?php/* Mircparser, parses mirc code Copyright (C) <year> <name of author> 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/>. *//** * Parses mirc code * * @author stefys <stefys@gmail.com> *///due to no static in PHP4 OOP, i'm gonna have to put some variables outside the class//Uncomment to have debug turned on//define('WITH_DEBUG', 1);//pattern to match identifiers with parameters//\x28 = '('//\x29 = ')' //those are used so they don't break my syntax highlighting ;)//$1 = identifier name//$2 = parameters list//$3 = optional prop$_mircparser_identfier_regexp = '@' . '(\$[^\s\x28]+)' . // identifier name '\x28' . // identifier open paranthesis '((?:[^\x29]*,)*' . // all parameters but last '[^\x29]*)' . // last parameter '\x29' . //identifier close paranthesis '(?:(\.[^\s]+)|())' . // optional prop '@i';$_mircparser_directory_tree = array( //d: = directory //f: = file //every directory name and file name has to be lowercase //for case insensitivity 'C' => array( 'd:windows' => array( 'd:system32' => array( 'f:winsock32.dll' ), 'd:system' ), 'd:documents and settings' => array( 'd:administrator' => array( 'd:desktop' => 'f:secret.txt' ) ), 'd:program files', 'd:mirc' => array( 'd:downloads', 'd:sounds', 'd:logs', 'f:mirc.ini', 'f:mirc.exe', 'f:script.ini' ), 'f:ntdetect.com', 'f:msdos.sys', 'f:io.sys', 'f:command.com' ), 'D' => array( 'd:games' => array('d:solitaire' => array('f:solitaire.exe')) ));$_mircparser_partition_info = array( 'C' => array( 'type' => 'ntfs', 'free' => 1024*1024*1024*3.1, // 3.1 GB 'label' => 'local', 'size' => 4.5*1024*1024*1024 //4.5 GB (used 1.4GB) ), 'D' => array( 'type' => 'fat32', 'free' => 1024*1024*200, // 200mb free 'label' => 'other', 'size' => 1024*1024*512 //512 mb total ));$_mircparser_mirc_dir = "C:\\mirc\\";/** * Public functions of the class: * constructor (string $code_to_evaluate, array $variables_to_use, * string $nick, string $addr, string $addr_server, * string $chan, string $name, string $me, * int $port, string $s_string, string $mirc_version) * bool iswm (string wildcard, string string) * string get_parsed_string() * array get_used_commands() * ** returns an array where each value * ** is a command used with $findfile or $finddir */class Mircparser { var $_str, $_info, $_used_commands, $_used_identifiers, $_variables; /** * Class constructor */ function Mircparser ($mirc_code, $variables, $nick, $addr, $addr_server, $chan, $name, $me, $port, $s_string, $version) { // constructor $this->_str = $mirc_code; $this->_info = array( 'nick' => $nick, 'addr' => $addr, 'addr_server' => $addr_server, 'chan' => $chan, 'name' => $name, 'me' => $me, 'port' => $port, 's_string' => $s_string, 'version' => $version ); $this->_used_commands = array(); $this->_used_identifiers = array(); $this->_variables = $variables; //if the mirc code to parse starts wtih $ or %, we prepend a space if (substr($this->_str,0,1) == '$' || substr($this->_str,0,1) == '%') $this->_str = ' '. $this->_str; $this->_str = &$this->_eval($this->_str); $this->_str = &$this->_tomirc($this->_str); } // no double spaces, no spaces at beginning, no spaces at the end function _tomirc ($str) { $str = str_replace(array("\r", "\n"), "", $str); $str = str_replace(' ', ' ', $str); $str = preg_replace('@^\s+@', '', $str); $str = preg_replace('@\s+$@', '', $str); return $str; } function _eval ($mirc_code) { global $_mircparser_identfier_regexp; $str = $mirc_code; //first we replace identifiers with parameters in the following way //$id(param1,param2,...,paramN) becomes //$id( param1 , param2 , param3 , ... , paramN) //we add spaces so we can then do the basic replace if (defined('WITH_DEBUG')) echo "_eval($str)<br />"; $str = preg_replace($_mircparser_identfier_regexp."e", "'$1( ' . str_replace(',', ' , ', '$2') . ' )$3'", $str); if (defined('WITH_DEBUG')) echo "added spaces to identifiers: $str<br />"; // we did add spaces between parameters of identifiers, we now do the basic replace $str = $this->_basic($str); if (defined('WITH_DEBUG')) echo "after basic parse: $str<br />"; //we replace all the variables //first, we replace the one that exist with their corresponding values foreach ($this->_variables as $var => $val) $str = str_replace(' %'.$var, ' '.$val, $str); if (defined('WITH_DEBUG')) echo "after variables replacement[1]: $str<br />"; //then we replace the ones that do not exist with null $str = preg_replace('@%(?:[^ ]+)@', ' ', $str); if (defined('WITH_DEBUG')) echo "[2]: $str<br />"; //we've done basic replace, now we do replace for identifiers that have parameters //we do so by calling the _adv_replacel function for each identifier $str = preg_replace($_mircparser_identfier_regexp."e", '$this->_adv_replace(\'$0\')', $str); if (defined('WITH_DEBUG')) echo "finally, the result: $str<br />"; return $str; } function _adv_replace ($str) { $id_name = substr($str, 1, strpos($str, '(')-1); // everything after $ until ( $id_params = substr($str, ($s = strpos($str, '(') +1), strpos($str,')')-$s); $id_params_a = array(); $id_params_arr = explode(',', $id_params); foreach ($id_params_arr as $param) $id_params_a[] = $this->_tomirc($param); if (($s=strpos($str, ').')) !== false) //we have a prop $id_prop = substr($str, $s+2); else $id_prop = ''; return $this->_adv_replace_call($id_name, $id_params_a, $id_prop); } //called when we have an identifier with parameters function _adv_replace_call ($id_name, $id_params, $prop) { if (count($id_params) < 1) return ''; global $_mircparser_partition_info; switch ($id_name) { case 'chr': return chr( (int)$id_params[0] ); break; case 'asc': return ord( substr($id_params[0],0,1) ); break; case 'disk': $exists = isset($_mircparser_partition_info[strtoupper(substr($id_params[0],0,1))]); if ($exists) $ref = &$_mircparser_partition_info[strtoupper(substr($id_params[0],0,1))]; else $ref = null; if ($prop == null) return $exists?'$true':'$false'; elseif (isset($ref[$prop])) return $ref[$prop]; else return ''; break; case 'len': return strlen($id_params[0]); break; case 'calc': //simple calc only $m = array(); //$1 = first number //$2 = sign //$3 = second number if (!preg_match('@(\d+)\s*([+*/-^])\s*(\d+)@', $id_params[0], $m)) return 0; elseif ($m[2] == '+') return $m[1]+$m[3]; elseif ($m[2] == '-') return $m[1]-$m[3]; elseif ($m[2] == '*') return $m[1]*$m[3]; elseif ($m[2] == '/' && $m[3] == 0) return 0; elseif ($m[2] == '/') return $m[1]/$m[3]; elseif ($m[2] == '^') return pow($m[1],$m[2]); break; case 'findfile': return $this->_find($id_params, 'f:'); break; case 'finddir': return $this->_find($id_params, 'd:'); break; case 'abs': return abs((float)$id_params[0]); break; case 'and': if (count($id_params) < 2) return ''; return (int)$id_params[0] & (int)$id_params[1]; break; case 'base': if (count($id_params) < 3) return ''; $d = base_convert((float)$id_params[0], (int)$id_params[1], (int)$id_params[2]); if (isset($id_params[3]) && intval($id_params[3]) == $id_params[3] && ( $to_add=$id_params[3]-strlen($d) ) > 0) $d = str_repeat('0', $to_add) . $d; return $d; break; case 'ceil': return ceil((float)$id_params[3]); case 'encode': if (count($id_params) != 2) return ''; if ($id_params[1] != 'm') return ''; return base64_encode($id_params[0]); break; case 'decode': if (count($id_params) != 2) return ''; if ($id_params[1] != 'm') return ''; return base64_decode($id_params[0]); break; case 'int': return (int)$id_params[0]; break; case 'lower': return strtolower($id_params[0]); break; case 'upper': return strtoupper($id_params[0]); break; case 'mid': return substr($id_params[0], (int)$id_params[1], (int)$id_params[2]); break; case 'left': return substr($id_params[0], 0, (int)$id_params[1]); break; case 'right': return substr($id_params[0], strlen($id_params[0])-(int)$id_params[1], (int)$id_params[1]); break; default: return ''; } } function iswm ($wildcard, $string) { $regex = '@^'; for ($i=0; $i<strlen($wildcard); $i++) { $c = $wildcard{$i}; if ($c == '*') $regex .= '.*'; elseif ($c == '?') $regex .= '.'; else $regex .= preg_quote($c, '@'); } $regex .= '$@i'; return (bool)preg_match($regex, $string); } function _find ($id_params, $start_with) { global $_mircparser_mirc_dir, $_mircparser_directory_tree; if (!isset($id_params[0])) return ''; $path = strtolower($id_params[0]); if (!isset($id_params[1])) return ''; $wildcard = strtolower($id_params[1]); if (!isset($id_params[2])) return ''; $nth = $id_params[2]; if (!isset($id_params[3])) { $depth = 0; $cmd_or_win = ''; } elseif (isset($id_params[3]) && ctype_digit($id_params[3])) { $depth = $id_params[3]; if (isset($id_params[4])) $cmd_or_win = $id_params[4]; else $cmd_or_win = ''; } else { $depth = 0; $cmd_or_win = $id_params[3]; } $path = str_replace('/', '\\', $path); if ($path{1} != ':') $path = $_mircparser_mirc_dir . ($path{0}=='.'?substr($path,1):$path); $partition = strtoupper($path{0}); if (!isset($_mircparser_directory_tree[$partition])) return ''; $crt = &$_mircparser_directory_tree[$partition]; //explode everything after first \\ //e.x.: c:\a\b\c makes: //array("a", "b", "c") $dirlist = explode('\\', substr($path,strpos($path,'\\')+1) ); foreach ($dirlist as $dir) { if ($dir == '') continue; if (!isset($crt['d:'.$dir])) return ''; else $crt = &$crt['d:'.$dir]; } //now $crt points to the structure of the current directory if (!is_array($crt)) return ''; $to_find = $start_with . $wildcard; $matches = 0; //we won't really use a depth, that would be just complicating //for no reason and making the find slower and possible DoS-able //so it would use a depth of 1 foreach ($crt as $i => $v) { if (is_array($v)) $item_name = $i; else $item_name = $v; if ($this->iswm($to_find, $item_name)) { $matches++; if ( ($cmd_or_win != '' && $cmd_or_win{0}!='@') && ($matches == $nth || $nth == 0) ) { $this->_used_commands[] = $cmd_or_win; } if ($matches == $nth) return $path . substr($item_name,strlen($start_with)); } } if ($nth == 0) return $matches; return ''; } //by weekend function _basic ($str) { //function to convert sertant mirc stuffs //its just a replace... //NOTE: this WILL do newline and whatnot so remove that if needed! global $_mircparser_mirc_dir; $from = array(); $to = array(); $nick = &$this->_info['nick']; $addr = &$this->_info['addr']; $addr_server = &$this->_info['addr_server']; $chan = &$this->_info['chan']; $name = &$this->_info['name']; $me = &$this->_info['me']; $port = &$this->_info['port']; $s_string = &$this->_info['s_string']; $version = &$this->_info['version']; //stefys: //would have been nicer to store them only once instead of initializing array everytime the function is called $from[] = ' $address'; $to[] = $addr; $from[] = ' $nick'; $to[] = $nick; $from[] = ' $server'; $to[] = $addr_server; $from[] = ' $serverip'; $to[] = '127.0.0.1'; $from[] = ' $status'; $to[] = 'connected'; $from[] = ' $show'; $to[] = '$true'; $from[] = ' $ulevel'; $to[] = '1'; $from[] = ' $snicks'; $to[] = ''; $from[] = ' $snotify'; $to[] = ''; $from[] = ' $sreq'; $to[] = 'ask'; $from[] = ' $ssl'; $to[] = '$true'; $from[] = ' $sslready'; $to[] = '$true'; $from[] = ' $ticks'; $to[] = '42569'.rand(111,999); $from[] = ' $time'; $to[] = date("H:i:s"); $from[] = '$timestamp'; $to[] = date("[H:i:s]"); $from[] = '$timestampfmt'; $to[] = '[HH:nn:ss]'; $from[] = '$timezone'; $to[] = '25200'; $from[] = ' $titlebar'; $to[] = ''; $from[] = ' $url'; $to[] = 'http://www.hackthissite.org'; $from[] = ' $usermode'; $to[] = '+iwghrsOxqBzt'; $from[] = ' $vcmdver'; $to[] = '$null'; $from[] = ' $vcmdstat'; $to[] = '0'; $from[] = ' $version'; $to[] = $version; $from[] = ' $wid'; $to[] = '6'; $from[] = ' $site'; $to[] = ''; $from[] = ' $wildsite'; $to[] = ''; $from[] = ' $active'; $to[] = $chan; $from[] = ' $activecid'; $to[] = '1'; $from[] = ' $cid'; $to[] = '1'; $from[] = ' $activewid'; $to[] = '7'; $from[] = ' $agentname'; $to[] = ''; $from[] = ' $anick'; $to[] = 'altnick'; $from[] = ' $aop'; $to[] = '$false'; $from[] = ' $appactive'; $to[] = '$true'; $from[] = ' $appstate'; $to[] = 'maximized'; $from[] = ' $avoice'; $to[] = '$false'; $from[] = ' $away'; $to[] = '$false'; $from[] = ' $cb'; $to[] = ''; $from[] = ' $cr'; $to[] = "\r"; $from[] = ' $crlf'; $to[] = "\r\n"; $from[] = ' $chan'; $to[] = $chan; $from[] = ' $chanmodes'; $to[] = 'beI,kfL,lj,psmntirRcOAQKVCuzNSMTG'; $from[] = ' $chantypes'; $to[] = '#'; $from[] = ' $cid'; $to[] = '1'; $from[] = ' $cmdbox'; $to[] = '$false'; $from[] = ' $creq'; $to[] = 'ask'; $from[] = ' $ctime'; $to[] = time(); $from[] = ' $date'; $to[] = date("d/m/Y"); $from[] = ' $adate'; $to[] = date("m/d/Y"); $from[] = ' $day'; $to[] = date("l"); $from[] = ' $daylight'; $to[] = ((date("I") == 1) ? "3600" : "0"); $from[] = ' $dccignore'; $to[] = '$false'; $from[] = ' $dccport'; $to[] = '59'; $from[] = ' $dlevel'; $to[] = '1'; $from[] = ' $emailaddr'; $to[] = 'moo@cowland.com'; $from[] = ' $ferr'; $to[] = '0'; $from[] = ' $filtered'; $to[] = '0'; $from[] = ' $fulladdress'; $to[] = $addr; $from[] = ' $fulldate'; $to[] = date("D M j G:i:s Y"); $from[] = ' $fullname'; $to[] = $name; $from[] = ' $gmt'; $to[] = time(); $from[] = ' $highlight'; $to[] = '$false'; $from[] = ' $host'; $to[] = 'www.hackthissite.org'; $from[] = ' $idle'; $to[] = '0'; $from[] = ' $ip'; $to[] = '127.0.0.1'; $from[] = ' $lf'; $to[] = "\n"; $from[] = ' $locked'; $to[] = '$false'; $from[] = ' $logdir'; $to[] = $_mircparser_mirc_dir.'logs\\'; $from[] = ' $logstamp'; $to[] = date("[H:i:s]"); $from[] = ' $logstampfnt'; $to[] = '[HH:nn:ss]'; $from[] = ' $ltimer'; $to[] = '4'; $from[] = ' $me'; $to[] = $me; $from[] = ' $mididir'; $to[] = $_mircparser_mirc_dir.'sounds\\'; $from[] = ' $mircdir'; $to[] = $_mircparser_mirc_dir; $from[] = ' $mircexe'; $to[] = $_mircparser_mirc_dir.'mirc.exe'; $from[] = ' $mircini'; $to[] = $_mircparser_mirc_dir.'mirc.ini'; $from[] = ' $mnick'; $to[] = $me; $from[] = ' $network'; $to[] = 'HackThisSite'; $from[] = ' $os'; $to[] = 'XP'; $from[] = ' $passivedcc'; $to[] = '$false'; $from[] = ' $port'; $to[] = $port; $from[] = ' $portable'; $to[] = '$false'; $from[] = ' $prefix'; $to[] = '~&@%+'; $from[] = ' $rawline'; $to[] = $s_string; $from[] = ' $script'; $to[] = 'script.mrc'; $from[] = ' $scriptdir'; $to[] = $_mircparser_mirc_dir; $from[] = ' $scriptline'; $to[] = '40'; //that should do.. return str_replace($from, $to, $str); } function get_parsed_string () { return $this->_str; } //the one replaced by _basic() are not shown here function get_used_identifiers () { return $this->_used_identifiers; } // an array with commands executed with $finddir() or $findfile function get_used_commands () { return $this->_used_commands; }}/* Usage$code = '$findfile(.,*,1,lol) $finddir(c:/,*w*,1,echo -a found!) $right(abcdef,2)';$vars = array('d' => 'omg var worked', 'a' => 5, 'b' => 6);//function Mircparser ($mirc_code, $variables, $nick, $addr, $addr_server, $chan, $name, $me, $port, $s_string, $version)$mircparser = new Mircparser($code, $vars, 'YourNick', 'Addr', 'AddrServer', '#Chan', 'Name', 'MyNick', '12345', 'S_string', 4);echo $mircparser->get_parsed_string();print_r($mircparser->get_used_commands()); */?>