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, “ ” στην 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 ,

10 must εργαλεία για reverse engineering

December 17th, 2008

Παρακάτω είναι μια λίστα με διάφορα εργαλεία για reverse engineering που μπορείτε να χρησιμοποιήσετε αν ασχολείστε με το “σπόρ”.

Servant Salamander

Το Servant Salamander είναι ένα φανταστικό εργαλείο γενικά για development αλλα και για απλούς χρήστες. Το salamander είναι ένας file manager που θυμίζει λίγο το παλιό norton commander, ωστόσο παρέχει αρκετές ευκολίες για τους επαγγελματίες χρήστες του, όπως file compare, ενσωματομένο ftp και sftp client, κτλ. Αξιοσημείωτο οτι ακόμα και στην αντιγραφή αρχείων είναι πιό γρήγορος απο τα windows :)

EmEditor

O emEditor είναι ένας απλός text editor ο οποίος παρέχει ένα βασικό code highlighting και “παίζει” με οποιοδήποτε encoding(και UTF8). Δέν παρέχει τις ευκολίες ενός επαγγελματικού IDE ωστόσο είναι πολύ καλό για την περίπτωση που θέλουμε να επεξεργαστούμε ένα αρχείο γρήγορα.

Hex Editor

Ένας hex editor είναι τουλάχιστον απαραίτητος για όποιον ασχολείται με reverse engineering. Προσωπικά χρησιμοποιώ τον WinHex αλλά μπορείτε να δείτε και τον xvi32 που είναι freeware.

IDA Pro Dissasembler & Debugger

Ο  IDA Pro είναι ένας πολύ δυνατός dissasembler. Το εργαλείο παρέχει και debugger ωστόσο για αυτή την χρήση καλύτερα προτιμίστε τον…

OllyDbg Debugger

Ο OllyDbg είναι ο πιό εύχρηστος debugger που έχω βρεί μεχρι στιγμής.

RegMon

Το RegMon είναι ένα utility που αγοράστηκε απο την Microsoft. Η δουλειά του είναι να σας δείχνει ποιές εφαρμογές κάνουν αλλαγές στο registry.

FileMon

Το FileMon που επίσης έχει εξαγοραστεί απο την Microsoft είναι ένα εργαλείο που παρακολουθεί τις αλλαγές στο filesystem σε real time.

LordPE

To LordPE(screenshot) είναι ένα freeware εργαλειάκι που διαχειρίζεται πολλά κομμάτια αρχείων PE (Portable Executable)

Winspector

Ο Winspector είναι ίσως το καλύτερο alternative για τον Spy++ που έρχεται με το Visual Studio.

Resource Hacker

Το τελευταίο προγραμματάκι στην λίστα μας, ο Resource Hacker, βοηθάει στην διαχείριση resource files. Μπορείτε να το χρησιμοποιήσετε για να δείτε ή και να επεξεργαστείτε resource files και resources απο εκτελέσιμα αρχεία.

Bonus εργαλείο

Το 11ο εργαλείο που παρουσιάζουμε σήμερα, είναι μια δική μου, open source, προσθήκη για php developers. Ονομάζεται php hexed και χρησιμοποιείται σαν patch script engine και μπορεί να συνεργάζεται με τον Win32Dasm και με τον OllyDbg. Αργότερα θα κάνω post κάποιο παράδειγμα, οπότε αν σας ενδιαφέρει μείνετε συντονισμένοι :)

Reverse Engineering, php , ,

FirePHP για την έκδοση 4 του PHP

December 6th, 2008

Είμαι σίγουρος ότι δεν υπάρχει web developer που να μην γνωρίζει το Firebug. Για όποιον δεν το γνωρίζει είναι ένα firefox extension που βοηθάει τον developer στην κατασκευή ενός site. Μπορείτε να επεξεργαστείτε και να κάνετε debug javascript, css και html πάνω στα πραγματικά δεδομένα και σε πραγματικό χρόνο. Βεβαία οι δυνατότητες του δεν έχουν όρια…, εγώ πχ. σαν reverser τον χρησιμοποιώ και διαφορετικά. Δεν θέλω να επεκταθώ παραπάνω για τον firebug γιατί δεν είναι και το θέμα του άρθρου. Όποιος όμως θέλει να μάθει περισσότερα μια αναζήτηση στο google και θα βρει αξιόλογα πράγματα. Εγώ βρηκα σε ένα ελληνικό blog 11 tips.

Ξεφύγαμε στο θέμα μας. FirePHP ένα πολύ δυνατό firefox extension που παράλληλα με το firebug μπορούμε να κατευθύνουμε τα php (error και debug) μηνύματα μας στην κονσόλα του firebug. Στο site του firephp μπορείτε να βρείτε μία php class που μπορείτε να την ενσωματώσετε στο project σας και να χρησιμοποιείτε την firebug console.

Τι γίνεται όμως αν χρησιμοποιείτε την έκδοση 4 του php ακόμα ? Δεν υπάρχει τίποτα και δεν πρόκειται να βγάλουν, διότι όσο έψαξα, όλοι λένε “php4 is dead”. Προσωπικά δεν νομίζω να ισχύει αυτό διότι υπάρχουν πολλά projects που τρέχουν σε php4 και δεν έχουν περάσει σε php5. Εμείς π.χ. στην Netwerk δεν έχουμε γυρίσει 100% σε php5 σε όλα μας τα project.

