klassen methode hooking problem

12/22/2015 17:34 Slade100#1
hey leute,
ich versuche gerade einen eine klassen methode an eine adresse zu hooken, aber der compiler lässt den PBYTE cast auf die klassen methoden nicht zu :S
hier der code:
Code:
void packet::HookIt(){

	PacketRecv = (int(__stdcall *)(SOCKET, char *, int, int))DetourFunction((PBYTE)(RecvAddr), (PBYTE)MyPacketRecv);//der fehler bei Mypacketrecv
	PacketSendHook = (int(__stdcall *)(BYTE, LPCSTR, ...))DetourFunction((PBYTE)PacketSendHookOffset2, (PBYTE)MyPacketSendHook);//der fehler bei Mypacketsendhook
}
da diese beiden methoden auf die klassen attribute und methoden zugreifen kann ich die nicht staatisch machen, es sei denn ich mache die ganzen sachen global, aber dann wirds hässlig^^
gibt es irgendeine lösung wie ich diesen cast und somit den hook hinkriegen kann? :D
Viele grüße,
Slade
12/22/2015 17:53 Jeoni#2
Geht so nicht. Schon alleine wegen der Signatur bzw. Calling Convention. Deine nicht-statischen Memberfunktionen sind thiscalls, die in ecx den thisptr erwarten (über den sie dann auf Datenmember oder virtuelle Funktionen zugreifen). Die Funktion, die send / recv aufruft, ruft die Funktion allerdings als stdcall auf, wobei ecx ("this") unspezifiziert bleibt. Du brauchst eine Art Zwischenfunktion, die entweder eine statische Klassenfunktion ist oder halt zu keiner Klasse gehört und welche dann als Hookfunktion agiert und MyPacketRecv / MyPacketSendHook aufruft (das Objekt müsste es dann durch irgendeine globale / statische Variable bekommen).
Eventuell könnte man auch mit std::bind etwas machen, aber da liegen die Implementationsdetails nicht vor und sind nicht standardisiert.
Mit freundlichen Grüßen
Jeoni
12/22/2015 20:43 Slade100#3
wow danke dir :D durch deine antworten lerne ich wirklich immer was dazu :)
12/23/2015 18:19 Logtetsch#4
Quote:
Originally Posted by Slade100 View Post
da diese beiden methoden auf die klassen attribute und methoden zugreifen kann ich die nicht staatisch machen, es sei denn ich mache die ganzen sachen global, aber dann wirds hässlig^^
Slade
Du kannst auch einfach die Methoden als Statische deklarieren und die entsprechende Instanz als Parameter übergeben.

Code:
class MyClass {
private:
     bool attribute_1;
     bool attribute_2;

public:
     static void __stdcall doSomething(MyClass& obj, ...){
          obj.attribute_1 = true;
          obj.attribute_2 = true;
     }
};
12/23/2015 22:16 Jeoni#5
Quote:
Originally Posted by Logtetsch View Post
Du kannst auch einfach die Methoden als Statische deklarieren und die entsprechende Instanz als Parameter übergeben.

Code:
class MyClass {
private:
     bool attribute_1;
     bool attribute_2;

public:
     static void __stdcall doSomething(MyClass& obj, ...){
          obj.attribute_1 = true;
          obj.attribute_2 = true;
     }
};
Ergibt im Kontext wenig Sinn, weil die Funktion, die gebraucht wird, ja eine Hookfunktion ist. Entsprechend muss sie die gleiche Signatur haben, wie die Original-Funktion (hier halt send / recv). Immerhin wird die Funktion ja von externen Stellen (bei Gamehacks irgendwelche spielinternen Routinen) aufgerufen und die übergeben mit Sicherheit nicht einfach auf einmal die Objektreferenz, die man da gerne hätte, sondern halten sich halt an die Signatur von recv / send. Gleiches gilt auch für Callbackfunktionen.
Wenn man die Funktion nur selber aufrufen würde, bräuchte man den Workaround auch wieder nicht, weil man dann an der aufrufenden Stelle genauso einen thiscall vom Objekt aufrufen könnte.
Als Lösung könnte man mit std::bind arbeiten um bei einer solchen Funktion dann das erste Argument fest zu binden. Aber dann müsste man an den Funktionspointer vom std::bind-Ergebnis rankommen (was aufgrund der fehlenden standardisierung schon echt doof ist) und wenn das ginge, könnte man auch direkt eine thiscall-Funktion mit dem entsprechenden Objekt binden.
Mit freundlichen Grüßen
Jeoni
12/23/2015 22:19 Slade100#6
erstmal danke für die antwort logtetsch, nur ist das problem das diese funktion die funktion ja von ausserhalb aufgerufen wird und bestimmte parameter erwartet und das obj eh nicht kriegt, naja habe die funktion gestern einfach aus der klasse raus genommen und das objekt global gemacht, die normalen errors waren zwar raus aber da sind irgendwelche lnk 2005 errors aufgekommen xD
muss mal schauen woher die kommen^^
12/23/2015 23:41 Logtetsch#7
Ärgerlich, habe mir leider nicht alles durchgelesen! Verstehe leider immer noch nicht ganz das Problem. Was soll die Klasse denn darstellen? Generierst du zur Laufzeit mehrere Instanzen?
12/23/2015 23:58 Slade100#8
eigentlich nicht xD die klasse dient einfach dazu das es übersichtlich bleibt.Das probelm habe ich aber wie gesagt schon gelöst, naja habe mittlerweile eh ein anderes problem, und zwar habe habe ich ein paar funktionen,welche von verschiedenen klassen und der main benötigt werden, habe diese in eine main.h gesteckt und dann main.h in den klassen included, naja mein problem ist das der compiler meckert(include guard ist drin) z.B.
1>packet.obj : error LNK2005: "void __cdecl SwitchOnOff(bool &)" (?SwitchOnOff@@YAXAA_N@Z) ist bereits in main.obj definiert.
iwas stimmt da doch nicht xD wieso sollte ich die selbe funtkion nicht in 2 verschiedenen cpp dateien benutzen können.
12/24/2015 01:35 Logtetsch#9
Liegt dadran, dass du die Funktion mehrfach definierst. Und das liegt wiederum dadran, dass du die Funktion in der main.h definierst, statt zu deklarieren. Das Definieren von Funktionen in Headerdateien würde ich dir streng abraten. Im Notfall kannst du die Funktion auch als inline definieren (Nur unter der Bedingung, dass die Funktion nicht mehr als 10 Zeilen auffasst).

Mit der Deklaration machst du dem Compiler klar, dass es diese Funktion gibt, jedoch nicht, wo die Funktion definiert wird bzw. was diese Funktion eigentlich macht.


Deklaration in der main.h
Code:
void __cdecl SwitchOnOff(bool&);
Definition in der main.cpp
Code:
void __cdecl SwitchOnOff(bool& value)
{ .... }
12/24/2015 03:13 Slade100#10
danke dir vielmals für die hilfe :)