Register for your free account! | Forgot your password?

Go Back   elitepvpers > Metin2 > Metin2 Guides & Templates
You last visited: Today at 11:52

  • Please register to post and access all features, it's quick, easy and FREE!


[How To]Metin2 Funktionen reversen

Reply
 
Old   #1
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
Arrow [How To]Metin2 Funktionen reversen/Write your own Bot

English translation:

Vorwort

Im Folgenden geht es darum, am Beispiel von Metin2 Funktionen im Speicher zu reversen(ich zeige das am Beispiel von SG). Was bringt einem das? Nunja, man kann damit zum Beispiel Bots/Hacks programmieren.
Eingeleitet wird das ganze durch ein paar Basics, welchen man sich bewusst sein sollte, bevor man sich Assemblercode anschaut.
Ich setze hier einige Dinge vorraus. Ums kurz zu halten sollte man schon einmal irgendetwas programmiert haben und sich evtl mit CheatEngine auseinander gesetzte haben. Ist natürlich aber nicht zwingend notwendig. Verbesserungsvorschläge oder Ergänzungen, welche zu einem besseren Verständnis verhelfen, sind gerne gesehen. Ich werde als Beispiel die SendUseItemPacketFunktion nehmen. Wenn mehr gewünscht ist werde ich mit anderen Funktionen weitere Beispiele bringen.(z.B. NetzwerkStream Reader für den Client mit inline Hooking etc..)

1.) Umgebung einrichten


Zuerst einmal müssen wir die nötigen Programme herunterladen und diese konfigurieren.

Benötigte Programme:
CheatEngine
Visual Studio 2015
Irgendein Metin2Client

Zu CheatEngine:
Um Abstürze des Spiels zu vermeiden, hat es sich bei mir bewährt den VEH Debugger zu aktivieren.

2.) Basics

[How To]Eine Funktion reversen(SendItemUse)

Da es bereits Tutorials über PickUp oder ähnliche Funktionen gibt, dachte ich mir ich nehme die SendItemUsePacket, welche es möglich macht, Items automatisch auszurüsten bzw. zu benutzen.

Der Client kommuniziert mit dem Server über Pakete und die SendItemUsePaket teilt dem Server mit, welches Item benutzt werden soll. Diese sieht im Sourcecode folgendermaßen aus:



In dem Bild/Source sind nun Zeichenketten/Strings zu sehen.



Diese wären:
PHP Code:
BINARY_AppendNotifyMessage
CANNOT_EQUIP_EXCHANGE
BINARY_AppendNotifyMessage
CANNOT_EQUIP_SHOP
SendItemUsePacket Error 
Nach diesen Strings können wir den Speicher des Prozesses nun untersuchen.
Zuerst einmal müssen jedoch folgende Schritte durchgeführt werden:

1.) Starte Metin2 und CheatEngine

2.) MemoryViewer in CheatEngine anklicken

3.) Tools -> Dissect Code( oder STRG+J) und Start drücken, um nach Strings zu suchen

4.) Wenn die Stringsuche fertig ist, in der Menüleiste auf View->Referenced Strings( oder STRG-ALT+R) und dann mit STRG+F nach String suchen: "SendItemUsePacket Error"
Man könnte auch nach den anderen oben genannten Strings suchen und würde im Endeffekt auch auf die selbe Lösung kommen.

5.) Klickt man auf den String erscheint rechts eine Adresse. Diese mit Doppelklick anklicken.

Nun zum eigentlichen Part.

Die Funktion finden

Die Stelle an welche wir nun gesprungen sind zeigt:
PHP Code:
"push 012C50AC" CommentSendItemUsePacket Error 
(Natürlich wird die Adresse sehr wahrscheinlich anders bei euch aussehen!)

012C50AC ist eine Adresse im Speicher, an der ein String liegt. Um zu sehen, ob dies auch wirklich stimmt, kann man unten im MemoryViewer bei der Hexansicht einen Rechtsklick machen und mit "Got to Adress" zu dieser Adresse springen.


Es wird also die Adresse, an der die Errormeldung steht, auf den Stack gepusht.