Έτσι σκέφτηκα να δημιουργήσω from scratch (πολύ το γουστάρω αυτό) μία function που να εμφανίζει της μεταβλητές που θέλω, σε πρώτη φάση, και στην συνέχεια να την ενσωματώσω στον error handler του php και στον mysql error handler ώστε να μου εμφανίζει τα php και mysql errors. Το ποιο ωραίο είναι ότι μπορείς να δεις και ένα dump από ένα mysql query με μορφή table καθώς και ένα πολύπλοκο array ή object, γιατί ανοίγει ένα παραθυράκι στη μέση της οθόνης με scroll.

Το καλό με τον firephp είναι ότι δεν σου χαλάει το site ένα error που θα εμφανιστεί ή ένα dump που θέλεις να κάνεις. Άντε πολύ ασχοληθήκαμε με την θεωρεία, πάμε σε λίγο ανάλυση και κώδικα.

Πως δουλεύει ο firephp; Πολύ έξυπνο χρησιμοποιεί δικούς του headers με μία πολύ έξυπνη δομή. Υπάρχει η προηγούμενη έκδοση X-FirePHP (ασχολήθηκα λίγο και την παράτησα) και η τωρινή X-Wf που είναι πολύ ποιο βελτιωμένη.

Έφτιαξα λοιπόν μια function την dev (την ονόμασα έτσι γιατί την είχα και παλιά, απλά τα τύπωνε στον browser), η οποία στην ουσία στέλνει τα κατάλληλα headers. Για json χρησιμοποείσα την php class Services_JSON.

function dev($a0) {
static $messageIndex=1;
if ($messageIndex==1) {
header('X-Wf-Protocol-1:http://meta.wildfirehq.org/'.'Protocol/JsonStream/0.2');
header('X-Wf-1-Plugin-1:http://meta.firephp.org/'.'Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0');
header('X-Wf-1-Structure-1:http://meta.firephp.org/'.'Wildfire/Structure/FirePHP/FirebugConsole/0.1');
}
$type='INFO';
$args=func_get_args();
if (is_string($type)) {
$a0=strtoupper($a0);
if ($a0=='LOG' || $a0=='INFO' || $a0=='WARN' || $a0=='ERROR' || $a0=='TABLE') {
array_shift($args);
$type=$a0;
}
}

include_once('json.php');
$json = new Services_JSON();
$_ar=debug_backtrace();
if (strstr($_ar[0]['file'],'cmysql')) {
array_shift($_ar);
}
elseif (is_array($args[0]) && $args[0][msg]) {
$_ar[0]=$args[0];
$args[0]=$args[0][msg];
}
foreach($args as $arg) {
if (is_resource($arg)) $arg=get_resource_type($arg);
$meta=array('Type'=>$type,'File'=>$_ar[0]['file'],
'Line'=>$_ar[0]['line']);
$msg='['.$json->encode($meta).','.$json->encode($arg).']';
$parts=explode("\n",chunk_split($msg,5000,"\n"));
for($i=0; $i
$part = $parts[$i];
if ($part) {
if(count($parts)>2) {
header('X-Wf-1-1-1-'.$messageIndex.':'.
(($i==0)?strlen($msg):'').'|'.
$part.'|'.(($i
}
else {
header('X-Wf-1-1-1-'.$messageIndex.':'.
strlen($part).'|'.$part.'|');
}
$messageIndex++;
}
}
}
}

Έπειτα χρησιμοποίησα την set_error_handler και την σύνδεσα με την dev για να έχω και τα php error.

function errorHandler($errno, $errmsg, $filename, $linenum, $vars) {
if(error_reporting()!=0) {
$errortype = array(
E_ERROR           => "ERROR",
E_WARNING         => "WARN",
E_PARSE           => "ERROR",
E_USER_ERROR      => "ERROR",
E_USER_WARNING    => "WARN",
);
if ($errortype[$errno]) {
dev($errortype[$errno],array("msg"=>$errno.': '.
$errmsg,"file"=>$filename,"line"=>$linenum));
}
}
}
set_error_handler("errorHandler");

Σύνδεσα την κλάση που έχω για mysql query ώστε τα error να τα στέλνω στην dev. Τέλος μέσω της dev με τύπο table έδωσα τα αποτελέσματα των queries.

function dump() {
$dbDump = new CMySql();
$dbDump->query($this->Query,-1);
$body=array();
$title = $this->Query." (rows: ".$dbDump->num_rows().", fields: ".($dbDump->num_fields()-1).")";
if ($dbDump->next()) {
$header = array();
foreach($dbDump->record() as $i=>$v) $header[]=$i;
$body[] = $header;
do {
$row = array();
foreach($dbDump->record() as $v) $row[]=$v;
$body[] = $row;
}
while ($dbDump->next());
}
dev('table',array($title, $body));
}

Υπάρχουν και άλλοι τύποι στα headers που δεν ασχολήθηκα ακόμα. Trace, Dump και Groups, αλλά αυτά ας τα αφήσουμε στην php5, για να μην μας πουν ότι κάνουμε και προπαγάνδα κατά της ή ότι στηρίζουμε μόνο την php4. Απλά είναι κρίμα το firephp να είναι προνόμιο της php5, μόνο και μόνο επειδή το αποφάσισαν κάποιοι. Το μόνο configuration που χρειάζεται για να λειτουργήσουν τα παραπάνω, είναι να είναι ανοιχτό το output buffering ή να χρησιμοποιήσετε την ob_start()

php ,