Originally Posted by sarkoplata
Or be ultra mega wery pro like me and use Drew's project to make the server stat refresh every 5 seconds with the correct value, becuase in database, it's refreshed every 5 minutes ;)
ServerStatsReal.php
PHP Code:
<?php
if($_SERVER['REMOTE_ADDR'] != "127.0.0.1") die("only localhost can access");
header('Content-Type: text/html; charset=utf-8'); // to support output in unicode
require( "SilkroadSecurity.php" );
require( "SocketUtility.php" );
require( "HexDump.php" );
function Send( $socket, $buffer )
{
if( !socket_send_buffer( $socket, $buffer, strlen( $buffer ) ) )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Could not send data." );
return false;
}
return true;
}
$param_host = "127.0.0.1";
$param_port = "15779";
$param_locale = "22";
$param_version = "188";
$param_timeout = "10";
if( !isset( $param_host ) )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No host set." );
return;
}
if( !isset( $param_port ) )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No port set." );
return;
}
if( !isset( $param_locale ) )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No locale set." );
return;
}
if( !isset( $param_version ) )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No version set." );
return;
}
if( !isset( $param_timeout ) )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No timeout set." );
return;
}
$s = new SilkroadSecurity();
$socket = @socket_create( AF_INET, SOCK_STREAM, 0 );
if( $socket === false )
{
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Could not create the socket." );
return;
}
@socket_set_nonblock( $socket );
@socket_connect( $socket, $param_host, $param_port );
@socket_set_block( $socket );
$r = array( $socket );
$w = array( $socket );
$e = array( $socket );
if( false === @socket_select( $r, $w, $e, $param_timeout ) )
{
@socket_close( $socket );
echo "SER VER is OFFLINE.";
return;
}
if( count( $w ) != 1 || count( $e ) == 1 )
{
@socket_close( $socket );
echo "SER VER is OFFLINE.";
return;
}
$big_packet = false;
$big_opcode = 0;
$big_count = 0;
$big_data = "";
while( true )
{
$r = array( $socket );
$w = NULL;
$e = NULL;
if( false === @socket_select( $r, $w, $e, $param_timeout ) )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "There was an error with the connection." );
return;
}
if( count( $r ) != 1 )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "No more data was received on the socket." );
return;
}
$response = socket_recv_buffer( $socket, 2 );
if( $response == false )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Could not receive data." );
return;
}
$header = "";
$array = unpack( "vsize", $response );
$response = "";
$size = (int)$array["size"];
if( bcand( $size, 0x8000 ) > 0 )
{
$expected_size = 0;
$input_size = bcadd( 4, bcand( $size, 0x7FFF ) );
$lVal = bcmod( $input_size, 8 );
if( $lVal != 0 )
{
$expected_size = bcsub( bcadd( $input_size, 8 ), $lVal );
}
else
{
$expected_size = $input_size;
}
$enc_payload = socket_recv_buffer( $socket, $expected_size );
$enc_payload_tmp = "";
while( strlen( $enc_payload ) > 0 )
{
$val = unpack( "N", $enc_payload );
$enc_payload = substr( $enc_payload, 4 );
$enc_payload_tmp .= bcbytearray( hexdec( dechex( $val[1] ) ), 4 );
}
$dec_payload = mcrypt_ecb( MCRYPT_BLOWFISH, bcbytearray( $s->m_handshake_blowfish_key, 8 ), $enc_payload_tmp, MCRYPT_DECRYPT );
$dec_payload_arr = array();
while( strlen( $dec_payload ) > 0 )
{
$val = unpack( "N", $dec_payload );
$dec_payload = substr( $dec_payload, 4 );
$val = hexdec( dechex( $val[1] ) );
$m = bcbytearray( $val , 4 );
$m = unpack( "C*", $m );
for( $x = 1; $x <= 4; ++$x )
{
array_push( $dec_payload_arr, $m[$x] );
}
}
$payload = "";
$dec_payload_arr = array_splice( $dec_payload_arr, 0, $input_size );
for( $x = 0; $x < count( $dec_payload_arr ); ++$x )
{
$payload .= pack( "C", bchexdec( bcdechex( $dec_payload_arr[$x] ) ) );
}
$header = unpack( "vopcode/vsecurity", $payload );
$header["size"] = bcsub( $input_size, 4 );
$header["encrypted"] = true;
if( $header["size"] > 0 )
{
$payload = substr( $payload, 4 );
$header["payload"] = hexdump( $payload );
}
else
{
$payload = "";
}
}
else
{
$header = socket_recv_buffer( $socket, 4 );
$header = unpack( "vopcode/vsecurity", $header );
$header["size"] = $size;
$header["encrypted"] = false;
if( $size > 0 )
{
$payload = socket_recv_buffer( $socket, $size );
$header["payload"] = hexdump( $payload );
}
}
// Debugging
//print_r( $header );
//print( PHP_EOL . "<br />". PHP_EOL );
if( $header["opcode"] == 0x5000 )
{
$data = unpack( "Cflag", $payload );
if( $data["flag"] == 0x0E )
{
$data = unpack( "Cflag/Vblowfishlow/Vblowfishhigh/Vseedcount/Vseedcrc/Vhandshakelow/Vhandshakehigh/Vg/Vp/VA", $payload );
$packet_payload = $s->Handshake_E( $data );
if( !Send( $socket, $packet_payload ) )
return;
}
else if( $data["flag"] == 0x10 )
{
$data = unpack( "Cflag/Vhandshakelow/Vhandshakehigh", $payload );
$packet_payload = $s->Handshake_10( $data );
if( !Send( $socket, $packet_payload ) )
return;
$new_payload = pack( "va9C", 9, "SR_Client", 0 );
$packet_payload = $s->format_packet( 0x2001, $new_payload, true );
if( !Send( $socket, $packet_payload ) )
return;
}
else
{
@socket_close( $socket );
echo( "Unknown flag: " . dechex( $data["flag"] ) );
return;
}
}
else if( $header["opcode"] == 0x2001 )
{
$new_payload = pack( "Cva9V", $param_locale, 9, "SR_Client", $param_version );
$packet_payload = $s->format_packet( 0x6100, $new_payload, true );
if( !Send( $socket, $packet_payload ) )
return;
}
else if( $header["opcode"] == 0x600D )
{
$type = unpack_uint8( $payload );
if( $type == 1 ) // header
{
if( $big_packet == true )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Received an invalid 0x600d packet. Duplicate header." );
return;
}
$big_count = unpack_uint16( $payload );
$big_opcode = unpack_uint16( $payload );
$big_packet = true;
}
else if( $type == 0 ) // data
{
if( !$big_packet )
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Received an invalid 0x600d packet. Out of order data." );
return;
}
$big_data .= $payload; // Append the data
$payload = "";
--$big_count; // One less packet chunk to process
if( $big_count == 0 ) // The massive packet is complete now
{
$big_packet = false;
if( $big_opcode == 0xA100 ) // 0x6100 response
{
$res = unpack_uint8( $big_data );
if( $res == 1 ) // Success, now request server list
{
if( $param_locale == 18 ) // ISRO has this
{
$new_payload = "";
$packet_payload = $s->format_packet( 0x6107, $new_payload, true );
if( !Send( $socket, $packet_payload ) )
return;
}
$new_payload = "";
$packet_payload = $s->format_packet( 0x6101, $new_payload, true );
if( !Send( $socket, $packet_payload ) )
return;
}
else // Error, can be version, GatewayServer being down, etc...
{
print( "Error" . PHP_EOL . "<br />" . PHP_EOL );
$res = unpack_uint8( $big_data );
if( $res == 4 )
{
print( "The version packet was rejected because the GatewayServer is closed." . PHP_EOL . "<br />" . PHP_EOL );
}
else if( $res == 2 )
{
print( "The version packet was rejected because it is outdated." . PHP_EOL . "<br />" . PHP_EOL );
$len = unpack_uint16( $big_data );
$ip = unpack_ASCII( $big_data, $len );
$port = unpack_uint16( $big_data );
$new_version = unpack_uint32( $big_data );
print( "$ip|$port|$new_version" . PHP_EOL . "<br />" . PHP_EOL );
$new_file = unpack_uint8( $big_data );
while( $new_file == 1 )
{
$id = unpack_uint32( $big_data );
$len = unpack_uint16( $big_data );
$name = unpack_ASCII( $big_data, $len );
$len = unpack_uint16( $big_data );
$path = unpack_ASCII( $big_data, $len );
$size = unpack_uint32( $big_data );
$in_pk2 = unpack_uint8( $big_data );
$new_file = unpack_uint8( $big_data );
print( "$id|$name|$path|$size|$in_pk2" . PHP_EOL . "<br />" . PHP_EOL );
}
break;
}
else if( $res == 1 )
{
print( "The version packet was rejected because the version is too new." . PHP_EOL . "<br />" . PHP_EOL );
}
else if( $res == 5 )
{
print( "The version packet was rejected because the version is too old." . PHP_EOL . "<br />" . PHP_EOL );
}
else if( $res == 6 )
{
print( "The version packet was rejected because a manual patch is needed." . PHP_EOL . "<br />" . PHP_EOL );
}
else
{
print( "The version packet was rejected (Code: $res)." . PHP_EOL . "<br />" . PHP_EOL );
}
print( hexdump( $big_data ) );
print( PHP_EOL . "<br />" );
@socket_close( $socket );
return;
}
}
else if( $big_opcode == 0x2005 ) // server info, ignore
{
}
else if( $big_opcode == 0x6005 ) // server info, ignore
{
}
else
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Unknown packet contained in 0x600d: 0x" . dechex( $big_opcode ) );
return;
}
$big_opcode = 0;
$big_data = "";
}
}
else
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Unknown type(" . $type . ") in 0x600d." );
return;
}
}
else if( $header["opcode"] == 0xA107 ) // ISRO
{
$count = unpack_uint8( $payload );
for( $x = 0; $x < $count; ++$x )
{
$id = unpack_uint8( $payload );
$len = unpack_uint16( $payload );
$ip = unpack_ASCII( $payload, $len );
$port = unpack_uint16( $payload );
//echo( "id: $id ip: $ip port: $port<br />" );
}
//echo( "<br />" );
}
else if( $header["opcode"] == 0xA101 )
{
$header = true;
$new_server = unpack_uint8( $payload );
while( $new_server == 1 )
{
$id = unpack_uint8( $payload );
$len = unpack_uint16( $payload );
$name = unpack_ASCII( $payload, $len );
//echo( "id: $id name: $name<br />" );
$new_server = unpack_uint8( $payload );
}
$new_server = unpack_uint8( $payload );
while( $new_server == 1 )
{
$id = unpack_uint16( $payload );
$len = unpack_uint16( $payload );
if( $param_locale == 18 )
{
$c = chr( unpack_int8( $payload ) );
if( $c == '1' )
{
$c = "USA";
}
else if( $c == '0' )
{
$c = "Korea";
}
$len--;
$name = unpack_ASCII( $payload, $len );
$ratio = unpack_float( $payload );
}
else
{
$name = unpack_ASCII( $payload, $len );
$cur = unpack_uint16( $payload );
$max = unpack_uint16( $payload );
}
$state = unpack_uint8( $payload );
if( $param_locale == 4 || $param_locale == 23 ) // csro/vsro extra bytes
{
$extra1 = unpack_uint8( $payload );
$extra2 = "";
if( $extra1 == 1 )
{
$extra2 = unpack_uint8( $payload );
}
}
if( $param_locale == 40 ) // russian
{
$name = mb_convert_encoding( $name, "utf-8", "Windows-1251" );
}
else if( $param_locale == 2 ) // korean
{
$name = mb_convert_encoding( $name, "utf-8", "EUC-KR" );
}
else if( $param_locale == 4 ) // chinese
{
$name = mb_convert_encoding( $name, "utf-8", "EUC-CN" );
}
else if( $param_locale == 12 ) // taiwanese
{
$name = mb_convert_encoding( $name, "utf-8", "BIG-5" );
}
else if( $param_locale == 15 ) // japanese
{
$name = mb_convert_encoding( $name, "utf-8", "EUC-JP" ); // not tested, might need to use something else
}
else // everything else that uses default windows codepage
{
$name = mb_convert_encoding( $name, "utf-8", "Windows-1252" );
}
if( $param_locale == 18 )
{
if( $header )
{
print( "Id|Country|Name|Ratio|State" . PHP_EOL . "<br />" . PHP_EOL );
}
print( "$id|$c|$name|$ratio|$state" . PHP_EOL . "<br />" . PHP_EOL );
}
else if( $param_locale == 4 || $param_locale == 23 )
{
if( $header )
{
print( "Id|Name|Cur|Max|State|Extra1|Extra2" . PHP_EOL . "<br />" . PHP_EOL );
}
print( "$id|$name|$cur|$max|$state|$extra1|$extra2" . PHP_EOL . "<br />" . PHP_EOL );
}
else
{
if( $header )
{
}
$str = "";
$str = $name . " " . $cur . "/" . $max;
echo $name . " " . $cur . "/" . $max;
if($state == 1){
echo " ONLINE";
$str .= " ONLINE";
} else {
$str .= " OFFLINE";
echo " CHECK";
}
$File = "C:\wamp\www\stats.html";
$Handle = fopen($File, 'w');
$ifwritten = fwrite($Handle, $str);
fclose($Handle);
}
$new_server = unpack_uint8( $payload );
$header = false;
}
break;
}
else
{
@socket_close( $socket );
echo( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Unknown opcode: 0x" . dechex( $header["opcode"] ) );
return;
}
}
@socket_close( $socket );
return;
?>
ServerStats.php
PHP Code:
<?php header('Refresh: 10'); ?>
$text = file_get_contents("http://localhost/s/ServerStatsReal.php"); ?>
<?php $splitted = explode(" ", $text); ?>
<?php $str = ""; ?>
<?php if($splitted[3] == "ONLINE") {
$str .= "<img src=\"your online image here" width=\"12\" heigth=\"12\" /><font color=\"918a6a\"> $splitted[0] $splitted[1]</font>";
} elseif($splitted[3] == "CHECK") {
$str .= "<img src=\"your check image here" width=\"12\" heigth=\"12\" /><font color=\"918a6a\"> $splitted[0] $splitted[1]</font>";
} else {
$str .= "<img src=\"your offline image here" width=\"12\" heigth=\"12\" /><font color=\"918a6a\"> Server Name</font>";
}?>
<?php $str .= "<font color=\"918a6a\"> </font>"; ?>
<?php if($splitted[3] == "ONLINE") {
$str .= "<font color=\"918a6a\">$splitted[2]</font>";
} elseif($splitted[3] == "CHECK") {
$str .= "<font color=\"918a6a\">$splitted[2]</font>";
} else {
$str .= "<font color=\"918a6a\">0/1000</font>";
}
$File = "C:\wamp\www\stats.php";
$Handle = fopen($File, 'w');
$ifwritten = fwrite($Handle, $str);
echo $str;
fclose($Handle);
?>
SilkroadSecurity.php
PHP Code:
<?php
require( "bcmath.php" );
require( "SecurityTable.php" );
class SilkroadSecurity
{
public $m_initial_blowfish_key = 0;
public $m_seed_count = 0;
public $m_crc_seed = 0;
public $m_handshake_blowfish_key = 0;
public $m_value_g = 0;
public $m_value_p = 0;
public $m_value_A = 0;
public $m_value_x = 0;
public $m_value_B = 0;
public $m_value_K = 0;
public $m_count_byte_seeds = array( 0, 0, 0 );
public $m_client_key = 0;
public $m_challenge_key = 0;
public $key_array = 0;
function GenerateValue( &$val )
{
for( $i = 0; $i < 32; ++$i )
{
$val = bcor( bcand( bcxor( bcrightshift( bcxor( bcrightshift( bcxor( bcrightshift( bcxor( bcrightshift( bcxor( bcrightshift( $val, 2 ), $val ), 2 ), $val ), 1 ), $val ), 1 ), $val ), 1 ), $val ), 1 ), bcand( bcor( bcleftshift( bcand( $val, 1 ), 31 ), bcrightshift( $val, 1 ) ), 0xFFFFFFFE ) );
}
return $val;
}
function SetupCountByte( $seed )
{
if( $seed == 0 ) $seed = 0x9ABFB3B6;
$mut = $seed;
$mut1 = $this->GenerateValue( $mut );
$mut2 = $this->GenerateValue( $mut );
$mut3 = $this->GenerateValue( $mut );
$this->GenerateValue( $mut );
$byte1 = bcxor( bcand( $mut, 0xFF ), bcand( $mut3, 0xFF ) );
$byte2 = bcxor( bcand( $mut1, 0xFF ), bcand( $mut2, 0xFF ) );
if( $byte1 == 0 ) $byte1 = 1;
if( $byte2 == 0 ) $byte2 = 1;
$this->m_count_byte_seeds[0] = bcand( bcxor( $byte1, $byte2 ), 0xFF );
$this->m_count_byte_seeds[1] = bcand( $byte2, 0xFF );
$this->m_count_byte_seeds[2] = bcand( $byte1, 0xFF );
}
function G_pow_X_mod_P( $P, $X, $G )
{
$result = 1;
$mult = $G;
if( $X == 0 )
{
return 1;
}
while( $X != 0 )
{
if( bcand( $X, 1 ) > 0 )
{
$result = bcmod( bcmul( $mult, $result ), $P );
}
$X = bcrightshift( $X, 1 );
$mult = bcmod( bcmul( $mult, $mult ), $P );
}
return bcand( $result, 0xFFFFFFFF );
}
function KeyTransformValue( &$val, $key, $key_byte )
{
$s1 = bcand( bcrightshift( $val, 0 ), 0xFF );
$s2 = bcand( bcrightshift( $val, 8 ), 0xFF );
$s3 = bcand( bcrightshift( $val, 16 ), 0xFF );
$s4 = bcand( bcrightshift( $val, 24 ), 0xFF );
$s5 = bcand( bcrightshift( $val, 32 ), 0xFF );
$s6 = bcand( bcrightshift( $val, 40 ), 0xFF );
$s7 = bcand( bcrightshift( $val, 48 ), 0xFF );
$s8 = bcand( bcrightshift( $val, 56 ), 0xFF );
$s1 = bcxor( $s1, bcand( $s1 + bcand( bcrightshift( $key, 0 ), 0xFF ) + $key_byte, 0xFF ) );
$s2 = bcxor( $s2, bcand( $s2 + bcand( bcrightshift( $key, 8 ), 0xFF ) + $key_byte, 0xFF ) );
$s3 = bcxor( $s3, bcand( $s3 + bcand( bcrightshift( $key, 16 ), 0xFF ) + $key_byte, 0xFF ) );
$s4 = bcxor( $s4, bcand( $s4 + bcand( bcrightshift( $key, 24 ), 0xFF ) + $key_byte, 0xFF ) );
$s5 = bcxor( $s5, bcand( $s5 + bcand( bcrightshift( $key, 0 ), 0xFF ) + $key_byte, 0xFF ) );
$s6 = bcxor( $s6, bcand( $s6 + bcand( bcrightshift( $key, 8 ), 0xFF ) + $key_byte, 0xFF ) );
$s7 = bcxor( $s7, bcand( $s7 + bcand( bcrightshift( $key, 16 ), 0xFF ) + $key_byte, 0xFF ) );
$s8 = bcxor( $s8, bcand( $s8 + bcand( bcrightshift( $key, 24 ), 0xFF ) + $key_byte, 0xFF ) );
$val = $s1;
$val = bcadd( $val, bcleftshift( $s2, 8 ) );
$val = bcadd( $val, bcleftshift( $s3, 16 ) );
$val = bcadd( $val, bcleftshift( $s4, 24 ) );
$val = bcadd( $val, bcleftshift( $s5, 32 ) );
$val = bcadd( $val, bcleftshift( $s6, 40 ) );
$val = bcadd( $val, bcleftshift( $s7, 48 ) );
$val = bcadd( $val, bcleftshift( $s8, 56 ) );
}
function GenerateCountByte( $update )
{
$result = bcand( bcmul( $this->m_count_byte_seeds[2], bcadd( bcnot( $this->m_count_byte_seeds[0] ), $this->m_count_byte_seeds[1] ) ), 0xFF );
$result = bcand( bcxor( $result, bcrightshift( $result, 4 ) ), 0xFF );
if( $update == true )
{
$this->m_count_byte_seeds[0] = $result;
}
return $result;
}
function GenerateCheckByte( $stream, $offset, $length )
{
global $global_security_table;
$stream = unpack( "C*", $stream );
$checksum = 0xFFFFFFFF;
$moddedseed = bcleftshift( $this->m_crc_seed, 8 );
for( $x = $offset; $x < $offset + $length; ++$x )
{
$checksum = bcxor( bcrightshift( $checksum, 8 ), $global_security_table[bcadd( $moddedseed, bcand( bcxor( $stream[$x + 1], $checksum ), 0xFF ) )] );
}
$val = bcand( $checksum, 0xFF );
$val = bcadd( $val, bcand( bcrightshift( $checksum, 8 ), 0xFF ) );
$val = bcadd( $val, bcand( bcrightshift( $checksum, 16 ), 0xFF ) );
$val = bcadd( $val, bcand( bcrightshift( $checksum, 24 ), 0xFF ) );
return bcand( $val, 0xFF );
}
function Handshake_10( $data )
{
$this->m_challenge_key = bcadd( hexdec( dechex( $data["handshakelow"] ) ), bcleftshift( hexdec( dechex( $data["handshakehigh"] ) ), 32 ) );
$expected_challenge_key = bcadd( $this->m_value_A, bcleftshift( $this->m_value_B, 32 ) );
$this->KeyTransformValue( $expected_challenge_key, $this->m_value_K, bcand( $this->m_value_A, 7 ) );
$expected_challenge_key = mcrypt_ecb( MCRYPT_BLOWFISH, bcbytearray( $this->key_array, 8 ), swap( bcbytearray( $expected_challenge_key, 8 ), 8 ), MCRYPT_ENCRYPT );
$arr = unpack( "Nl/Nh", $expected_challenge_key );
$arr["l"] = hexdec( dechex( $arr["l"] ) );
$arr["h"] = hexdec( dechex( $arr["h"] ) );
$expected_challenge_key = bcadd( $arr["l"], bcleftshift( $arr["h"], 32 ) );
if( bcdechex( $expected_challenge_key ) != bcdechex( $this->m_challenge_key ) )
{
die( "Error" . PHP_EOL . "<br />" . PHP_EOL . "Server signature error. " . bcdechex( $this->m_challenge_key ) . " vs " . bcdechex( $expected_challenge_key ) );
}
$this->KeyTransformValue( $this->m_handshake_blowfish_key, $this->m_value_K, 0x3 );
$new_payload = ""; // Nothing for 0x9000
return $this->format_packet( 0x9000, $new_payload, false );
}
function Handshake_E( $data )
{
$this->m_initial_blowfish_key = bcadd( $data["blowfishlow"], bcleftshift( $data["blowfishhigh"], 32 ) );
$this->m_seed_count = bcadd( $data["seedcount"], 0 );
$this->m_crc_seed = bcadd( $data["seedcrc"], 0 );
$this->m_handshake_blowfish_key = bcadd( hexdec( dechex( $data["handshakelow"] ) ), bcleftshift( hexdec( dechex( $data["handshakehigh"] ) ), 32 ) );
$this->m_value_g = bcadd( $data["g"], 0 );
$this->m_value_p = bcadd( $data["p"], 0 );
$this->m_value_A = bcadd( $data["A"], 0 );
$this->SetupCountByte( $this->m_seed_count );
$this->m_value_x = mt_rand( 0, 0x7FFFFFFF );
$this->m_value_B = $this->G_pow_X_mod_P( $this->m_value_p, $this->m_value_x, $this->m_value_g );
$this->m_value_K = $this->G_pow_X_mod_P( $this->m_value_p, $this->m_value_x, $this->m_value_A );
$this->key_array = bcadd( $this->m_value_A, bcleftshift( $this->m_value_B, 32 ) );
$this->KeyTransformValue( $this->key_array, $this->m_value_K, bcand( $this->m_value_K, 3 ) );
$this->m_client_key = bcadd( $this->m_value_B, bcleftshift( $this->m_value_A, 32 ) );
$this->KeyTransformValue( $this->m_client_key, $this->m_value_K, bcand( $this->m_value_B, 7 ) );
$this->m_client_key = mcrypt_ecb( MCRYPT_BLOWFISH, bcbytearray( $this->key_array, 8 ), swap( bcbytearray( $this->m_client_key, 8 ), 8 ), MCRYPT_ENCRYPT );
$arr = unpack( "Nl/Nh", $this->m_client_key );
$arr["l"] = hexdec( dechex( $arr["l"] ) );
$arr["h"] = hexdec( dechex( $arr["h"] ) );
$this->m_client_key = bcadd( $arr["l"], bcleftshift( $arr["h"], 32 ) );
// Build the 0x5000 response packet
$new_payload = pack( "VVV", $this->m_value_B, $arr["l"], $arr["h"] );
return $this->format_packet( 0x5000, $new_payload, false );
}
function format_packet( $opcode, $new_payload, $encrypted = false )
{
if( $encrypted == false )
{
$packet_payload = "";
$packet_payload .= pack( "v", strlen( $new_payload ) );
$packet_payload .= pack( "v", $opcode );
$packet_payload .= pack( "C", $this->GenerateCountByte( false ) );
$packet_payload .= pack( "C", 0 );
$packet_payload .= $new_payload;
$crc = $this->GenerateCheckByte( $packet_payload, 0, strlen( $packet_payload ) );
$packet_payload = "";
$packet_payload .= pack( "v", strlen( $new_payload ) );
$packet_payload .= pack( "v", $opcode );
$packet_payload .= pack( "C", $this->GenerateCountByte( true ) );
$packet_payload .= pack( "C", $crc );
$packet_payload .= $new_payload;
}
else
{
$len = bcor( 0x8000, strlen( $new_payload ) );
$packet_payload = "";
$packet_payload .= pack( "v", $len );
$packet_payload .= pack( "v", $opcode );
$packet_payload .= pack( "C", $this->GenerateCountByte( false ) );
$packet_payload .= pack( "C", 0 );
$packet_payload .= $new_payload;
$crc = $this->GenerateCheckByte( $packet_payload, 0, strlen( $packet_payload ) );
$packet_payload = "";
$packet_payload .= pack( "v", $len );
$packet_payload_tmp = "";
$packet_payload_tmp .= pack( "v", $opcode );
$packet_payload_tmp .= pack( "C", $this->GenerateCountByte( true ) );
$packet_payload_tmp .= pack( "C", $crc );
$packet_payload_tmp .= $new_payload;
$packet_payload_tmp = pad( $packet_payload_tmp, strlen( $packet_payload_tmp ) );
$packet_payload_tmp = swap( $packet_payload_tmp, strlen( $packet_payload_tmp ) );
$packet_payload_tmp = mcrypt_ecb( MCRYPT_BLOWFISH, bcbytearray( $this->m_handshake_blowfish_key, 8 ), $packet_payload_tmp, MCRYPT_ENCRYPT );
while( strlen( $packet_payload_tmp ) > 0 )
{
$val = unpack( "N", $packet_payload_tmp );
$packet_payload_tmp = substr( $packet_payload_tmp, 4 );
$packet_payload .= bcbytearray( hexdec( dechex( $val[1] ) ), 4 );
}
}
return $packet_payload;
}
}
function pad( $data, $count )
{
if( $count % 8 == 0 )
{
return $data;
}
$padlen = 8 - ( $count % 8 );
for( $i = 0; $i < $padlen; $i++ )
{
$data .= chr( 0 );
}
return $data;
}
function swap( $data, $count ) // taken from a php.net post
{
if( $count % 4 )
{
die( "Invalid count[$count] passed to swap." );
}
$res = "";
for( $i = 0; $i < $count; $i += 4 )
{
list( , $val ) = unpack( 'N', substr( $data, $i, 4 ) );
$res .= pack( 'V', $val );
}
return $res;
}
?>
SocketUtility.php
PHP Code:
<?php
function socket_send_buffer( &$sock, $buffer, $length )
{
while($length > 0)
{
$sent = @socket_write( $sock, $buffer, $length );
if( $sent === false )
{
return false;
}
if( $sent < $length )
{
$buffer = substr( $buffer, $sent );
$length -= $sent;
}
else
{
return true;
}
}
return false;
}
function socket_recv_buffer( &$sock, $length )
{
$all_buffer = "";
while( $length > 0 )
{
$buffer = "";
$count = @socket_recv( $sock, $buffer, $length, MSG_WAITALL );
if( $count == 0 )
{
return false;
}
$all_buffer .= $buffer;
$length -= $count;
}
return $all_buffer;
}
function unpack_uint8( &$stream )
{
$val = unpack( "C", $stream );
$val = $val[1];
$stream = substr( $stream, 1 );
return $val;
}
function unpack_int8( &$stream )
{
$val = unpack( "c", $stream );
$val = $val[1];
$stream = substr( $stream, 1 );
return $val;
}
function unpack_uint16( &$stream )
{
$val = unpack( "v", $stream );
$val = $val[1];
$stream = substr( $stream, 2 );
return $val;
}
function unpack_uint32( &$stream )
{
$val = unpack( "V", $stream );
$val = $val[1];
$stream = substr( $stream, 4 );
return $val;
}
function unpack_float( &$stream )
{
$val = unpack( "f", $stream );
$val = $val[1];
$stream = substr( $stream, 4 );
return $val;
}
function unpack_ASCII( &$stream, $len )
{
$val = implode("", unpack( "a" . $len, $stream ));
$stream = substr( $stream, $len );
return $val;
}
?>
SecurityTable.php
Code:
Attached as attachment because of size.
HexDump.php
PHP Code:
<?php
/**
* View any string as a hexdump.
*
* This is most commonly used to view binary data from streams
* or sockets while debugging, but can be used to view any string
* with non-viewable characters.
*
* @version 1.3.2
* @author Aidan Lister <[Only registered and activated users can see links. Click Here To Register...]>
* @author Peter Waller <[Only registered and activated users can see links. Click Here To Register...]>
* @link http://aidanlister.com/2004/04/viewing-binary-data-as-a-hexdump-in-php/
* @param string $data The string to be dumped
* @param bool $htmloutput Set to false for non-HTML output
* @param bool $uppercase Set to true for uppercase hex
* @param bool $return Set to true to return the dump
*/
function hexdump ($data, $htmloutput = true, $uppercase = true, $return = true)
{
// Init
$hexi = '';
$ascii = '';
$dump = ($htmloutput === true) ? '<pre>' : '';
$offset = 0;
$len = strlen($data);
// Upper or lower case hexadecimal
$x = ($uppercase === false) ? 'x' : 'X';
// Iterate string
for ($i = $j = 0; $i < $len; $i++)
{
// Convert to hexidecimal
$hexi .= sprintf("%02$x ", ord($data[$i]));
// Replace non-viewable bytes with '.'
if (ord($data[$i]) >= 32) {
$ascii .= ($htmloutput === true) ?
htmlentities($data[$i]) :
$data[$i];
} else {
$ascii .= '.';
}
// Add extra column spacing
if ($j === 7) {
$hexi .= ' ';
$ascii .= ' ';
}
// Add row
if (++$j === 16 || $i === $len - 1) {
// Join the hexi / ascii output
$dump .= sprintf("%04$x %-49s %s", $offset, $hexi, $ascii);
// Reset vars
$hexi = $ascii = '';
$offset += 16;
$j = 0;
// Add newline
if ($i !== $len - 1) {
$dump .= "\n";
}
}
}
// Finish dump
$dump .= $htmloutput === true ?
'</pre>' :
'';
$dump .= "\n";
// Output method
if ($return === false) {
echo $dump;
} else {
return $dump;
}
}
?>
bcmath.php
PHP Code:
<?php
// Bitwise math of arbitrary precision numbers.
// From http://cct.me.ntut.edu.tw/chchting/aiahtm/computer/phphelp/ref.bc.php.htm
// MAX_BASE is the maximum base that can be represented in
// one byte on the host machine. On most modern systems, this
// value can be 256, but if there are still any systems with 7-bit
// bytes out there, you should use 128 for maximum
// portability.
define('MAX_BASE', 256);
//// INTERFACE ROUTINES:
// Bitwise NOT
function bcnot($x) // pushedx
{
return _bcbitwise_internal($x, 0, '_bcnot');
}
// Bitwise AND
function bcand($x, $y)
{
return _bcbitwise_internal($x, $y, '_bcand');
}
// Bitwise OR
function bcor($x, $y)
{
return _bcbitwise_internal($x, $y, '_bcor');
}
// Bitwise XOR
function bcxor($x, $y)
{
return _bcbitwise_internal($x, $y, '_bcxor');
}
// Left shift (<<)
function bcleftshift($num, $shift)
{
return bcmul($num, bcpow(2, $shift), 0);
}
// Right shift (>>)
function bcrightshift($num, $shift)
{
return bcdiv($num, bcpow(2, $shift), 0);
}
// Convert decimal to hex (like PHP's builtin dechex)
function bcdechex($num)
{
$res = "";
while ($num != '0') {
$byte = bcand($num, 255);
$hex = dechex($byte);
if (strlen($hex) == 1) $hex = '0' . $hex;
$res = $hex . $res;
$num = bcrightshift($num, 8);
}
if ($res == '') $res = 0;
return $res;
}
// Convert hex to decimal (like PHP's builtin hexdec)
function bchexdec($hex) {
$res = 0;
for ($i=0; $i<strlen($hex); $i++) {
$res = bcadd(bcleftshift($res, 4), hexdec($hex[$i]));
}
return $res;
}
// Convert args from hex and result to hex of a bcxxx operation.
function bcashex($operation, $x, $y) {
$x = bchexdec($x);
$y = bchexdec($y);
return bcdechex($operation($x, $y));
}
// Hex version of all the operators
function bcandhex($x, $y) {
return bcashex('bcand', $x, $y);
}
function bcorhex($x, $y) {
return bcashex('bcor', $x, $y);
}
function bcxorhex($x, $y) {
return bcashex('bcxor', $x, $y);
}
function bcleftshifthex($x, $y) {
return bcashex('bcleftshift', $x, $y);
}
function bcrightshifthex($x, $y) {
return bcashex('bcrightshift', $x, $y);
}
function bcaddhex($x, $y) {
return bcashex('bcadd', $x, $y);
}
function bcsubhex($x, $y) {
return bcashex('bcsub', $x, $y);
}
function bcmulhex($x, $y) {
return bcashex('bcmul', $x, $y);
}
function bcdivhex($x, $y) {
return bcashex('bcdiv', $x, $y);
}
//// INTERNAL ROUTINES
// These routines operate on only one byte. They are used to
// implement _bcbitwise_internal.
function _bcand($x, $y)
{
return $x & $y;
}
function _bcor($x, $y)
{
return $x | $y;
}
function _bcxor($x, $y)
{
return $x ^ $y;
}
function _bcnot($x, $y) // pushedx
{
return ~$x;
}
// _bcbitwise_internal - The majority of the code that implements
// the bitwise functions bcand, bcor, and bcxor.
//
// arguments - $x and $y are the operands (in decimal format),
// and $op is the name of one of the three
// internal functions, _bcand, _bcor, or _bcxor.
//
//
// see also - The interfaces to this function: bcand, bcor,
// and bcxor
function _bcbitwise_internal($x, $y, $op)
{
$bx = bc2bin($x);
$by = bc2bin($y);
// Pad $bx and $by so that both are the same length.
equalbinpad($bx, $by);
$ix=0;
$ret = '';
for($ix = 0; $ix < strlen($bx); $ix++)
{
$xd = substr($bx, $ix, 1);
$yd = substr($by, $ix, 1);
$ret .= call_user_func($op, $xd, $yd);
}
return bin2bc($ret);
}
// equalbinpad - Pad the operands on the most-significant end
// so they have the same number of bytes.
//
// arguments - $x and $y, binary-format numbers (converted
// from decimal format with bc2bin()), passed
// by reference.
//
// notes - Both operands are modified by this function.
function equalbinpad(&$x, &$y)
{
$xlen = strlen($x);
$ylen = strlen($y);
$length = max($xlen, $ylen);
fixedbinpad($x, $length);
fixedbinpad($y, $length);
}
// fixedbinpad - Pad a binary number up to a certain length
//
// arguments - $num: The operand to be padded.
//
// - $length: The desired minimum length for
// $num
//
// notes - $num is modified by this function.
function fixedbinpad(&$num, $length)
{
$pad = '';
for($ii = 0; $ii < $length-strlen($num); $ii++)
{
$pad .= bc2bin('0');
}
$num = $pad . $num;
}
// bc2bin - Convert a decimal number to the internal
// binary format used by this library.
//
// return value - The binary representation of $num.
function bc2bin($num)
{
return dec2base($num, MAX_BASE);
}
// bin2bc - Reverse of bc2bin
function bin2bc($num)
{
return base2dec($num, MAX_BASE);
}
// convert a decimal value to any other base value
function dec2base($dec,$base,$digits=FALSE) {
if($base<2 or $base>256) die("Invalid Base: ".$base);
bcscale(0);
$value="";
if(!$digits) $digits=digits($base);
while($dec>$base-1) {
$rest=bcmod($dec,$base);
$dec=bcdiv($dec,$base);
$value=$digits[$rest].$value;
}
$value=$digits[intval($dec)].$value;
return (string) $value;
}
// convert another base value to its decimal value
function base2dec($value,$base,$digits=FALSE) {
if($base<2 or $base>256) die("Invalid Base: ".$base);
bcscale(0);
if($base<37) $value=strtolower($value);
if(!$digits) $digits=digits($base);
$size=strlen($value);
$dec="0";
for($loop=0;$loop<$size;$loop++) {
$element=strpos($digits,$value[$loop]);
$power=bcpow($base,$size-$loop-1);
$dec=bcadd($dec,bcmul($element,$power));
}
return (string) $dec;
}
function digits($base) {
if($base>64) {
$digits="";
for($loop=0;$loop<256;$loop++) {
$digits.=chr($loop);
}
} else {
$digits ="0123456789abcdefghijklmnopqrstuvwxyz";
$digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
}
$digits=substr($digits,0,$base);
return (string) $digits;
}
// returns a binary string of the bytes of 'value'.
// Leading 0x00s are added based on how many are needed.
function bcbytearray($value, $bytes) // pushedx
{
$bin = "";
$parts = str_split(bcdechex($value), 2);
if(count($parts) < $bytes)
{
$arr = array();
for($x = 0; $x < $bytes - count($parts); ++$x)
{
array_push($arr, "0");
}
for($x = 0; $x < count($parts); ++$x)
{
array_push($arr, $parts[$x]);
}
$parts = $arr;
}
for($x = 0; $x < count($parts); ++$x)
{
$bin .= chr(hexdec($parts[count($parts) - $x - 1]));
}
return $bin;
}
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1/Apache 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is LoomClient PHP library
*
* The Initial Developer of the Original Code is
* Bill St. Clair.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bill St. Clair <[Only registered and activated users can see links. Click Here To Register...]>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), the GNU Lesser General Public License Version 2.1 or later
* (the "LGPL"), or The Apache License Version 2.0 (the "AL"), in
* which case the provisions of the GPL, LGPL, or AL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, the LGPL, or the AL, and
* not to allow others to use your version of this file under the
* terms of the MPL, indicate your decision by deleting the provisions
* above and replace them with the notice and other provisions
* required by the GPL or the LGPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under the terms of any one of the MPL, the GPL the LGPL, or the AL.
****** END LICENSE BLOCK ***** */
?>
Output:
[Only registered and activated users can see links. Click Here To Register...]
Credits: Drew (pushedx) Benton, best programmer I've ever seen in SRO scene.
|