hey, hier gibts leider keine asm section daher poste ich das mal hierhin
unzwar wollte ich eine funktion hooken, welche mir in ida mit folgenden übergabeparametern angezigt wird __stdcall sub(float, int, int, char, int, int, int), der hook ist getan(ist nicht das erstemal das ich eine function hooke,also habe den schon richtig gemacht ^^ ), aber ich vermute das die parameter nicht ganz stimmen(sofern das möglich ist), sobald ich irgendwas in meinen hook reinschreibe, sogar bei einem einfach printf("hallo") crasht mein game... also ist es möglich das ida pro mir da ein funtktion zeigt, die nicht der wahrheit entspricht?^^
Das liegt daran das ihr euch glaube nicht alle sicher seit was ihr da tut. Ein midfunction hook heißt das ihr in der Runtime des Programms seit sprich ihr dürft nicht denken das es euer Programm ist. Du must hutsam mit dem Stack umgehen da er dir ansonsten wegcrasht.In den midfunction hook sollte man auch sonst asm x86 fortführen, womit sich auch eig. so gut wie alles machen läst und wenn du wirklich vc++/c++ weiter nutzen möchtest musste die flags und den stack speichern und am ende des hooks wieder restoren.
Ich glaube nicht dass er von einem Midfunction-Hook spricht, sondern eher von einem normalen, am Anfang der Funktion.
Er hat schon recht, es kann sein dass IDA die falsche Funktionssignatur anzeigt, allerdings ist das nur der Fall wenn der Hook auch crasht wenn du in der Funktion nichts machst, außer zu returnen.
Kannst du mal deinen Code zeigen? Dann lässt sich einfacher helfen
Ich glaube nicht dass er von einem Midfunction-Hook spricht, sondern eher von einem normalen, am Anfang der Funktion.
Er hat schon recht, es kann sein dass IDA die falsche Funktionssignatur anzeigt, allerdings ist das nur der Fall wenn der Hook auch crasht wenn du in der Funktion nichts machst, außer zu returnen.
Kannst du mal deinen Code zeigen? Dann lässt sich einfacher helfen
Padmak
Kein Programm ist perfekt außer der Windows Movie Maker ° _°
Kein Programm ist perfekt außer der Windows Movie Maker ° _°
danke schonmal für die antworten. hier die meine funktion
Code:
DWORD func_add = 0x006439E0;
DWORD func_back = func_add + 0x06;
int(__stdcall *OnMapClick)(float, int, int, char, int, int, int);
int __declspec(naked) myfunction(float floatA, int intA, int intB, char charA, int intC,int intD, int intE){
__asm
{
push ebp // func_add, wenn der hook noch nicht gesetzt ist
mov ebp, esp
sub esp, 48h
}
printf("hey");//das hier alleine verursacht schon den crash :S
__asm {jmp func_back}
}
also in der main schreibe ich an der func_add ein jmp zu meiner function, dann kommt der asm teil der aus der funktion rausgeschrieben ist und dann kommen meine funktionen und dann der jmp back.
die funktion hat aufjedenfall etwas mit dem clicken in einem game zutun, die wird immer aufgerufen wenn ich iwo hinclicke um hinzulaufen.
crashen tut es nur wenn ich nicht auf den boden clicke, also wenn ich auf ein anderen player/npc/monster klicke dann crasht es :S wenn ich auf normalen boden clicke um hinzulaufen, dann läufts perfekt, echt komig
hier der ida auszug
was ich hier komig fand, war das die funktion 7 args oben hat, aber unten im stack iwie nur 6 sind, aber ich bin gerade noch in der anfangsphase bei asm, daher versteh ich solche funktionen auch leider immer nur bis zu einem gewissen teil, :S
Urgh.
Bevor du printf aufrufst, solltest du noch pushad und popad machen (vllt auch pushfd und popfd, ich mache immer beides und bin zu faul nachzusehen.)
Wieso machst du das aber von Hand? Nimm dir lieber Microsoft Detours, oder MologieDetours, damit sparst du dir das ganze naked Assembler zeugs.
Außerdem ist __declspec(naked) *nicht* das gleiche wie __stdcall, da ist vermutlich dein Crash zu finden
Das ganze ist KEIN stdcall, sondern ein thiscall. Dies kann man recht gut an 0x006439E6 sehen, wo ecx (this) gelesen wird, ohne dass es in der Funktion vorher gesetzt wird.
Dein Hook selbst ist korrekt, wenn auch, wie Padmak schon sagte, mit dem inline asm irgendwie unnötig. Aber wenn du am Ende unbedingt springen willst, meinetwegen.
Ob die Hookfunktion an der Stelle stdcall ist oder nicht, ist extrem egal, da die Funktion eh kein return (ret XX) beinhaltet, sondern lediglich einen unbedingten Sprung zurück.
Das fehlende Sichern der Register ist das, was hier vermutlich für den Crash sorgt. Insbesondere ecx wird während dem printf aller Wahrscheinlichkeit nach verändert (da Caller-Saved) ohne wiederhergestellt zu werden. Dadurch kann die Originalfunktion nach dem Rücksprung nicht richtig arbeiten, weil ihr this (ecx) irgendein Müll ist. Alle anderen Register werden entweder von printf wieder korrekt hergestellt (Callee-Saved Register) oder sind nicht zu sichern, weil der Hook eh am Anfang der Funktion ist und noch keine Caller-Saved Register von der Originalfunktion verwendet wurden. Ein Sichern des Flagregisters wird auch nicht nötig sein.
Mein Vorschlag also:
Code:
int __declspec(noreturn) __declspec(naked) __fastcall myfunction(void* thisptr, void* _edx, float floatA, int intA, int intB, char charA, int intC,int intD, int intE){
__asm
{
push ebp // func_add, wenn der hook noch nicht gesetzt ist
mov ebp, esp
sub esp, 48h
push ecx
}
printf("hey");
__asm pop ecx;
__asm jmp func_back;
}
Durch das Deklarieren der Funktion als Fastcall, werden die ersten beiden Argumente in ecx und edx erwartet. Dadurch kriegst du das this (hier thisptr) der Funktion mit.
Trotzdem kein Fan von der inline asm Variante, wenn es nicht sein muss (und hier muss es nicht sein).
Abgesehen davon, speichere BITTE Pointer NICHT in DWORDs. Welcher Trottel ist bitte auf solchen Mist gekommen und warum kopiert das quasi jeder? Nicht einmal in der WinAPI werden irgendwo Pointer als DWORD übergeben. Ein DWORD ist eine 32 bit lange Ganzzahl ohne Vorzeichen. Sobald du solchen Code auf 64 bit ausführst, hast du 32 bit zu wenig. Sehe dauernd irgendwelche ... naja, Programmierer, die sich dann wundern, warum ihr toller Code auf 64 bit gar nicht funktioniert. Davon abgesehen impliziert ein DWORD auch irgendwie keinen Pointer. Wie man also auf derartigen Unfug kommen kann, ist mir irgendwie immernoch rätselhaft.
Mit freundlichen Grüßen
Jeoni
Kurzer Einwurf für MSVC (wovon ich nach dem ASM-Syntax ausgehe
Man braucht diesen __fastcall-Hack nicht, man kann sich mit einem anderen Hack behelfen (ich hoffe der Syntax passt so, bin bisschen zu faul zum Testen gerade):
Ich finde, dass die Funktion dadurch wesentlich schöner ist, weil man keine "unnützen" Parameter hat und noch dazu keine Probleme mit this hat.
Funktioniert so aber nur unter MSVC, woanders habe ich das noch nicht zum Laufen bringen können.
POPAD/POPFD hab ich vorgeschlagen, weil er im Endeffekt in seiner Funktion wesentlich mehr machen möchte als nur ein einfaches printf, wenn er jetzt nach deiner Erklärung nur ECX sichert, schmiert es ihm dann später ab, wenn er irgendeine seiner eigenen Funktionen benutzt. (Oder Stack-Variablen einführt, was ihm ESP zerschießen dürfte, oder? Kann das jemand verifizieren/widerlegen?)
Dein Hook selbst ist korrekt, wenn auch, wie Padmak schon sagte, mit dem inline asm irgendwie unnötig. Aber wenn du am Ende unbedingt springen willst, meinetwegen.
Ob die Hookfunktion an der Stelle stdcall ist oder nicht, ist extrem egal, da die Funktion eh kein return (ret XX) beinhaltet, sondern lediglich einen unbedingten Sprung zurück.
Das fehlende Sichern der Register ist das, was hier vermutlich für den Crash sorgt. Insbesondere ecx wird während dem printf aller Wahrscheinlichkeit nach verändert (da Caller-Saved) ohne wiederhergestellt zu werden. Dadurch kann die Originalfunktion nach dem Rücksprung nicht richtig arbeiten, weil ihr this (ecx) irgendein Müll ist. Alle anderen Register werden entweder von printf wieder korrekt hergestellt (Callee-Saved Register) oder sind nicht zu sichern, weil der Hook eh am Anfang der Funktion ist und noch keine Caller-Saved Register von der Originalfunktion verwendet wurden. Ein Sichern des Flagregisters wird auch nicht nötig sein.
Mein Vorschlag also:
Code:
int __declspec(noreturn) __declspec(naked) __fastcall myfunction(void* thisptr, void* _edx, float floatA, int intA, int intB, char charA, int intC,int intD, int intE){
__asm
{
push ebp // func_add, wenn der hook noch nicht gesetzt ist
mov ebp, esp
sub esp, 48h
push ecx
}
printf("hey");
__asm pop ecx;
__asm jmp func_back;
}
Durch das Deklarieren der Funktion als Fastcall, werden die ersten beiden Argumente in ecx und edx erwartet. Dadurch kriegst du das this (hier thisptr) der Funktion mit.
Trotzdem kein Fan von der inline asm Variante, wenn es nicht sein muss (und hier muss es nicht sein).
Abgesehen davon, speichere BITTE Pointer NICHT in DWORDs. Welcher Trottel ist bitte auf solchen Mist gekommen und warum kopiert das quasi jeder? Nicht einmal in der WinAPI werden irgendwo Pointer als DWORD übergeben. Ein DWORD ist eine 32 bit lange Ganzzahl ohne Vorzeichen. Sobald du solchen Code auf 64 bit ausführst, hast du 32 bit zu wenig. Sehe dauernd irgendwelche ... naja, Programmierer, die sich dann wundern, warum ihr toller Code auf 64 bit gar nicht funktioniert. Davon abgesehen impliziert ein DWORD auch irgendwie keinen Pointer. Wie man also auf derartigen Unfug kommen kann, ist mir irgendwie immernoch rätselhaft.
Mit freundlichen Grüßen
Jeoni
danke dir sehr für die Antwort , und schon hat man wieder was gelernt
eine frage hätte ich jedoch noch unzwar, wie sieht das aufrufen so einer funktion in der eigenen main aus? also ich habe gesehn das die adresse vom thisptr, das selbe ist wie die value vom intA, nun hatte ich versucht die funktion zu callen, erstmal so
naja iwie hat mein (void*)intA 0 einfluss den thisptr in der function
Code:
printf("ecx(this) = %p\n", thisptr);/* kommt immer was komplett anderes raus, als das wie ich es aufrufen will, auch wenn ich für intA 0 habe steht da was anderes*/
daher dachte ich mir ich ändere ecx halt in meinem asm code.
dann hab ichs so versucht
Code:
int __declspec(noreturn) __declspec(naked) __fastcall MyOnMapClick(void* thisptr, void* _edx, float floatA, int intA, int intB, char charA, int intC, int intD, int intE){
__asm
{
push ebp
mov ebp, esp
sub esp, 48h
push ecx
}
printf("ecx(this) = %p\n", thisptr);
printf("floata = %d\n", floatA);
printf("inta = %d\n", intA);
printf("intb = %d\n", intB);
printf("intc = %d\n", intC);
printf("intd = %d\n", intD);
printf("inte = %d\n", intE);
printf("charA = %d\n", charA);
__asm pop ecx
__asm mov ecx, intC
__asm jmp mapclick_back
}
hab zwar nicht geprüft was für ein wert ecx nach meinem mov hatte, aber da die function nicht getan hat was sie sollte wusst ich schon das ich iwas falsch mache, sry das ich noch so schlecht drin bin und soviel frage
danke dir sehr für die Antwort , und schon hat man wieder was gelernt
eine frage hätte ich jedoch noch unzwar, wie sieht das aufrufen so einer funktion in der eigenen main aus? also ich habe gesehn das die adresse vom thisptr, das selbe ist wie die value vom intA, nun hatte ich versucht die funktion zu callen, erstmal so
naja iwie hat mein (void*)intA 0 einfluss den thisptr in der function
Code:
printf("ecx(this) = %p\n", thisptr);/* kommt immer was komplett anderes raus, als das wie ich es aufrufen will, auch wenn ich für intA 0 habe steht da was anderes*/
daher dachte ich mir ich ändere ecx halt in meinem asm code.
dann hab ichs so versucht
Code:
int __declspec(noreturn) __declspec(naked) __fastcall MyOnMapClick(void* thisptr, void* _edx, float floatA, int intA, int intB, char charA, int intC, int intD, int intE){
__asm
{
push ebp
mov ebp, esp
sub esp, 48h
push ecx
}
printf("ecx(this) = %p\n", thisptr);
printf("floata = %d\n", floatA);
printf("inta = %d\n", intA);
printf("intb = %d\n", intB);
printf("intc = %d\n", intC);
printf("intd = %d\n", intD);
printf("inte = %d\n", intE);
printf("charA = %d\n", charA);
__asm pop ecx
__asm mov ecx, intC
__asm jmp mapclick_back
}
hab zwar nicht geprüft was für ein wert ecx nach meinem mov hatte, aber da die function nicht getan hat was sie sollte wusst ich schon das ich iwas falsch mache, sry das ich noch so schlecht drin bin und soviel frage
Nutz als erstes mal eine andere printf formatierung.
Und um die funktion aufzurufen musst du erstmal gucken was mit dem Registern gemacht wird, falls vorher werte gesetzt wurden etc. Könntest du mir einmal sagen ob du beim ecx wirklich immer den Wert von Inta hattest und nicht die adresse ?
Hab dir das mal mit einem Code verdeutlicht:
Code:
#include <iostream>
void Output(void *thisptr)
{
printf("ecx(this) = %p\n", thisptr);
}
int main()
{
int Test = 11;
// Hier wird der Wert der Adresse übergeben, 11
Output((void*)Test);
// Hier wird die Adresse übergeben ( bei jedem start anders )
Output((void*)&Test);
getchar();
return 0;
}
Da ich eher auf klassischen C++ cast stehe:
Code:
// Wird der Wert der Adresse übergeben, 11 (Durch den printf wird dadurch aber B, B = 11 in Hexadezimal)
Output( reinterpret_cast<void*>(Test) );
// Hier wird die Adresse übergeben
Output( reinterpret_cast<void*>(&Test) );
POPAD/POPFD hab ich vorgeschlagen, weil er im Endeffekt in seiner Funktion wesentlich mehr machen möchte als nur ein einfaches printf, wenn er jetzt nach deiner Erklärung nur ECX sichert, schmiert es ihm dann später ab, wenn er irgendeine seiner eigenen Funktionen benutzt. (Oder Stack-Variablen einführt, was ihm ESP zerschießen dürfte, oder? Kann das jemand verifizieren/widerlegen?)
Das Sichern der Flags ist nicht nötig. Die Zielfunktion wurde am Anfang gehookt. Nach dem Standard, an den sich die Compiler halten, sind die meisten Flags zu diesem Zeitpunkt eh unbestimmt. Und die, die einen vordefinierten Wert haben (Direction-Flag soweit ich weiß), haben diesen auch noch nach der Hookfunktion, da jeglicher Code, welche diese umsetzt am Ende auch gleich wieder zurücksetzt. Jedenfalls habe ich das bisher nicht anders gehen.
Alle Caller-Saved Register (abgesehen von ECX, welches hier ja die Sonderrolle von this einnimmt) müssen ebenfalls nicht gesichert werden (wie es der Name auch schon impliziert, in dem Fall ebenfalls korrekt). Die Funktion, welche die Zielfunktion aufruft, muss damit rechnen, dass diese Register nach dem Call der Zielfunktion zerstört sind (und muss die Register entsprechend selbst sichern, wenn sie diese noch braucht). Da die Register beim Aufruf keine besonderen Werte tragen und die Zielfunktion dank Hook am Funktionsbeginn die Register auch noch nicht mit Werten belegt hat, ist es egal, ob die Register ihren Wert in der Hookfunktion verlieren.
Callee-Saved Register müssen gesichert werden, sofern sie verwendet werden. Normalerweise muss man sich nicht kümmern, wenn man quasi-standardisierte Hooks benutzt. Mit diesem inline asm Zeug und den compilergenerierten Code dazwischen, wird es aber durchaus sinnvoll sein, diese zu sichern. Wobei simple Funktionsaufrufe (bspw. printf) eigentlich kein Callee-Saved Register ändern sollten, weil die Unterfunktion selbst das Callee-Saved Register natürlich selbst speichert und wiederherstellt und der Aufruf (also das Ablegen der Argumente auf dem Stack, das Call und das Säubern des Stacks) keine Callee-Saved Register benutzt, soweit ich weiß. Wobei diese Entscheidung eigentlich auch wieder Compilersache ist.
Nein, Stack-Variablen zerschießen ihn nicht den Stack, da der Compiler in einer declspec(naked) Funktion nicht für das Allokieren von Speicher auf dem Stack (in der Regel durch "sub esp, XX") zuständig ist. Ferner wird der Compiler sowieso keine lokalen Variablen zulassen, sofern er nicht sieht, dass entsprechend Platz auf dem Stack geschaffen wurde. Das sieht er meines Wissens nach, wenn man "sub esp, __LOCAL_SIZE" in den Prolog schreibt. Entsprechend muss man den Speicher aber am Ende auch wieder freigeben (bspw. mit add oder "mov esp, ebp" wenn man mit Framepointern arbeitet).
Quote:
Originally Posted by Terrat
Und um die funktion aufzurufen musst du erstmal gucken was mit dem Registern gemacht wird, falls vorher werte gesetzt wurden etc. Könntest du mir einmal sagen ob du beim ecx wirklich immer den Wert von Inta hattest und nicht die adresse ?
this wird sicherlich nicht die Adresse eines Arguments auf dem Stack sein
Da wäre es aber vermutlich eh besser einfach zweimal printf zu schreiben, statt die Funktion zu nutzen
Der Cast von "&Test" (einem int*) auf ein void* ist btw. unnötig, weil ein typisierter Zeiger (hier int*) auch ein (untypisierter) Zeiger (void*) ist. Der Cast dort geht implizit und das ist an der Stelle meiner Meinung nach auch vollkommen in Ordnung.
Quote:
Originally Posted by erfan100
naja iwie hat mein (void*)intA 0 einfluss den thisptr in der function
Code:
printf("ecx(this) = %p\n", thisptr);/* kommt immer was komplett anderes raus, als das wie ich es aufrufen will, auch wenn ich für intA 0 habe steht da was anderes*/
Ich rate dazu entweder die Funktion aussschließlich in asm zu schreiben oder ausschließlich in C/C++, da du dank declspec(naked) auf Register achten musst, aber dennoch Code vom Compiler generieren lässt, auf welchen du quasi keinen Einfluss hast. Oft wird eine kleine Stub in asm geschrieben, die alles Nötige an eine abstraktere C/C++-Funktion weiterreicht und bei Bedarf Register und Flags sichert und wiederherstellt. Das sieht man häufiger bei Midfunction-Hooks. In dem Fall braucht man eigentlich gar kein asm, da reicht ein "Standard"-Hook für den Funktionsanfang doch komplett aus. Du machst es dir wirklich schwerer als es eigentlich ist
danke euch wirklich sehr für die hilfe habs jetzt normal mit ms detours gemacht und scheint auch gut zu klappen ,
hier wie es jetzt aus sieht,vllt ist etwas ja doch noch falsch
Ja gut, hab ich was von Tempelates erwähnt ja gut hab ich nicht aber ja gut
Oh, sorry, mein Fehler. Ich sollte weniger von mir auf Andere schließen. Ich bin ein Fan von solchen Dingen.
Quote:
Originally Posted by erfan100
danke euch wirklich sehr für die hilfe habs jetzt normal mit ms detours gemacht und scheint auch gut zu klappen ,
hier wie es jetzt aus sieht,vllt ist etwas ja doch noch falsch
Sieht schon viel besser aus. Floats kannste, wie Terrat schon vor ein paar Posts erwähnte, schlecht mit %d ausgeben. Für die anderen Argumente kannste %d eigentlich weiter verwenden. Ist meines Wissens nach Synonym zu %i, aber man möge mich korrigieren, wenn ich falsch liege. Habe da jetzt nicht nachgeschaut.
Den char kannste theoretisch mit %c ausgeben, wie Terrat ebenfalls erwähnte. Das macht aber nur Sinn, wenn das tatsächlich ein Asciicharakter ist, und halt keine beliebige 8 bit Zahl (für was man char ja ebenfalls verwenden kann). In letzterem Fall ist %d / %i vermutlich die sinnvollere Variante.
Mit freundlichen Grüßen
Jeoni
[LUA] Funktion mit Funktion zu deaktivieren 06/17/2014 - General Coding - 8 Replies Hey,
Ich arbeite erst seit geringe Zeit mit Lua und wollte mal fragen ob ihr wisste wie das geht.
Also ich habe eine Funktion (z.B. Dmg aus) und ob ich dann in einer weiteren Funktion schreiben kann das wenn das chatcommand (was ich oben gadded habe) z.B. /dmgoff benutzt wird das dmg aus geht. (bzw das hab ich schon jetzt kommt mein Problem). Wenn ich in einer Weiteren funktion mit z.B. /dmgon (das command oben schon geadded) das dmg wieder einzuschalten in dem ich die dmgoff funktion...
[HELP]Kostümystem clientside grob und funktion für funktion fail.. 05/04/2014 - Metin2 Private Server - 2 Replies Moin ,
ich hab das Kostümystem clientside erst funktion für funktion eingefügt, zeile für zeile aber auch bei "grob einfügen (copy and past) den gleichen scheiß fehler..
0503 15:06:14429 :: CPythonPlayer::SetItemData(dwSlotIndex=5, itemIndex=1289) - Failed to item data
0503 15:06:14430 :: CPythonPlayer::SetItemData(dwSlotIndex=38, itemIndex=41010) - Failed to item data
0503 15:06:14548 :: CMapOutdoor::Load - LoadMonsterAreaInfo ERROR
[S] USA.net E-mail Spammer (Proxy Funktion & Account-listen Abruf Funktion) [B] e*g 04/24/2013 - elite*gold Trading - 0 Replies Hallo,
Ich Suche einen E-mail Spammbot der mit USA.net E-mail Adressen Arbeitet. den SMTP Herrauszufinden ist ja nicht Wirklich schwer. Er Sollte Proxy Funktionen haben (E-mail via Proxy versenden) Und er sollte eine liste mit Accounts (Format E-mail:Passwort) Einlesen und verwenden Können (Wenn eine E-mail nichtsmehr sendet wird eine 2te Genommen Also aus der Liste)
Hoffe ihr könnt mir da Weiterhelfen ^^ Kontakt Bitte per PN.
Hilfe bei Send Funktion mit Stop Funktion 04/02/2011 - AutoIt - 11 Replies Hallo Elitepvpers
ich habe ein Problem und Mein Problem ist das mein Text einfach weiter schreibt wenn ich mit HotKey verwende... gib es keine Funktion das der Text einmal kommt und nicht wenn man einmal die HotKey das er 10 min das selbe schreibt :confused:
[C++]Funktion einer Klasse in einer anderen Funktion der Klasse verwenden, aber wie? 07/25/2010 - C/C++ - 3 Replies Mein Problem ist eigentlich recht simpel und die Lösung wahrscheinlich auch.
Da ich bisher fast 0 mit Klassen am Hut hatte, wollte ich mich doch mit dem Thema anfreunden und hatte gleich angefangen:
int test::Funktion2()
{
int temp;
cin>>temp;
return temp;
}