Archive

Archive for January, 2009

PHP ping

January 30th, 2009

Σε ένα απο τα τελευταία projects που ασχολούμαι στην NetWerk, η εφαρμογή μου επικοινωνεί με web services που βρίσκονται σε άλλους servers, ωστόσο για την αποφυγή λαθών και για καλύτερο debugging ήθελα να κάνω ping τον server που “μιλάω” ωστε να ξέρω τι συμβαίνει.

Πώς κάνουμε ping με php

Επειδή γενικώς δέν μου αρέσει να ανακαλύπτω τον τροχό κάθε φορά που κάνω κάτι καινούριο, έψαξα στο internet και ανακάλυψα ένα code snippet για ping μέσω php. Το μόνο πρόβλημα, είναι πως εφόσον o server που κάνουμε ping δέν απαντήσει, το scriptάκι κολλάει. Παρακάτω είναι μία αλλαγμένη έκδοση του snippet οπου ορίζεις το timeout.


<?php

//add
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}

// Checksum calculation function
function icmpChecksum($data) {
if (strlen($data)%2)
$data .= "\x00";

$bit = unpack('n*', $data);
$sum = array_sum($bit);

while ($sum >> 16)
$sum = ($sum >> 16) + ($sum &amp; 0xffff);

return pack('n*', ~$sum);
}

// Making the package
$type= "\x08";
$code= "\x00";
$checksum= "\x00\x00";
$identifier = "\x00\x00";
$seqNumber = "\x00\x00";
$data= "Scarface";
$package = $type.$code.$checksum.$identifier.$seqNumber.$data;
$checksum = icmpChecksum($package); // Calculate the checksum
$package = $type.$code.$checksum.$identifier.$seqNumber.$data;
// And off to the sockets
$socket = socket_create(AF_INET, SOCK_RAW, 1);
if (socket_connect($socket, $argv[1], null)) {

socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0)); // thek add

// If you're using below PHP 5, see the manual for the microtime_float
// function. Instead of just using the m
//     icrotime() function.

//$startTime = microtime(true); // thek remove
$startTime = microtime_float(); // thek add

socket_send($socket, $package, strLen($package), 0);
if (socket_read($socket, 255)) {
//echo round(microtime(true) - $startTime, 4) .' seconds'; // thek remove
echo round(microtime_float() - $startTime, 4) .' seconds'; // thek add
}
else {
echo 'lost connection';
}
socket_close($socket);
}
else {
echo 'lost connection';
}
?>

Στο παραπάνω παράδειγμα το timeout θα γίνει σε 5 δευτερόλεπτα. Αν θέλετε να το αλλάξετε απλώς αλλάξτε το 5 στην παρακάτω γραμμή:

socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array(“sec”=>5, “usec”=>0)); // thek add

Το script τρέχει μόνο απο CLI δίνοντας την εντολή

php -q script.php <ip address>

όπου script.php είναι το παρών σκριπτάκι και <ip_address> είναι η διεύθυνση που θέλετε να κάνετε ping. Σε επόμενο άρθρο θα γράψω πώς να το κάνετε απο web εφαρμογή.

php , ,

Google trace script

January 26th, 2009

Ένα απο τα θέματα που μας ενδιαφέρουν σχετικά με το search engine optimization, είναι το κάθε πότε κάνει crawl το google το site μας. Ειδικότερα θέλουμε να δούμε – κυρίως για εγκυκλοπαιδικούς λόγους – πόσος καιρός μεσολαβεί απο ένα crawl μέχρι την παρουσία μιας σελίδας στο index.

Με αυτές τις απορίες κατά νου αποφασίσαμε να δημιουργήσουμε ένα απλό scriptάκι το οποίο απλά καταγράφει κάθε valid request του google. To script είναι πάρα πολύ απλό, ωστόσο ελπίζω να σας χρησιμέψει.

Το Google script

Καταρχήν χρειαζόμαστε ένα mysql database που θα κρατάει τα δεδομένα μας. Στην προκειμένη περίπτωση δημιουργήσαμε ένα database με όνομα “google_spy” και τρέξαμε το παρακάτω SQL για να δημιουργηθεί ο πίνακας που θα κρατάει τα δεδομένα:

