[METIN2]OllyDbg-Fragen

08/21/2010 17:07 Padmak#1
Hallo Leutchens,

und zwar habe ich mehrere Fragen zu OllyDbg in Verbindung mit Metin2 und C++
Also:
Erste Frage:
Ich will an die PickUp-Funktion rankommen, sie ist auch nicht schwer zu finden (denke ich)
Olly zeigt mir das hier an:

Code:
MOV ECX,DWORD PTR SS:[EBP+8]
PUSH ECX
MOV ECX,DWORD PTR DS:[5F1D34] 
CALL XXXXXXX.0041DFC0
Alle anderen Funktionen kann ich so aufrufen, aber nur weil das in den eckigen Klammern statisch ist
Hier hab ich allerdings EBP+8... wenn ich es so injecte stürzt entweder Metin ab oder es passiert nichts
Kann mir wer sagen wie ich das verwenden muss?

Das leitet gleich zur zweiten Frage über:
Ich such auf nem Privatserver (Also mit einer alten Exe) und da gibts ja die ganzen Namen wie z.b. "SendItemPickUpPacket Error"
Aber das kann doch unmöglich die einzige Möglichkeit sein, an die Funktionen zu kommen oder?
Ich würd ja gerne mal die Schlag-Funktion finden oder ähnliches, aber wie kann ich Hotkeys verfolgen?

Ich weiß nicht wie ich das machen soll
Vllt kennt auch jemand ein gutes Tut wo sowas angesprochen wird
Ich hab bis jetzt 2 Olly-Tuts hier durchgemacht (Chatfunktionen finden von schlurmann und itemuse-adressen finden von xWaffeleisen glaub ich)
Weiß jemand noch Ergänzungen? Am liebsten direkt für Metin

Schonmal danke von

Padmak
08/22/2010 07:55 tim66613#2
Quote:
Originally Posted by Padmak View Post
Alle anderen Funktionen kann ich so aufrufen, aber nur weil das in den eckigen Klammern statisch ist
Hier hab ich allerdings EBP+8... wenn ich es so injecte stürzt entweder Metin ab oder es passiert nichts
Kann mir wer sagen wie ich das verwenden muss?
Also, die Funktion ist __thiscall. Wenn du sie aus deinem Code (ich gehe mal von C/C++ aus) heraus aufrufen willst, musst du den Klasseninstanz-Ptr ins ECX Register kopieren.

Intel:
Code:
const void* classPtr = *(const void **)0x5F1D34; // <-- Zeigt auf den eigentlichen Klasseninstanz-Ptr
__asm mov ecx, [classPtr]
AT&T
Code:
const void* classPtr = *(const void **)0x5F1D34; // <-- Zeigt auf den eigentlichen Klasseninstanz-Ptr
asm("movl %0, %%ecx" : : "m" (classPtr));
Nun zu dem
Code:
PUSH EBP+8
Hier wird ein Argument für die eigentliche PickUp-Funktion auf den Stack gepusht.
Wenn du dich mal genauer mit dem Stack beschäftigst wirst du herausfinden das EBP+8 hier ein Argument der Funktion ist, aus der du den Asm-Code kopiert hast.

Beispielimplementation "PickUp" Funktion:
Code:
void PickUp(unsigned long itemID)
{
	char (__stdcall* FPickUp)(unsigned long itemID) = (char (__stdcall*)(unsigned long))0x41DFC0;
	const void* classPtr = *(const void **)0x5F1D34;

	__asm mov ecx, [classPtr]

	FPickUp(itemID);
}
Quote:
Originally Posted by Padmak View Post
Das leitet gleich zur zweiten Frage über:
Ich such auf nem Privatserver (Also mit einer alten Exe) und da gibts ja die ganzen Namen wie z.b. "SendItemPickUpPacket Error"
Aber das kann doch unmöglich die einzige Möglichkeit sein, an die Funktionen zu kommen oder?
Ich würd ja gerne mal die Schlag-Funktion finden oder ähnliches, aber wie kann ich Hotkeys verfolgen?
Tastendrücke landen immer in der Python-Klasse "Game", wo dann die jeweiligen API-Funktionen gecallt werden.
Für die Schlag-Api kann ich dir "player.ComboAttack" und "player.SetAttackKeyState" empfehlen.

