Java Paketbot für Flashgame

05/23/2011 22:58 mr-pink#1
Hallo, ich möchte einen Bot für Shakes & Fidget bauen, ja ich weiß, so etwas gib es schon(Google: SFBot), aber ich will verstehen wie es funktioniert.

Nach einigen Tutorials habe ich mit Auto It einen simplen Pixel Bot geschrieben der sich einloggt.
Der PixelBot ist mir aber zu trivial und mit zu vielen Nachteilen behaftet.

Da es ein Flash Browsergame ist kann ich mir auch nicht per Auto It die Eingabefelder und Buttons krallen und benutzen.
Außerdem scheint es nahezu unmöglich die MemoryPointer zu finden.

Damit bleibt nur ein PaketBot als elegante Lösung, sehe ich das richtig?

Also habe ich weitere Tutorials gelesen und angefangen.
Diesmal aber nicht mit Auto It sondern mit Java, da ich mehrmals gelesen habe das Auto It recht langsam ist und ich mich mit Java schon enigermaßen auskenne.

Mit Live HTTP Headers habe ich die Pakete abgefangen die gesendet werden wenn ich mich bei dem Spiel einlogge.
Wichtig scheint dieses zu sein:
Code:
http://gamona.sfgame.de/request.php?req=00000000000000000000000000000000002 [B]USERNAME[/B] %3B [B]PASSWORT IN MD5[/B] %3Bv1.60&rnd=1273818731

GET /request.php?req=00000000000000000000000000000000002 [B]USERNAME[/B] %3B [B]PASSWORT IN MD5[/B] %3Bv1.60&rnd=1273818731 HTTP/1.1
Host: gamona.sfgame.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: POPUPCHECK=1306178663925
Der Wert rnd nach dem Passwort wird glaube ich zufällig gesetzt.

Dann habe ich mich an mein Java Prgramm gesetzt:

Code:
import java.net.*;
import java.io.*;

public class Login {

	public static void main(String[] a) 
	{

		String name = "UserName";
		String pw = "PasswortInMD5";
		
		try {
			URL gameUrl = new URL("http://gamona.sfgame.de/");

			Socket server = new Socket(gameUrl.getHost(), 80);

			//Muss ich das alles senden...
			schreibeNachricht(server,"GET /request.php?req=00000000000000000000000000000000002" + name + "%3B" + pw + "%3Bv1.60&rnd=8564654657 HTTP/1.1\n" +
									 "Host: gamona.sfgame.de\n" +
									 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\n" +
									 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n" +
									 "Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3\n" +
									 "Accept-Encoding: gzip, deflate\n" +
									 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n" +
									 "Keep-Alive: 115\n" +
									 "Connection: keep-alive\n" +
									 "Cookie: POPUPCHECK=1306178663925");
			//...oder nur das?
			schreibeNachricht(server,"gamona.sfgame.de/request.php?req=00000000000000000000000000000000002"+name+"%3B"+pw+"%3Bv1.60&rnd=111111113");	
			
			System.out.println(leseNachricht(server));
			

		} catch (MalformedURLException e) {
			System.err.println("Server nicht gefunden");
		} catch (IOException e) {
			System.err.println("I/O Fehler");
		}
	}
	
	
	 private static void schreibeNachricht(java.net.Socket socket, String nachricht) throws IOException 
	 {
         PrintWriter printWriter =
            new PrintWriter(
                new OutputStreamWriter(
                    socket.getOutputStream()));
        printWriter.print(nachricht);
        printWriter.flush();
    }
	 
	 private static String leseNachricht(java.net.Socket socket) throws IOException 
	 {
	        BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
	        char[] buffer = new char[1000];
	        int anzahlZeichen = bufferedReader.read(buffer, 0, 1000); 
	        String nachricht = new String(buffer, 0, anzahlZeichen);
	        return nachricht;
	    }
}
Zum einen weiß ich nicht was ich alles senden muss, da ich ja ein Http Paket senden will wohl eher da ganze.
Dabei bekomme ich aber keine Rückmeldung vom Server :(

Wenn ich nur die eine Zeile sende bekomme ich folgende Meldung:
PHP Code:
HTTP/1.1 400 Bad Request
Content
-Typetext/htmlcharset=us-ascii
Server
Microsoft-HTTPAPI/2.0
Date
Mon23 May 2011 20:46:12 GMT
Connection
close
Content
-Length326

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<
HTML><HEAD><TITLE>Bad Request</TITLE>
<
META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<
BODY><h2>Bad Request Invalid Verb</h2>
<
hr><p>HTTP Error 400. The request verb is invalid.</p>
</
BODY></HTML
Der Server kann mit meiner Anfrage also nichts anfangen.

Und weiter weiß ich nicht...

Ist mein Ansatz richtig?
Warum bekomme ich keine Rückmeldung, wenn ich das Paket versende?
Ist das was in dem Paket steht richtig?

Wenn jemand von euch davon Ahnung hat und mir Tipps geben kann würd ich
mich echt freuen.

Danke schonmal fürs Lesen :)
05/23/2011 23:36 5769854332#2
Weiß nicht, ob das alle Probleme löst, aber du solltest HTTP Header mit 'zwei Leerzeilen' beenden. "Cookie: POPUPCHECK=1306178663925\n\n"
Evtl antwortet der Server nicht, und wartet stattdessen auf ein zweites Packet, in dem das Ende des Headers angezeigt wird.