CREATE TABLE IF NOT EXISTS `trace` (
  `TraceID` int(10) unsigned NOT NULL auto_increment,
  `Domain` varchar(100) NOT NULL default '',
  `Time` datetime NOT NULL default '0000-00-00 00:00:00',
  `Bot` varchar(100) NOT NULL default '',
  `Url` text NOT NULL,
  PRIMARY KEY  (`TraceID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Παρακάτω είναι το php script που κάνει την δουλειά:

<?
php
define ('GOOGLE_AGENT','Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)');

//A few settings for the script:

$db_host = 'localhost';

$db_user = 'user';

$db_pass = 'password';

function googlebot($ip)  {

  $bot = 'googlebot.com';

  $name = gethostbyaddr($ip);

  if ($name == $ip) return false;

  return (strpos($name, $bot) !== false and gethostbyname($name) == $ip) ? true : false;

}

if ($_SERVER['HTTP_USER_AGENT']==GOOGLE_AGENT &amp;amp;amp;&amp;amp;amp; googlebot($_SERVER['REMOTE_ADDR'])) 

{

	$url='http://'.$_SERVER['HTTP_HOST'];

	if ($_SERVER['REQUEST_URI']) $url.=$_SERVER['REQUEST_URI'];

	$url_u8=iconv('Windows-1253','UTF-8',$url);

	if (crc32($url)==crc32(iconv('UTF-8','Windows-1253',$url_u8))) $url=$url_u8;

	$url=urldecode($url);

	$sql ="INSERT LOW_PRIORITY INTO `google_spy`.`trace` SET `Domain`='".$_SERVER['HTTP_HOST']."',`Time`='".date('Y-m-d H:i:s')."',";

	$sql.="`Bot`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."',`Port`='".$_SERVER['REMOTE_PORT']."',`Url`='$url'";

	$con=mysql_connect($db_host,$db_user,$db_pass);

	mysql_query("SET NAMES 'utf8'",$con);

	mysql_query($sql,$con);

	mysql_close($con);

}

?>

Για να το χρησιμοποιείσετε απλώς αλλάξτε τα settings στην αρχή ($db_host, $db_user, $db_pass) και κάντε include το script σε οποιοδήποτε site θέλετε να κρατάτε logs. Σημειώστε οτι το script κρατάει μία εγγραφή ανα visit (που προέρχεται απο το google) οπότε καλό θα είναι να σβήνετε τα δεδομένα ανα τακτά χρονικά διαστήματα.

Αν κάνετε κάποια μετατροπή ή δημιουργήσετε ένα όμορφο interface για το scriptάκι μήν διστάσετε να το μοιραστείτε μαζί μας :)

nuSOAP, php, seo , ,

Winamp plugin για το audiotwit

January 20th, 2009

Το twitter, η micro blogging πλατφόρμα που πλέον όλοι γνωρίζουμε και χρησιμοποιούμε, είναι το αγαπημένο μας social network για ανταλλαγή μηνυμάτων. Όπως όλα τα social networks έχει friends, αλλά αυτό που το κάνει ιδιαίτερο είναι ο τρόπος που παρακολουθείς μια συζήτηση (follow,@). Έχουν γραφτεί πάρα πολλές εφαρμογές βασισμένες στο api του twitter, πολλές από αυτές, έχουν κάνει το twitting καθημερινή συνήθεια.

To audiotwit είναι και αυτό μία εφαρμογή που χρησιμοποιεί το api του twitter για να δημιουργεί ένα audio playlist με την βοήθεια του χρήστη @listensto. Η ιδέα έρχεται από τον Νίκο Παπανώτα, ο οποίος έψαχνε να βρεί ένα project για να πειραματιστεί με το api. Για να το χρησιμοποιήσει κάποιος δεν έχει παρά να κάνει follow τον user @listensto και να στέλνει τα ακούσματά του με την μορφή «@listensto Artists – Song». Το audiotwit κάθε 5 λεπτά, βλέπει τα μυνήματα και τα καταχωρεί στην σελίδα του κάθε χρήστη. (π.χ. Το δικό μου twitter είναι το thek27, οπότε το thek27.audiotwit.com παρουσιάζει την λίστα με τα τραγούδια που έχω ακούσει, ενώ η υπηρεσία έχει και RSS feed για κάθε χρήστη.)

To Winamp plugin

Πολύ ωραίο σαν ιδέα, άλλα το πρόβλημα είναι ότι για να ενημερώνω το playlist μου θα πρέπει κάθε φορά που ακούω ένα τραγούδι να το στέλνω και στο twitter. Έτσι μου ήρθε η ιδέα να φτιάξω ένα winamp plugin το οποίο θα στέλνει αυτόματα το τραγούδι που ακούω κάθε στιγμή χωρίς εγώ να ασχολούμαι με το twitter.

Σε επόμενο post θα γράψω όλη την διαδικασία κατασκευής αυτού του plugin, αφού θα δώσω και τον κώδικα ανοιχτό. Αλλά προς το παρόν συγχωρέστε με άλλα βιάζομαι να δω πως θα προχωρήσει το audiotwit μετά την εφαρμογή του winamp plugin.

Σείρα έχει το plugin για media player και itunes. Πιστέυω πως δεν θα αργήσουν. Αν έχει ασχοληθεί κάποιος και θέλει να βοηθήσει μπορεί να επικοινωνήσει μαζί μου.

Εγκατάσταση του plugin

Αν θέλετε να συμμετάσχετε στο ελληνικό social experiment του twitter, δέν έχετε παρά να κατεβάσετε το plugin απο εδώ. Αφού το εκτελέσετε, την πρώτη φορά που θα τρέξει θα σας ζητήσει το username και το password σας στο twitter ωστε να μπορεί να κάνει updates όποτε ακούτε κάποιο κομμάτι.

twitter ,

Η ιστορία ενός cracking

January 14th, 2009

Όταν γράφτηκα στην REA και κατέβασα το πρώτο crack project (είχε 4 κατηγορίες από projects) , είχα ένα μήνα μπροστά μου για να βρω την λύση. Αν περνούσε αυτό το διάστημα δεν θα μπορούσα να συνεχίσω, οπότε η πρόκληση ήταν μεγάλη. Έπρεπε λοιπόν σε αυτό το διάστημα να βρω τα εργαλεία (debugger, disassembler, hex editor κτλ)  και να μάθω πως θα τα χρησιμοποιήσω όλα αυτά μαζί. Νέα εμπειρία για ένα προγραμματιστή.

Έτσι το πρώτο εργαλείο που έπεσε στα χέρια μου, ήταν ο Win32Dasm, οι παλιοί θα τον γνωρίζουν. Τώρα βέβαια τον έχω αντικαταστήσει με τον OllyDbg, που τον θεωρώ καλύτερο. Πάντως ο Win32Dasm για απλά project τα καταφέρνει καλά (για περισσότερα cracking εργαλεία δείτε εδώ).

Η πρώτη αποστολή ήταν ένα πρόγραμμα το splish.exe το οποίο εμφανίζει ένα nag screen και στην συνέχεια έχει μια φόρμα με πεδία για pass phases. Αυτό που έπρεπε να κάνω ήταν να μην εμφανίζετε το splash screen και να βρω τα pass phases.

Η αποστολή είχε 3 sections:

A hardcoded Serial

Το πρώτο βήμα πάντα είναι να εκτελέσουμε την εφαρμογή για να δούμε τι εμφανίζει ώστε να αναλύσουμε τον τρόπο που θα κινηθούμε. Έτσι και εγώ εκτέλεσα τον πρόγραμμα και πάτησα το κουμπί “Check Hardcoded”. Ένα message box με το κείμενο “Sorry, please try again” εμφανίστηκε στην οθόνη.

Έτσι σκέφτηκα να ψάξω να βρω το κείμενο μέσα στον Win32Dasm. Βρήκα 2 διευθύνσεις που είχε το κείμενο.

A)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401386(C)

|

:004013D2 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->”Splish, Splash”

|

:004013D4 680A304000              push 0040300A

* Possible StringData Ref from Data Obj ->”Sorry, please try again.”

|

:004013D9 6867304000              push 00403067

:004013DE 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh

|

:004013E0 E863030000              Call 00401748

B)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004016C8(C)

|

:004016E2 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->”Splish, Splash”

|

:004016E4 680A304000              push 0040300A

* Possible StringData Ref from Data Obj ->”Sorry, please try again.”

|

:004016E9 6867304000              push 00403067

:004016EE 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh

|

:004016F0 E853000000              Call 00401748

Έβαλα ένα breakpoint στο πρώτο reference “004013D9″,έτρεξα την εφαρμογή και πάτησα το κουμπί “Check Hardcoded” και η εκτέλεση σταμάτησε.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040138A(U)

|

:0040137B 803800                 cmp byte ptr [eax], 00

:0040137E 740C                    je 0040138C

:00401380 8A08                    mov cl, byte ptr [eax]

:00401382 8A13                    mov dl, byte ptr [ebx]

:00401384 38D1                    cmp cl, dl

:00401386 754A                    jne 004013D2

:00401388 40                      inc eax

:00401389 43                      inc ebx

:0040138A EBEF                    jmp 0040137B

Η κλήση του message box έγινε από την διεύθυνση 00401386. Έτσι πήγα εκεί να δω τον κώδικα. Είχε την εντολή “jne 004013D2″ για την εντολή “cmp cl, dl”, μάλλον ένας έλεγχος χαρακτήρα-χαρακτήρα “byte ptr [eax]” & “byte ptr [ebx]“, προηγούμενες εντολές. Είδα στην μνήμη τι περιέχουν και ανακάλυψα ότι η μία είχε αυτό που πληκτρολόγησα ενώ η άλλη πιθανών τον σωστό password. Έτσι λοιπόν πήγα στην διεύθυνση μνήμης της μεταβλητής για να δω τι περιέχει. Οπότε στην θέση 401353 βρήκα το κείμενο “HardCoded”. Ξαναέτρεξα την εφαρμογή και έβαλα αυτό το password, εμφανίστηκε το μήνυμα “Congratulations, you got the hard coded serial”.

A simple serial-protection

Με παρόμοιο τρόπο, γεμίζουμε τα πεδία με ένα όνομα και ένα serial. Εγώ έβαλα “Kostas” και “1″ και πάτησα το κουμπί να δω τι θα γίνει. Εμφανίστηκε το ίδιο μήνυμα λάθους “Sorry, please try again.”. Έτσι αμέσως κατάλαβα ότι είναι η 2η αναφορά στο message box που βρήκα προηγουμένως. Έβαλα ένα break point στην διεύθυνση “004016E9″ και ξαναδοκίμασα με τα ίδια δεδομένα. Γενικά αυτή είναι η ποιο απλή μεθοδολογία για να ψαρέψεις ένα password. Ο debugger σταμάτησε πριν εμφανιστεί το message box. Βρήκα την διεύθυνση απ’ όπου είχε έρθει 004016C8.Πηγά εκεί και βρήκα την εντολή “jne 004016E2″ για την εντολή “cmp eax, ecx”

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040167C(U)

|

:004016A8 8D354D324000            lea esi, dword ptr [0040324D]

:004016AE 8D3D58324000            lea edi, dword ptr [00403258]

:004016B4 33DB                    xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004016CB(U)

|

:004016B6 3B1D63344000            cmp ebx, dword ptr [00403463]

:004016BC 740F                    je 004016CD

:004016BE 0FBE041F                movsx eax, byte ptr [edi+ebx]

:004016C2 0FBE0C1E                movsx ecx, byte ptr [esi+ebx]

:004016C6 3BC1                    cmp eax, ecx

:004016C8 7518                    jne 004016E2

:004016CA 43                      inc ebx

:004016CB EBE9                    jmp 004016B6

Μάλλον και εδώ έχουμε έλεγχο string και σίγουρα έχουν σχέση τα κείμενα που έχω δώσει στα πεδία. Πήγα στην “0040167C” που είναι reference από compare και βρήκα τα παρακάτω:

* Reference To: USER32.GetWindowTextA, Ord:015Bh

|

:0040160D E818010000              Call 0040172A

:00401612 85C0                    test eax, eax

:00401614 7468                    je 0040167E

:00401616 A363344000              mov dword ptr [00403463], eax

:0040161B 33C9                    xor ecx, ecx

:0040161D 33DB                    xor ebx, ebx

:0040161F 33D2                    xor edx, edx

:00401621 8D3536324000            lea esi, dword ptr [00403236]

:00401627 8D3D58324000            lea edi, dword ptr [00403258]

:0040162D B90A000000              mov ecx, 0000000A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401650(C)

|

:00401632 0FBE041E                movsx eax, byte ptr [esi+ebx]

:00401636 99                      cdq

:00401637 F7F9                    idiv ecx

:00401639 33D3                    xor edx, ebx

:0040163B 83C202                  add edx, 00000002

:0040163E 80FA0A                  cmp dl, 0A

:00401641 7C03                    jl 00401646

:00401643 80EA0A                  sub dl, 0A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401641(C)

|

:00401646 88141F                  mov byte ptr [edi+ebx], dl

:00401649 43                      inc ebx

:0040164A 3B1D63344000            cmp ebx, dword ptr [00403463]

:00401650 75E0                    jne 00401632

:00401652 33C9                    xor ecx, ecx

:00401654 33DB                    xor ebx, ebx

:00401656 33D2                    xor edx, edx

:00401658 8D3542324000            lea esi, dword ptr [00403242]

:0040165E 8D3D4D324000            lea edi, dword ptr [0040324D]

:00401664 B90A000000              mov ecx, 0000000A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040167A(C)

|

:00401669 0FBE041E                movsx eax, byte ptr [esi+ebx]

:0040166D 99                      cdq

:0040166E F7F9                    idiv ecx

:00401670 88141F                  mov byte ptr [edi+ebx], dl

:00401673 43                      inc ebx

:00401674 3B1D67344000            cmp ebx, dword ptr [00403467]

:0040167A 75ED                    jne 00401669

:0040167C EB2A                    jmp 004016A8

Εδώ έχουμε πολύ κώδικα. Ξέχασα να αναφέρω ξεσκόνισα ότι βιβλίο είχα για assembly από την σχολή μου, γιατί είχα ξεχάσει όλες τις εντολές και τους καταχωρητές του επεξεργαστή.

Μετά από πολύ μελέτη πάνω στον κώδικα έφτασα στο συμπέρασμα ότι έχουμε ένα decoded name το οποίο φτιάχνει το σωστό serial (00401632-00401650).

Ο αλγόριθμος είναι κάπως έτσι: για κάθε χαρακτήρα του ονόματος χρησιμοποιεί την cdq εντολή, idiv με ecx=0×0A, και στην συνέχεια το υπόλοιπο της idiv γίνεται xor με τον αριθμό της θέσης του χαρακτήρα μέσα στο string (σίγουρα πολλοί προγραμματιστές έχουν χρησιμοποιήσει την θέση του χαρακτήρα, χωρίς όμως να γνωρίζουν ότι είναι πολύ απλός σε assembly) και προσθέτει το 2. Αν το αποτέλεσμα είναι > 10 τότε αφαιρεί το 10.

πχ. Για τον χαρακτήρα K έχουμε 0×4B = 75 MOD 10 = 5 XOR 0 = 5 + 2 = 7.

Με τον ίδιο αλγόριθμο για το κείμενο “Kostas” έχουμε serial “729752″, άλλα είναι αυτό το σωστό :(

Όχι γιατί έχουμε και decoded serial το οποίο δημιουργείτε εδώ (00401669-0040167A).

Η διαφορά με τον προηγούμενο αλγόριθμό είναι η εντολή “add edx,00000002″.

Έτσι τελικά το σωστό serial υπολογίζεται για κάθε αριθμό του προηγούμενου serial προσθέτοντας το  2 και αν είναι > 10 τότε αφαιρεί το 10.

Στο παράδειγμα μας έχουμε “941974″. :)

Τρέχουμε το πρόγραμμα (χωρίς debugger) βάζουμε το “Kostas”, serial “941974″,

και εμφανίζεται το μήνυμα “Good job, now key gen it”.

A Nag-Screen at startup

Πρώτα εκτελούμε τον debuger και προχωράμε βήμα-βήμα την εκτέλεση της εφαρμογής μέχρι να βρούμε που εμφανίζεται το nag screen.

* Reference To: USER32.GetSystemMetrics, Ord:0143h

|

:00401060 E8BF060000              Call 00401724

:00401065 50                      push eax

:00401066 FF3573344000           push dword ptr [00403473]

:0040106C E8F0030000              call 00401461

:00401071 A37B344000              mov dword ptr [0040347B], eax

:00401076 FF7508                  push [ebp+08]

:00401079 E8F9030000              call 00401477

:0040107E C745D030000000          mov [ebp-30], 00000030

:00401085 C745D403000000          mov [ebp-2C], 00000003

:0040108C C745D878114000          mov [ebp-28], 00401178

:00401093 C745DC00000000          mov [ebp-24], 00000000

:0040109A C745E000000000          mov [ebp-20], 00000000

:004010A1 FF7508                  push [ebp+08]

:004010A4 8F45E4                  pop [ebp-1C]

:004010A7 C745F010000000          mov [ebp-10], 00000010

:004010AE C745F400000000          mov [ebp-0C], 00000000

Στην εντολή “call 00401477″ ανοίγει το nag screen, έτσι αν προσπεράσουμε το “jmp to 0040107E” έχουμε βρει την λύση :)

Υπάρχουνε πολλές διαφορετικές λύσεις. Μία από αυτές είναι αντί για το “call 00401477″ να το αντικαταστήσουμε με το “jmp 0040107E”. Άλλη μία λύση είναι να αντικατασταθεί με 5 nop εντολές. Η nop εντολή είναι μια εντολή που έχει ο επεξεργαστής, ώστε να μην κάνει τίποτα.

Θα μου πείτε γιατί υπάρχει αφού δεν κάνει τίποτα, άλλα στον προγραμματισμό τα έχουμε συνηθίσει αυτά, null στην C, “&nbsp;” στην html, “none” στα css κτλ.

Για να πειράξουμε το αρχείο χρειαζόμαστε ένα hex editor, βρήκα έναν τον hexedit, άνοιξα τη εφαρμογή πήγα στην διεύθυνση 0×479 (αφού πρώτα έπρεπε να μάθω πως υπολογίζω την σχετική διεύθυνση από την θέση μνήμης στην θέση αρχείου και έβαλα 0×90 (nop) μέχρι την διεύθυνση 0×47D και δημιούργησα μία άλλη εφαρμογή χωρίς nag screen.

Αν θέλετε να πειραματιστείτε με το project κατεβάστε το εκτελέσιμο απο εδώ.

Reverse Engineering , ,

Awstats και ελληνικά

January 8th, 2009

Ένα απο τα πιό γνωστά open source λογισμικά για την στατιστική παρακολούθηση ιστοσελίδων είναι το awstats. Στην Netwerk το παρέχουμε σε όλους τους web hosting λογαριασμούς και είμαστε αρκετά ευχαριστημένοι. Το μόνο μειονέκτημα που ανακαλύψαμε είναι οτι δέν υποστηρίζονται τα ελληνικά απευθείας. Εκεί έπρεπε να βάλουμε το χεράκι μας :)

Γενικά για το Awstats

Για όσους τυχαίνει να μήν γνωρίζουν το awstats, να πούμε μερικά βασικά πραγματάκια. Το awstats είναι ένα πρόγραμμα στατιστικών το οποίο παίρνει δεδομένα απο τα log files του web server (μπορεί να πάρει και με javascript αλλά αυτό είναι άλλη ιστορία). Σε αντίθεση με το google analytics που λειτουργεί εξ’ολοκλήρου με javascript το awstats μπορεί να μας πληροφορίσει για όλο το traffic του site μας, περιλλαμβάνοντας τις επισκέψεις bots είτε πρόκειται για search engine crawlers είτε για κακόβουλους χρήστες, οπότε σε γενικές γραμμές είναι ένα απαραίτητο εργαλείο άσχετα με το αν το analytics μπορεί να μας δώσει καλύτερη πληροφορία σχετικά με τους επισκέπτες ενός site.

Awstats και ελληνικά

Η βασική ρύθμιση που πρέπει να κάνουμε για να λειτουργήσει το awstats με ελληνικά είναι η ενεργοποίηση του plugin decodeutfkeys. Μιλώντας για plugins να κάνω μιά παρένθεση και να σας συστήσω να χρησιμοποιήσετε κάποιο απο τα geoIP plugins ωστε να βλέπετε τις χώρες απο τις οποίες έρχονται οι επισκέπτες σας.

Εφόσον ενεργοποιηθεί το decodeutfkeys θα βλέπετε τα ελληνικά keywords στις μηχανές αναζήτησης, ωστόσο δέν θα εμφανίζονται τα ελληνικά urls. Για αυτό μπορείτε να χρησιμοποιήσετε το παρακάτω hack που δημιουργήσαμε.

Awstats και ελληνικά urls

Για να χρησιμοποιήσετε το hack απλώς βρείτε στο awstats.pl αυτά που έχω κάνει σχόλια (# removed by thek) και αντικαταστήστε με τον παρακάτω κώδικα:


# my $nompage = CleanXSS($url); # removed by thek

# { patched by thek

my $nompage = "";

if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) {

$nompage = CleanXSS(

DecodeKey_decodeutfkeys(

$url, $PageCode || 'iso-8859-1'

)

);

}

else { $nompage = CleanXSS( $url ); }

# } patched by thek

# { removed by thek

#if ( length($nompage) > $MaxLengthOfShownURL ) {

#$nompage = substr( $nompage, 0, $MaxLengthOfShownURL ) . "...";

#}

# } removed by thek

Perl ,