Legen wir nun einen Breakpoint(Um einen Breakpoint zu setzen Rechtsklick auf die Zeile und Toggle Breakpoint auswählen) auf diese Zeile des push Befehls und benutzen ein Item in Metin2, werden wir feststellen, dass dieser nicht auslöst. Warum? Ganz einfach: Weil das Senden des Paketes erfolgreich war und dieser Codeabschnitt deswegen übersprungen wurde.Um ihn auszulösen müssen wir den Breakpoint auf die Zeile dadrüber legen:




Das Spiel ist nun eingefrohren und wir haben die Möglichkeit Schritt für Schritt durch den Code zu steppen(F8), um zu sehen wie sich die Funktion verhält und was für Werte auf dem Stack liegen, bzw in den Registern. Das ist an dieser Stelle jedoch erstmal nicht von Relevanz. Um das Spiel weiterlaufen zu lassen muss F9 gedrückt werden.

Wir haben also die Funktion fürs Erste gefunden.

Wie im Sourcecode zu sehen ist(Bild1), benötigt die Funktion einen Parameter. Und zwar die Position des Items.



Die Datenstruktur des Typs TItemPos sieht wie folgt aus:
PHP Code:
struct TItemPos{
    
BYTE window_type;
    
WORD cell;
}; 
Um die Funktion also benutzen zu können, müssen wir vorher auch angeben, welches Item/bzw Zelle wir benutzen möchten. Dazu muss man wissen wie die Parameterübergabe geschieht:

Bevor eine Funktion aufgerufen wird, werden die Parameter die an die Funktion übergeben werden sollen, auf den Stack gepusht. Wie kriegen wir nun raus, was wir später auf den Stack pushen müssen, um die Funktion zu benutzen? Wir setzen zunächst einen Breakpoint auf den Anfang der Funktion. Diese beginnt in diesem Beispiel bei 0099A740.

Rüsten wir uns nun mit einem Item aus, so freezt das Spiel wieder und wir sehen die Registerwerte. Uns interessiert hierbei nun aber der Stack. Dieser befindet sich im MemoryViewer unten rechts. Um diesen übersichtlicher darzustellen kann man per Rechtsklick in dem Stackfeld "Full Stack" auswählen.
Das sollte nun folgendermaßen aussehen:


Erklärung zum Stackview

Was ihr dort seht ist nun der aktuelle Stack, bzw die Stelle an dem der Stackpointer(ESP Register) momentan steht.
Address(Spalte 1) ist die Addresse, an der ein Wert(Spalte 2) steht. Dieser Wert kann nun ein Pointer auf eine Datenstruktur sein, oder ein 1-4 Byte Wert.
Ende Erklärung Stackv

Der erste Wert ist eine Addresse, und zwar nicht irgendeine Addresse sondern die Returnadresse, welche uns nach dem Durchlauf der Funktion wieder zum eigentlichen Programmablauf bringt.
(Um zu sehen von wo aus diese Funktion also gecalled wird, könnten wir dort hinspringen und evtl weitere interessante Dinge herrausfinden.)

Vorerst noch: Das Item welches ich angezogen habe liegt im Inventar I oben links.
Schauen wir 4Bytes weiter, also die nächste Zeile, sehen wir, dass dort der ein Wert gepusht wurde(Siehe Bild oben).

PHP Code:
00000001 
Das sieht doch schonmal interessant aus.

Gucken wir was passiert, wenn ich das Item in den 2. Platz von links im Inventar platziere, und den Breakpoint erneut auslösen.

Der gepushte Wert, der eben bei 00000001 lag, liegt nun bei 00000101. Lege ich das Item daneben und ziehe es an wird es 00000201 sein, lege ich es in den 5. Slot und benutze es, wird es 00000401 sein... und so weiter. Ihr könnt ja ein wenig testen.

Auffällig ist auf jeden Fall, dass das Byte 01 am Ende immer gleich zu sein scheint und das andere Byte(bzw WORD) die Zelle im Inventar angibt, wobei bei 0 angefangen wird zu zählen(Zelle 1 = Wert 0, Zelle 2 = Wert 1 usw..).