Der 404 BadRequest liegt evtl. an dem Fragezeichen im Request ("php?..."). Du musst schon GET, POST usw. verwenden.

Die gesendeten Pakete kannst du dir mit Wireshark :handsdown: ansehen. Link: [Only registered and activated users can see links. Click Here To Register...]
05/23/2011 23:44 mr-pink#3
Danke :)
Das mit den 2 Leerzeilen am Ende hat funktioniert und ich bekomme jetzt eine Rückmeldung:

PHP Code:
HTTP/1.1 200 OK
Content
-Typetext/html
Server
Microsoft-IIS/7.5
X
-Powered-ByPHP/5.3.5
Date
Mon23 May 2011 21:42:34 GMT
Content
-Length4

E006 
Was das bedeutet und wie ich weitermache überlege ich wenn ich morgen wieder wach bin.
05/23/2011 23:45 Shadow992#4
Quote:
Originally Posted by Kiakar View Post
Weiß nicht, ob das alle Probleme löst, aber du solltest HTTP Header mit 'zwei Leerzeilen' beenden. "Cookie: POPUPCHECK=1306178663925\n\n"
Evtl antwortet der Server nicht, und wartet stattdessen auf ein zweites Packet, in dem das Ende des Headers angezeigt wird.

Der 404 BadRequest liegt evtl. an dem Fragezeichen im Request ("php?..."). Du musst schon GET, POST usw. verwenden.

Die gesendeten Pakete kannst du dir mit Wireshark :handsdown: ansehen. Link: [Only registered and activated users can see links. Click Here To Register...]
Es muss kein doppelter hin, aber es muss ein cariagereturn hin, also ein
"\r\n".
05/23/2011 23:50 mr-pink#5
Mir \r\n bekomme ich aber auch keine Rückmeldung und der Prozess terminiert nicht.
05/24/2011 00:06 Shadow992#6
Quote:
Originally Posted by mr-pink View Post
Mir \r\n bekomme ich aber auch keine Rückmeldung und der Prozess terminiert nicht.
Kann sein, dass es bei Java etwas anders abläuft als bei C/C++.
Aber wenn es doch gleich sein sollte, dann musst du das überall machen.

Ansonsten bin ich mir ziemlich sicher, dass es vorgefertigte Funktionen dafür bereits in Java gibt.

Edit:
Mir ist jetzt erst dein "AutoIt" Beisatz aufgefallen, auch mit AutoIt sind Packetbots möglich:
[Only registered and activated users can see links. Click Here To Register...]
05/24/2011 12:12 mr-pink#7
Das Auto It Tutorial hatte ich auch schon gelesen, wollte es aber dennoch lieber mit Java versuchen.
Der Login funktioniert dank eurer Tipps nun auch :)
Das Paket wird jetzt so gesendet:
PHP Code:
"GET /request.php?req=00000000000000000000000000000000002" name "%3B" pw "%3Bv1.60&rnd=8464654557 HTTP/1.1\r\n" +
"Host: gamona.sfgame.de\r\n" +
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3\r\n" +
"Accept-Encoding: gzip, deflate\r\n" +
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
"Keep-Alive: 115\r\n" +
"Connection: keep-alive\r\n" +
"Cookie: POPUPCHECK=1306178663925\r\n"
"\r\n" 
Also sowohl mit \r als auch einer Leerzeile am Ende.

Als Antwort erhalte ich:
PHP Code:
HTTP/1.1 200 OK
Content
-Typetext/html
Server
Microsoft-IIS/7.5
X
-Powered-ByPHP/5.3.5
Date
Tue24 May 2011 09:35:35 GMT
Content
-Length1748

