Wie schon in anderem Thread geschrieben will ich ein Tutorial machen, wie man einen "echten" Multiclient macht und ein Tool releasen welches den Clienten nicht patcht, sondern den Mutex von Nostale killt. (Das alternative Tool)
=================================================
Inhaltsangabe:
- Voraussetzungen & Programme
- Ein kurzer Blick in die Theorie.
- Wie patche ich den Nostale Client richtig um einen Multiclient zu machen?
- Ein alternatives Tool, um den Clienten nicht patchen zu müssen.
Voraussetzungen & Programme:
- Grundlegende Erfahrung im Umgang mit Debuggern
- Grundlegende ASM Kenntnisse
- OllyDBG
- C/C++ Kentnisse (für den Multiclient starter)
Theorie:
Um einen Multiclient erstellen zu können, müssen wir wissen, welche Windows Funktionen die Limitierung setzen. Diese sind: CreateMutex(), CreateProcess()
MSDN - CreateMutex:
Je nach Zeichensatz(ANSI oder UNICODE) kann die Funktion, CreateMutexA oder CreateMutexW heißen.Quote:
HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCTSTR lpName
);
Es ist zu beachten dass die CreateProcess Funktion nicht immer vorhanden sein muss. Sie kann auch fehlen
MSDN - CreateProcess:
Was das wichtigste bei den 2 Funktionen ist das: BOOL bInitialOwner / BOOL bInheritHandles.Quote:
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
Auszüge MSDN:
Quote:
Originally Posted by BOOL bInitialOwnerIf this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section.
Das heißt wir müssen aufpassen, dass jeweils diese 2 Variablen auf FALSE bleiben.Quote:
Originally Posted by BOOL bInheritHandlesIf this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.
Wie beendet man den Mutex eines Prozesses?
Das beenden selbst ist einfach und das Zauberwort für dies heißt: DuplicateHandle()
MSDN-Auszug:
MSDN:Quote:
BOOL WINAPI DuplicateHandle(
_In_ HANDLE hSourceProcessHandle,
_In_ HANDLE hSourceHandle,
_In_ HANDLE hTargetProcessHandle,
_Out_ LPHANDLE lpTargetHandle,
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwOptions
);
Man ruft einfach DuplicateHandle auf, aber mit der Angabe von DUPLICATE_CLOSE_SOURCE (0x1) im Options-Parameter.
Man kann bei Target Prozess Handle und Target Handle NULL angeben, wichtig sind Source Prozess Handle und Source Handle.
Bsp:
Code:
DuplicateHandle(handleToTheRemoteProcess, theRemoteHandle, NULL, NULL, 0, FALSE, 0x1);
Um an den Mutex zu kommen, müssen diese Windows NT-Funktionen verwendet werden: NtQuerySystemInformation, NtDuplicateObject, NtQueryObject
Dazu aber mehr, wenn genug Nachfrage deshalb besteht!
Das Patchen:
Genug Theorie, begeben wir uns aufs patchen von Nostale
Wir öffnen NostaleX.dat in OllyDBG.
Im CPU Fenster drücken wir die rechte Maustaste, gehen auf View und wählen NostaleX aus. Somit sind wir im Modul von NostaleX, da wir ja auch hier arbeiten wollen und nicht im ntdll Modul
Jetzt sehen wir ASM-Code von NostaleX. Jedoch ist dieser Code, wie man sieht nicht analysiert, also analysiren wir es! Wir drücken wieder die rechte Maustaste, gehen aber auf Analysis und dann auf Analys Code.
So, nachdem wir den analysirten Code haben, suchen wir nach unserer CreateMutex Funktion. Da NostaleX keine CreateProcess Funktion hat, müssen wir diese nicht suchen. Wieder: Rechte Maustaste ->Search for -> All intermodular calls
Jetzt sollte ein neues kleines Fenster erscheinen mit vielen Funktionen. Wir wollen es sortieren um die CreateMutex Funktion leichter zu finden, also gehen wir wie gefolgt vor: Rechte Maustaste -> Sort by -> destination
Nun suchen wir die CreateMutex Funktion.Wenn wir sie gefunden haben, machen wir einen Doppelklick darauf und wir sollten bei der CreateMutex Funktion sein. Der rot markierte Bereich im 2ten Bild welches nach diesem folgt ist wichtig!
Sooo. Was sehen wir im rot markierten Teil? Unsere Funktion! Und offentsichtlich wird da etwas geprüft verschoben, inkrementiert usw. Jetzt sind die Grundlegenden ASM kentnisse gefragt. Unser eax hat zurzeit den 0 Wert. aber beim
Code:
inc eax and eax,7F
Na ganz einfach, statt der and - Anweisung werden wir unseren gerade eben inkrementierten eax, wieder dekrementieren. Um dies zu machen, machen wir ein Doppelklick auf and eax,7F und schreiben unsere dekremtnierungs - Anweisung.
Code:
dec eax
Glückwunsch, wir haben CreateMutex erfolgreich gepatcht!
Was noch zu tuhen ist, weil die CreateMutex von einer Stelle aufgerufen wird (100% irgendwo beim Programm Entry Point), müssen wir einen Error-Handling überspringen. Um aber zum Entry Point des Programms zu gelangen, müssen wir einmal den Play-Button des Debuggers betätigen und er wird sofort dannach zum Entry Point des Programms springen.
Auf dem Bild ist eine Markierung zu sehen. Diese ist in diesem Fall wichtig.
JNZ = Jump if Not Zero
Dieser Jump wird jedesmal ausgeführt da wir die CreateMutex Funktion verändert haben. Wenn man sich mit dem Debugger spielt, kann man sehen wo man hinspringen wird. Also müssen wir wo anders springen. Wo springen wir? Wir springen vor dem Call, welcher den Splash-Screen des Spiels aufruft, weil ab da läuft das Programm "ohne Fehler" bzw. der Client wird nicht crashen etc.
Wie ich weiß welcher Call den Splash-Screen aufruft? Naja, man muss sich etwas tiefer mit dem beschäftigen. Aber ich habs Anfäger freundlich gemacht und so kann man alles in der folgenden screens erkennen
Unser patch ist ferig, yeah! Was wir noch machen müssen ist, die vorgenommenen Änderungen speichern. Dafür machen wir: Rechte Maustaste -> Copy to executeable -> All modifications
Man wird dann gefragt was man kopieren möchte, wir wählen Copy all.
Nun erscheint ein neues Fenster. In diesem wieder: Rechte Maustaste -> Save file
Die Datei speichern wir als NostaleX_Multiclient.dat
Nun. Jetzt schreiben wir einen kleinen Starter für den Multiclient und sind dann glücklich und zufireden :P
Ich habe die C++ Sprache für dies genommen, aber man kann welche man will nehmen, hauptsache wir starten den Clienten
Ich habe den Code kommentiert(/erklärt) damit ich hier nicht extra erkläre.
Nachdem ihr den Starter erstellt bzw. kompiliert habt, dann verschiebts ihr euren Starter in den Nostale Ordner und startet diesen als Admin! Nun, machts das wie oft ihr es wollt
Release und somit das alternative Tool um den Clienten nicht patchen zu müssen:
Vorerst: Den Source Code bzw. das Tutorial zu so einem Tool werde ich erst dann machen, wenn genug Nachfrage deshalb besteht.
Ausnhame: Mr.Tr33, kannst mir gerne eine PN schicken und wir reden dann darüber, da du wissen wolltest wie sowas funktioniert.
Das Tool wurde in C geschrieben und verwendet die NT - Funktionen. (von der ntdll.dll)
Was das Tool macht?
Es killt den Mutex von Nostale. Somit kannst du Nostale nochmals starten.
Wie verwende ich das Tool?
- Nostale MutexKiller.rar downloaded und entpacken.
- Nostale MutexKiller.exe starten. Entweder bevor man Nostale startet, oder nachdem Nostale gestartet ist, wie ihr wollts.
Ich hoffe das Tutorial zum Multiclient hat euch geholfen!
Ebenfalls hoffe ich, dass das Tool, anstatt den Multiclient zu patchen, auch gut ankommt!
Im Anhang findet ihr:
- Nostale Starter und den Source Code dazu.
- Nostale MutexKiller Tool
Greetz