Blicken wir im Tutorial nach oben steht dort die Struktur des Parameters. window_type vom Typ BYTE und cell vom Typ WORD. Word ist ein Datentyp mit 2Bytes.

Alles was wir also vor dem Funktionsaufruf machen müssen, ist die Datenstruktur auf den Stack zu pushen.
Wollen wir also das Item des Slots 10 benutzen, so muss der Wert wie folgt aussehen:

PHP Code:
0x00000A01. (A ist Hexadezimal für 10
Vom Prinzip sieht unser Code nun folgendermaßen aus:

PHP Code:
push 00000A01
call 0099A740 
Das ist jedoch leider noch nicht alles.

Der Klassenpointer

Die Funktion SendItemUsePacket(TItemPos pos) befindet sich in einer Klasse. Und zwar der CPythonNetworkStream class. Der Pointer(Zeiger) auf diese Klasse muss in diesem Fall ebenfalls bekannt sein. Wenn Funktionen aus anderen Klassen aufgerufen werden, wird der Pointer zu dieser Klasse mit angegeben. Dazu ist in der Regel das ECX Register.

Kurz gesagt: Vor dem Aufruf der Funktion SendUseItemPacket wird der Klasspointer in ECX gemoved. Dies müssen wir ebenfalls tun.(Das ist fast immer so!)
Um zu wissen wie der Pointer lautet müssen wir nur wieder einen Breakpoint auf den Anfang! der Funktion legen und ein Item benutzen. Der Wert, welcher sich nun im ECX Register befindet, ist unser gesuchter Klassenpointer. Dies ist jedoch kein statischer Pointer, heißt er wird nur für diesen Prozess funktionieren. Startet ihr das Spiel neu, ist der Pointer ebenfalls neu und euer Code wird nächstes mal nicht mehr hinhauen.

Wie findet man also den statischen Pointer?
Ganz einfach: Man reversed das Ganze ein wenig mehr.Wir wollen also nun herrausfinden, wo der Wert des ECX Registers herkommt. Dazu müssen wir allerdings vor den Aufruf der Funktion. Ich hatte vorher ja schon davon gesprochen, dass sich auf dem Stack, wenn der Breakpoint auslöst, die Rücksprungadresse befindet. Dort machen wir einfach einen Doppelklick drauf und schon landen wir bei dem Funktionsaufruf(call).



Scrollen wir nun etwas hoch sieht man in meinem Beispiel folgendes:


Durch Breakpoints setzen(über dem call) kann man nun herrausfinden, wo das ECX Register geladen wird, wenn es nicht vorher schon offensichtlich ist.
Es kann vorkommen, dass vor dem Funktionsaufruf direkt folgendes steht:
PHP Code:
mov ECX, [0035BD78
Dann habt ihr den statischen Pointer direkt gefunden.

Da das hier nicht offensichtlich ist, müssen wir ein wenig rumprobieren. Wir wissen also das ECX 06CA9ED0 sein muss, also setzen wir Schritt für Schritt Breakpoints(über dem eigentlichen Funktionscall) und warten bis unsere Addresse in den Registern auftaucht.
Ich habe mal auf die Addresse 0098C49B (siehe Bild oben) einen Breakpoint gesetzt und gemerkt, dass das EAX Register nach diesem call den gesuchten Wert hält.(EAX ist das return Register, wo nach dem Funktionsaufruf (meistens) das Ergebnis einer Funktion landet)



Nachfolgender Code(damit ist der Code nach dem call auf 0090BD70 gemeint) schiebt den EAX Wert dann nur noch in das ECX Register. Der call auf 0090BD70 scheint uns also den gesuchten Klassenpointer zu liefern.



Schauen wir uns diese nun genauer an (Rechtsklick auf call 0090BD70 und Follow).



Ahh! Perfekt. Wir sehen einen mov ins EAX Register. Und zwar mov eax, [01482190]. 01482190 ist hierbei eine Adresse im Speicher, an welcher unsere gesuchte Adresse steht.
Sucht man nach der Adresse unten wieder im HexViewer, so findet man an der Stelle 06CA9ED0(bzw D09ECA06-> Im Speicher steht es verkehrt herrum).

4.) Programmierung
Ich werde dazu demnächst mehr schreiben.
Programmcode dazu:
PHP Code:
void UseItem()
{
     
DWORD callToUseItem 0x099A740;
     
_asm{
                
MOV ECXDWORD PTR DS : [0x01482190]
                
PUSH 0x0A01
                CALL callToUseItem
              
}

Bei Fragen Skype: marcel.metin2



.Verkauf´ is offline  
Thanks
24 Users
Old 05/29/2016, 13:53   #2
 
elite*gold: 0
Join Date: Dec 2014
Posts: 403
Received Thanks: 169
schön das sich endlich mal mehr Leute dazu bereitstellen, was in der Reversing Szene in der Metin2 section was beizutragen!

bin aber immernoch einwenig entäuscht von der Programmierung, vorallem in der Metin2 Szene. Wenn du schon die Möglichkeit hast in den Source Code zu schauen (wobei das genau so einfach mit Assembler Code auslesen ist, oder Pseudo Code von einem Disassembler), dann benutze doch auch bitte die Calling Convention von der SendItemUsePacket Funktion, sprich Funktionspointer.

Wozu der ganze inline Assembler Kram (vorsicht: Ironie in meinem Username), wenn man's auch schön mit sicheren Funktionspointer Casts lösen kann?

Die Berechnung für die Position der Items habe ich jetzt rausgenommen, da dies trivial ist. __thiscall eignet sich hier gut, da man einfach auslesen kann, dass die Funktion eine Member-Methode (innerhalb einer Klasse) ist.

Dennoch denke ich, dass der Anwendungs-Part (die Programmierung) nicht nötig sein musste, da du sonst nur den Leuten alles vorkaust und sie im Prinzip auch gleich zur Programmierung springen können und c&p, was sicherlich nicht der Sinn hinter ist.


_asm is offline  
Thanks
1 User
Old 05/29/2016, 17:28   #3
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
Calling conventions sind mir bekannt Wollte das noch editieren, nur bin ich momentan aufgrund meines Studiums nicht in der Lage da was zu editieren.
Trotzdem danke für dein Feedback, werde es demnächst hinzufügen.

Und ja mit dem CopyPaste haste recht(vor allem in diesem Bereich des Forums). Aber irgendwie muss man den Leuten, wenn sie sowas lernen wollen und Interesse haben, die Möglichkeiten zeigen wie man denn vorgehen kann. Hoffe jedoch trotzdem, dass einige was daraus mitnehmen.
Würde das Ganze sonst auch weiterführen, evtl mit VideoTutorials, aber bei der Nachfrage lohnt das leider nicht. Es wird halt doch lieber in die Metin2 Hacks Bots Section gegangen und dort gedownloadet..
.Verkauf´ is offline  
Thanks
2 Users
Old 05/29/2016, 19:18   #4
 
elite*gold: 0
Join Date: Dec 2014
Posts: 403
Received Thanks: 169
bitte tu mir/uns nur den Gefallen und mache keine Video-Tutorials für diesen Bereich. Es wird nur geleeched und das findest du bestimmt auch nicht toll.

Mi4uric3 hat damit schon Erfahrung gemacht und deshalb auch diese Serie von Video-Tutorials und geschriebenen Tutorials beendet.
Ich halte dich nicht davon ab, aber es wäre super wenn nicht jeder Vollidiot gleich spoon-feded wird und unnötigen Kram in der Hack section released...


_asm is offline  
Thanks
1 User
Old 06/19/2016, 12:28   #5
 
elite*gold: 400
Join Date: Dec 2007
Posts: 6,573
Received Thanks: 6,294
Quote:
Originally Posted by Nanoxx™ View Post
Warum sollte man sein Wissen nicht weiter geben? Weil andere damit Geld machen wollen?
Wie bereits von _asm erwähnt habe ich auch mal solche Videos gemacht. Es haben dann Leute genau die Funktionen aus meinen Videos als Bots verkauft und das habe ich nicht eingesehen. Das heißt aber nicht, dass .Verkauf´ das nicht anders sehen darf, es war nur eine Warnung.
Mi4uric3 is offline  
Thanks
1 User
Old 07/03/2016, 00:18   #6
 
elite*gold: 0
Join Date: Apr 2013
Posts: 70
Received Thanks: 29
Sir, I think you shared a gold but i do not understand german.

I don't even know much english word.
Lindeth is offline  
Thanks
2 Users
Old 07/05/2016, 11:10   #7
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
I could write an english translation if u want
.Verkauf´ is offline  
Old 07/07/2016, 00:20   #8
 
elite*gold: 0
Join Date: Apr 2013
Posts: 70
Received Thanks: 29
Yes sir, please.
It'd be great.
Lindeth is offline  
Thanks
1 User
Old 07/07/2016, 14:11   #9
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
#english translation added on the top of the thread

If you guys want more about reversing pn me with ideas.

(like mob_proto reader based on inline hooking or something else...)
.Verkauf´ is offline  
Thanks
1 User
Old 07/07/2016, 19:53   #10
 
elite*gold: 0
Join Date: Apr 2013
Posts: 70
Received Thanks: 29
Quote:
Originally Posted by .Verkauf´ View Post
#english translation added on the top of the thread

If you guys want more about reversing pn me with ideas.

(like mob_proto reader based on inline hooking or something else...)
Thanks sir,

You're awesome.
Lindeth is offline  
Old 09/05/2016, 13:05   #11

 
elite*gold: 457
Join Date: Mar 2008
Posts: 2,540
Received Thanks: 1,596
Ich bin von dem Tutorial begeistert! hatte bereits mit Mi4uric3 kontakt und muss ihm da leider recht geben. Die M2 Sektion ist in vielen bereichen undankbar und versucht aus allem Geld zu machen.

Auf der anderen Seite muss man aber auch sehen, das es auch diese Leute gibt die durch solche Tutorials sachen lernen und ebenfalls für die Gemeinschaft einsetzen. Auch wenn der größteil es nicht verdient hat.

Ich würde mich sehr freuen wenn du diese Reihe fortführen würdest und wäre auch bereit für dies wenn nötig zu zahlen. Den es ist nicht selbstverständlich sein wissen Kostenlos mit anderen zu teilen!

Macht weiter so und lass dich nicht runter machen @.Verkauf´

##
Was vielleicht interessant wäre, wäre ein Tutorial wie man die Move Funktion ohne Strings findet. also nur über die Adressen (X/Z(Y)) und diese dann auch aufruft/benutzt.

Mit freundlichen Grüßen
Benhero
Benhero is offline  
Thanks
1 User
Old 09/05/2016, 14:00   #12
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
Danke für dein Feedback Benhero

Ich habe derzeit noch 2 andere Projekte am Laufen die ich gerne erst fertig machen möchte, darunter ein Packet-Reader der bereits fast fertig ist(liest Pakete die gesendet und Empfangen werden vom Client/Server im Klartext). Dieser funktioniert auf WOM2, SG, und offiziellen gameforge-Servern.
Damit ist es sehr leicht möglich zu sehen, welche pakete für welchen Anlass gesendet werden.
Ebenfalls wird die Adresse von der das paket gesendet wird(die Send() Funktion gecalled wird) mitgeliefert, sodass man sehr easy herausfindet, welche Funktion dafür zuständig ist.




Weitere Tutorials folgen wenn ich wieder zeit habe ich denke mit der Move-Funktion meinst du die MoveToDest().
Das Tutorial für die MoveFunktion würde allerdings einen größeren Umfang haben, da für das Movement ebenfalls Koordinaten gebraucht werden, die ja auch irgendwo herkommen müssen(Mob-pointer).


Wenn noch mehr Ideen und Wünsche da sind, dann bitte gerne äußern

Mfg
.Verkauf´ is offline  
Thanks
2 Users
Old 09/05/2016, 15:09   #13

 
elite*gold: 457
Join Date: Mar 2008
Posts: 2,540
Received Thanks: 1,596
Ich habe da viele Ideen

- Öffnen des Lagers ohne eingabe des Passworts (also Automatische Eingabe über ASM)
- Ansprechen von NPCs ohne diese anklicken zu müssen
- Abbauen von Erzen / Fischen + erkennen und rausziehen
- Erkennen der Monster in deiner Umgebung + Liste anlegen (ala MobFilter Funktion)
- Erkennen der Items auf dem Boden + Ihrer Position + aufheben (mit und oder ohne hinlaufen)
- Ghostmod (hoffe ist bekannt ^^)
- Verbessern von Items (Ohne beim schmied zu sein)
- Erkennen von Spielern in der Umgebung + Liste anlegen
- Erkennen von Teammitgliedern in der Umgebung (Un-/Sichtbar)
- Erkennen der Items im Inventar + Liste anlegen (in Verbindung mit Item use + Leben Adress für Auto Botter. Ggf. alles über ASM regelbar?)
- Benutzen von Skills
- Moblock (SendAttackPacket? + mobfilter s.o. + bogifilter (d.h. bogis werden nicht gepullt und wenn werden Sie bei alten Moblocks an den Spieler "gebunden" so das sie bei der nächsten Fertigkeit sterben ))
- Automatisches erkennen der Umgebung (Wasser, Normale Gehfläche, Unbegehbare fläche (Berge, Schluchten, ggf. Objekte)) + Wayfinder?
- Wallhack entweder über ASM oder über die SkipColison methode (Gab es mal ein video Tutorial von Mi4uric3 <3)

Wichtig wäre es vielleicht, das die Tutorials nicht nur auf M2 bezogen sind. Diese zwar auf M2 angewandt werden, aber die Technik ebenso auf andere Spiele übertragbar ist, online wie offline games :3

Wenn noch mehr Ideen gewünscht, werde ich mir gerne weiter den Kopf zerbrechen :3


Mit freundlichen Grüßen
Benhero
Benhero is offline  
Old 09/05/2016, 15:55   #14
 
elite*gold: 5
Join Date: Dec 2011
Posts: 1,079
Received Thanks: 616
haha, du gibst mir ja arbeit für das ganze jahr

ja, im Grunde alles machbar, hab auch das meiste schon selbst praktiziert, also kein problem ^^

Danke, werde das beim nächsten mal berücksichtigen
.Verkauf´ is offline  
Thanks
2 Users
Old 09/15/2016, 14:49   #15

 
elite*gold: 457
Join Date: Mar 2008
Posts: 2,540
Received Thanks: 1,596
Gibt es schon neuigkeiten? :P

Auch zu deinen Aktuellen Projekten?

Vielleicht kann man sich ja über Skype unterhalten :3 und evtl. kann ich dich mit ein paar "Kleinen" fragen löchern Würde mich jedenfalls Tierisch darüber freuen!

Grüße Ben


Benhero is offline  
Thanks
1 User
Reply



« M2Bob - Erklärung aller Funktionen | FREE WARRİOR İNTRO »

Similar Threads
Bit-Operatoren Reversen
Hallo EPVP, Ich brauchte mal eure hilfe bei einem Kleinen Problem. Und zwar bräuchte ich für (0x7f-($color>>25)<<24)|($color&0xffffff) den...
2 Replies - General Coding
Verschlüsselung reversen?
Hi, ich würde gerne wissen wie man am besten an eine Packetverschlüsselung rangeht um diese zu reversen. Ich weiß, dass die von Nostale z.B. nicht...
10 Replies - General Coding
Mit Olly reversen und in C++ Hooken
Guten Tag Gemeinde ;) Ich hoffe der Titel is einigermaßen io, mir is einfach nichts besseres eingefallen ^^ Wie ich ja schon in einem anderen...
22 Replies - C/C++
Reversen? Wie finde ich Values?
Hi Leute, Ich weiß, dass jetzt viel geflame kommen wird, aber: Wie finde ich die S4 Values? Wenn ich die nicht habe, kann ich ja nichts hacken....
6 Replies - S4 League



All times are GMT +2. The time now is 11:52.


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Abuse
Copyright ©2018 elitepvpers All Rights Reserved.