Kind Regards Tim
08/22/2010 12:57 Padmak#3
Oookay
Ich versteh was hier passiert, aber ich weiß nicht was FPickUp dann ist
Code:
void PickUp(unsigned long itemID)
{
	char (__stdcall* FPickUp)(unsigned long itemID) = (char (__stdcall*)(unsigned long))0x41DFC0;
	const void* classPtr = *(const void **)0x5F1D34;

	__asm mov ecx, [classPtr]

	FPickUp(itemID);
}
Und iwie habe ich glaub ich die falsche PickUp-Funktion
Jedes mal wenn ich was aufheb, ist der Parameter anders
Also ist es iwie keine Item-ID
Hier mal mein kompletter Code (wahrscheinlich total dämlich zusammengemixt^^)
Code:
DWORD dwPickFunc = 0x004C6C70;
void PickUp(unsigned long itemID)
{
	char (__stdcall* FPickUp)(unsigned long itemID) = (char (__stdcall*)(unsigned long))0x41DFC0;
	const void* classPtr = *(const void **)0x5F1D34;

	__asm mov ecx, [classPtr]

	FPickUp(itemID);
}
void FPickUp(unsigned long itemID)
{
	__asm
	{
	PUSH ECX
	CALL dwPickFunc
	}
}
Passt das? Bzw ich weiß dass es NICHT passt, Metin stürzt immer ab^^

Das mit dem Schlagen probier ich aus, danke

Padmak

Edit:
Okay.. das mit dem Schlagen krieg ich auch nich hin :D
Wie finde ich diese ominöse Game-Klasse?

Edit2:
Ich hab nen neuen Versuch gestartet, es stürzt nicht mehr ab, es passiert nur nix :D
Code:
void PickUp(unsigned long itemID)
{
	char (__stdcall* FPickUp)(unsigned long itemID) = (char (__stdcall*)(unsigned long))0x41DFC0;
	const void* classPtr = *(const void **)0x5F1D34;
	__asm
	{
	MOV ECX,DWORD PTR SS:[EBP+8]
	PUSH 19
	mov ecx, [classPtr]
	CALL dwPickFunc
	}
}
Ich weiß nicht was ich bei PUSH hinschreiben soll... bei ECX passiert nix, und egal welche zahl ich einfüge, passiert auch nix-.-

Nochmal Edit, kurze Ergänzung zum 2. Edit:
Ich hab mal ne Yangbombe gedroppt und die ganzen ECX-Werte aufgeschrieben...
Einfach ansehen^^ (DEC-Wert hab ich umgewandelt für mich, damit ich die zahlen leicher erkenn)
Code:
HEX-WERT:          DEC-WERT
ECX=00364C10      3558416
ECX=00364C12      3558418
ECX=00364C0E      3558414
ECX=00364C0C      3558412
ECX=00364C14      3558420
ECX=00364C0D      3558413
... hä?^^
08/22/2010 14:49 tim66613#4
Quote:
Originally Posted by Padmak View Post
Oookay
Ich versteh was hier passiert, aber ich weiß nicht was FPickUp dann ist
Code:
void PickUp(unsigned long itemID)
{
	char (__stdcall* FPickUp)(unsigned long itemID) = (char (__stdcall*)(unsigned long))0x41DFC0;
	const void* classPtr = *(const void **)0x5F1D34;

	__asm mov ecx, [classPtr]

	FPickUp(itemID);
}
Und iwie habe ich glaub ich die falsche PickUp-Funktion
Jedes mal wenn ich was aufheb, ist der Parameter anders
Also ist es iwie keine Item-ID
Hier mal mein kompletter Code (wahrscheinlich total dämlich zusammengemixt^^)
FPickUp ist die Adresse der PickUp-Funktion im Client.
Du brauchst da keine Funktion mehr definieren.

Und ja, es ist die eindeutige ID des Items.
Der Code den ich oben gepostet habe, sollte eigentlich funktionieren, solang du ihn mit einer validen ItemID aufrufst.

Quote:
Originally Posted by Padmak View Post
Passt das? Bzw ich weiß dass es NICHT passt, Metin stürzt immer ab^^

Das mit dem Schlagen probier ich aus, danke

Padmak

Edit:
Okay.. das mit dem Schlagen krieg ich auch nich hin :D
Wie finde ich diese ominöse Game-Klasse?
Die Game Klasse liegt in der Game.py, welche sich wiederum in der root.epk befindet.
Die root.epk muss aber vorher entpackt werden. (Tools gibt es zwei, einfach im Board suchen).

Quote:
Originally Posted by Padmak View Post
Ich weiß nicht was ich bei PUSH hinschreiben soll... bei ECX passiert nix, und egal welche zahl ich einfüge, passiert auch nix-.-
Du musst nirgends PUSH oder CALL verwenden, das macht der Compiler für dich, wenn du den Funktionspointer "FPickUp" aufrufst.

Um es ganz simpel zu erklären "FPickUp" ist das selbe wie dein "dwPickFunc".
Am besten du ließt ein Buch über die Grundlagen von C/C++, sowie über Reverse Engineering.

Kind Regards Tim
08/22/2010 15:04 Padmak#5
Neuester Edit:

Ich hab jetzt eigentlich alles
Ich hab allerdings nur noch ein Problem:
Wenn ich diese Dll injecte geht es einwandfrei:
(Pickup)
Code:
#include <windows.h>

DWORD Pick1 = 0x00000000;
DWORD Pick2 = 0x00000000;