0021825119273
/20151/1306236936/1274449785/-931166381/21/0/106/2660666/4079265/27801/1431/-1/65620/2/105/146/4/201/204/3/205/5/1/2/1/0/3/1/3/477/793/475/728/591/103/1362/103/769/769/401/713/400/647/513/2/2/1306237317/6/2009/600/0/2/5/3/203/0/0/108719/0/3/2051/542/0/2/4/5/118/118/118/281494/0/5/2051/579/0/2/4/5/109/109/109/1071532/0/4/2050/284/0/2/4/5/90/90/90/684420/0/8/51/0/0/2/4/5/126/126/126/363810/0/7/2051/525/0/2/4/5/110/110/110/1524738/0/9/50/0/0/2/4/5/113/113/113/1263140/0/10/55/0/0/6/0/0/103/0/0/1824550/0/1/2010/140/364/2/3/4/390/0/0/392684/0/0/0/0/0/0/0/0/0/0/0/0/0/0/6/0/0/11/1/0/24/94/0/0/0/12/15/0/0/11/5/0/24/212/0/79115/0/12/14/0/0/11/4/0/24/229/0/85381/0/12/11/0/0/11/1/0/24/216/0/80682/0/12/12/0/0/11/2/0/24/223/0/83032/0/1306236687/106/106/106/2/6/3/-24/-116/-25/5/11/4/420/630/630/0/18/0/0/5/3/1/124/78/0/140683/0/0/12/0/0/5/1/3/122/76/0/131846/0/0/16/0/0/3/2/5/123/77/0/136166/0/65900/102900/71300/143300/193500/390500/3/1306190839/4/2010/593/0/2/1/3/205/0/0/1017652/0/1/2009/218/298/4/5/1/198/190/0/796180/10/6/2008/353/0/1/4/3/203/0/0/949716/0/3/2010/645/0/2/3/1/204/0/0/1015887/0/1/2009/152/372/2/5/3/238/166/0/1372974/10/5/2008/333/0/4/1/2/124/82/0/689289/10/1306190832/8/20/0/0/1/2/4/97/91/0/217642/10/10/3/0/0/1/2/3/192/0/0/689160/0/10/14/0/0/3/1/2/119/85/0/477638/10/8/1/0/0/3/5/2/212/0/0/521992/1/10/37/0/0/1/5/2/118/80/0/462254/0/10/10/0/0/1/5/3/196/0/0/750575/0/11/0/1327/3/0/1/132920/0/0/0/1279143409/1/0/0/2530/140/364/0/1306788260/0/10/0/1306226263/960/0/60/1305844463/1305632909/106/96/1/1274867460/106/60/206/2252/2591/279210521/27801/0/0/65/0/0/2/1306099414/0/12/12/12/12/12/9/5/2/0/0/120/0/0/0/0/0/0/0/0/0/0/0/0/-583669117/-583669117/-583669117/0/0/0/573/1306236936/;0;058428236738365007R01BjTl5064399;0;354 
Erwartet hatte ich etwas anderes, aber nach etwas rumgesuche und ausprobieren habe ich einige Werte(Gold, Silber, Pilze, Item-Eigenschaften...) erkannt.

Mit etwas Fleiß kann ich also die relevanten Werte herausfinden.

Noch nicht ganz klar ist mir was ich mit den ; am Ende machen soll.
Der Eine Wert scheint wieder ein Hash zu sein, aber wofür...
Naja, ich denke das kann ich erst noch ignorieren.

Mein nächster Schritt wird sein die Navigation auf der Seite zu simulieren.
Dazu werde ich ich erstmal die Paket abfangen die gesendet werden, wenn ich auf einen Knopf klicke, um zB zur "Taverne" zu kommen.
Mal sehen was ich dabei herausfinden...
05/24/2011 16:24 Shadow992#8
Benutze den Java-Code, dann wird dir einiges klarer werden. ;)
Code:
import java.net.*;
import java.io.*;

public class Login {

	public static void main(String[] a) 
	{

		String name = "UserName";
		String pw = "PasswortInMD5";
		
		try {
			URL gameUrl = new URL("http://gamona.sfgame.de/");

			Socket server = new Socket(gameUrl.getHost(), 80);

			//Muss ich das alles senden...
			schreibeNachricht(server,"GET /request.php?req=00000000000000000000000000000000002" + name + "%3B" + pw + "%3Bv1.60&rnd=8564654657 HTTP/1.1\n" +
									 "Host: gamona.sfgame.de\n" +
									 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\n" +
									 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n" +
									 "Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3\n" +
		
									 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n" +
									 "Keep-Alive: 115\n" +
									 "Connection: keep-alive\n" +
									 "Cookie: POPUPCHECK=1306178663925");
			//...oder nur das?
			schreibeNachricht(server,"gamona.sfgame.de/request.php?req=00000000000000000000000000000000002"+name+"%3B"+pw+"%3Bv1.60&rnd=111111113");	
			
			System.out.println(leseNachricht(server));
			

		} catch (MalformedURLException e) {
			System.err.println("Server nicht gefunden");
		} catch (IOException e) {
			System.err.println("I/O Fehler");
		}
	}
	
	
	 private static void schreibeNachricht(java.net.Socket socket, String nachricht) throws IOException 
	 {
         PrintWriter printWriter =
            new PrintWriter(
                new OutputStreamWriter(
                    socket.getOutputStream()));
        printWriter.print(nachricht);
        printWriter.flush();
    }
	 
	 private static String leseNachricht(java.net.Socket socket) throws IOException 
	 {
	        BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(socket.getInputStream()));
	        char[] buffer = new char[1000];
	        int anzahlZeichen = bufferedReader.read(buffer, 0, 1000); 
	        String nachricht = new String(buffer, 0, anzahlZeichen);
	        return nachricht;
	    }
}