void PickUp()
{
	__asm
	{
	MOV ECX,DWORD PTR DS:[0x000000]
	CALL Pick1
	JMP Pick2
	}
}
int __stdcall DllMain(_In_ void * _HDllHandle, _In_ unsigned _Reason, _In_opt_ void * Reserved)
{
	if(DLL_PROCESS_ATTACH == _Reason)
	{
		PickUp();
	return 1;
	}
}
Wenn ich es so mache
Code:
#include <windows.h>

DWORD Pick1 = 0x0043C850;
DWORD Pick2 = 0x0053BFA0;

void HackThread()
{
	__asm
	{
	MOV ECX,DWORD PTR DS:[0x5EF738]
	CALL Pick1
	JMP Pick2
	}
	Sleep(500);
}

int __stdcall DllMain(_In_ void * _HDllHandle, _In_ unsigned _Reason, _In_opt_ void * Reserved)
{
	if(DLL_PROCESS_ATTACH == _Reason)
	{
	CreateThread(0, 0, (LPTHREAD_START_ROUTINE)HackThread , 0, 0, 0);
	return 1;
	}
}
kackt Metin ab :(
Warum?

Padmak
08/24/2010 16:28 Padmak#6
Sorry für den Doppelpost, aber ich hab immer noch keine Lösung...
Weiß das einer?

Padmak
08/26/2010 06:40 meak1#7
metin kommt nich so mit threads klar =/?
08/26/2010 11:22 Padmak#8
Ist das eine Antwort oder eine Frage?
Ich muss es doch in einem neuen Thread laufen lassen? Sonst hängt das ganze Spiel sobald ich da eine Schleife einbau
Gibts auch eine Alternative zu Threads? Also dass sich Metin nicht aufhängt?

Padmak
08/26/2010 23:59 MrSm!th#9
1. Threads haben den Typ DWORD WINAPI und nicht void
2. du musst eine while Schleife machen, wenn etwas die ganze Zeit passieren soll (die Tatsache, dass du nen Thread machst und dass du Sleep(500) schreibst, deutet darauf hin, dass du es immer wieder geschehen lassen willst)
3. return 1 oder TRUE gehört außerhalb von dem if Block, da immer TRUE zurückgegeben werden muss, wenn kein Fehler auftritt. Man man, du solltest dir echt mal was darüber anlesen o.ô
4. ich weiß ja nicht, ob die calling convention dieser Pickup Funktion WINAPI ist, aber falls nicht, musst du nach dem Call noch den Stack aufräumen.
08/27/2010 11:28 Padmak#10
Es stürzt aber immer noch ab-.-
In Olly kommt danach direkt eine Funktion, die damit aber nichts zu tun hat
Wo soll ich denn den Stack aufräumen bzw wie?

Padmak
08/28/2010 13:21 mydoom#11
Ich zitiere einmal das (meiner Meinung nach sehr hilfreiche) Wikibook "[Only registered and activated users can see links. Click Here To Register...]":

Quote:
The Standard Exit Sequence must undo the things that the Standard Entry Sequence does. To this effect, the Standard Exit Sequence must perform the following tasks, in the following order:

- Remove space for local variables, by reverting esp to its old value.
- Restore the old value of ebp to its old value, which is on top of the stack.
- Return to the calling function with a ret command.
(findet man [Only registered and activated users can see links. Click Here To Register...])

Sieht sehr nach [Only registered and activated users can see links. Click Here To Register...] aus, deshalb macht das dann nicht die aufgerufene Funktion, sondern eben die aufrufende Funktion.
08/28/2010 22:05 MrSm!th#12
Quote:
Originally Posted by mydoom View Post
Ich zitiere einmal das (meiner Meinung nach sehr hilfreiche) Wikibook "[Only registered and activated users can see links. Click Here To Register...]":


(findet man [Only registered and activated users can see links. Click Here To Register...])

Sieht sehr nach [Only registered and activated users can see links. Click Here To Register...] aus, deshalb macht das dann nicht die aufgerufene Funktion, sondern eben die aufrufende Funktion.
Das was du da beschrieben hast gilt für __stdcall, was ja sowieso beim return den Stack aufräumt.
Ich sprach von __cdecl, da muss der Teil, der die Funktion gecalled hat, durch Erhöhen des ESP Wertes zum Urpsprungswert, bevor die Parameter gepusht wurden, den Stack aufräumen.
08/28/2010 23:39 mydoom#13
Ja das meinte ich im endeffekt auch. Heute ist nicht mein Tag ;D
08/29/2010 22:36 Padmak#14
Genau... redhomie2
Du sagst es xD
omg-.-

@Die anderen 2...
Warum funktioniert es bei ALLEN anderen funktionen? Nur bei dieser nicht?

Padmak
08/30/2010 00:53 MrSm!th#15
Warum steppst du nicht einfach im Debugger durch und testest, was falsch läuft?