[C++] DLL Probleme

12/07/2014 04:13 Benhero#1
Hallo EPvP Com,

folgendes Problem. Ich versuche einen Wert der an einer bestimmten Adresse ist auf 0 zu setzen. Aktuell verwende ich dafür "WriteProcessMemory" was auch soweit gut Funktioniert. Jedoch würde ich es gerne in ASM umsetzen. Versucht habe ich es bereits. Aber es ist immer Fehlgeschlagen. Die EndSequence wird ausgeführt das MOV aber leider nicht.

[Only registered and activated users can see links. Click Here To Register...]

Woran liegt es genau? Vermute hier einen Leichtssinns fehler.. Aber ich finde ihn eben nicht.
Ich habe es schon über XOR probiert aber ebenfalls ohne erfolg. Und eine schleife die X mal DEC ausführt möchte ich auch nicht verwenden.

Eine andere frage wäre, wie ich eine Funktion ausNOPen kann. Also Funktion gegen NOP austauschen.

Folgender ASM Code müsste ausgetauscht werden:

[Only registered and activated users can see links. Click Here To Register...]

Ich würde mich über Hilfe sehr Freuen (dies muss nicht direkt eine Lösung sondern mehr ein Anstupsen in die Richtige Richung sein.

Google wurde vorher benutzt, lieferte aber nur eine lösung über eine
#if
#...

Lösung an. Aber ich möchte es erst verstehen bevor ich es verwende. Was ich hier leider nicht tu.

Vielen dank!

#edit
Ein neues Problem ist aufgetreten. Und zwar stimmt die Struktur in der Konsole nicht mehr wenn ich "system("cls")" verwende. Ich habe bereits es über eine funktion zu lösen:
Code:
void clearScreen()
{
	for (int i = 0; i < 30; i++)
	{
		cout << endl;
	}
}
Jedoch gefällt mir daran nicht, das der Text nach Unten verschoben ist und darüber nun diese Whitespaces sind. Was kann ich dagegen tun?

Morgentliche Grüße


Problem Solved / Erledigt
12/07/2014 04:16 snow#2
#moved
12/07/2014 04:53 bloodx#3
bei einer Dll kannst du genauso den Präprozessor definieren

Projekt -> Eigenschaften -> C++ -> Präprozessor
12/07/2014 05:14 Benhero#4
Wtf... ó.o vorhin war es nochh nicht da. Nun aber schon -,-... Danke dennoch.
Vielen dank! Benhero
12/07/2014 13:20 MrSm!th#5
Du schreibst in deine "Pointer"variable 0, überschreibst also einfach nur die Adresse.
Es müsste mov [aRubish], 0 sein.
Ich empfehle dir aber lieber Funktionszeiger zu verwenden, damit du ganz auf ASM verzichten kannst.
12/07/2014 13:47 Benhero#6
Mir ist durchaus bewusst das ich ganz auf ASM verzichten kann.
Ob nun über Funktionspointer (die ich noch nicht kenne) oder über MemoryWrite.

Jedoch ist es wichtig für mich ASM zu verwenden da es mich (wenn auch nicht viel) weiter bringt. Sicherlich wäre reines ASM (OllyDBG, ...) dafür besser geeignet.
Jedoch verbessere ich so meine Kentisse in beiden Bereichen! :)

Werde mich dennoch erstmal mit Funktionspointern auseinander setzen!

#edit:
habe [Only registered and activated users can see links. Click Here To Register...] gefunden und verstehe zwar wie es funktioniert. Jedoch verstehe ich nicht in welcher hinsicht es einen Unterschied macht wenn ich diese Verwende anstatt direkt Funktionen aufzurufen. Oder meinen Sie etwas anderes als in diesem Beispiel beschrieben?

Grüße
12/07/2014 14:29 Jeoni#7
Leider ist nicht direkt gesagt, ob du nur 1 byte, 2 oder 4 byte mit 0 ersetzen willst. Da du ja vermutlich das zweite Argument der sub-Instruktion von 01 auf 00 ändern willst, gehe ich mal von einem byte aus.
Wenn man dein Unterfangen in ASM umsetzen will, ginge das ca. so:
Code:
mov byte ptr [0x421F7C], 1
call endSequence
Ein "mov [aRubish], X" erfüllt nicht den gewünschten Zweck, da es (zumindest im MSVC inline asm) auch lediglich den Variablenwert ändert. Mit einer einzigen Instruktion ist das auch quasi anders gar nicht möglich, da die Variable selbst eine Adresse, entweder absolut (wenn Variable global) oder relativ zum Frame- / Stackpointer (bei lokaler Variable), ist, welche dereferenziert werden muss. Den Wert der Variable, an den man nur mittels dereferenzierung rankommt direkt nochmals in der selben Instruktion zu dereferenzieren ist unter x86 / x64 meines Wissens nach nicht möglich. Das ginge nur über zwei Instruktionen oder halt irgendwelche Makros, die der Assembler anbietet.

Sonst lässt sich das ganze natürlich direkt in C / C++ umsetzen. Zum Aufrufen der Gamefunktion EndSequence beispielsweise kannst du ja keinen direkten Aufruf machen, weil die Funktion nicht teil deines Codes ist. Wenn du nun aber einen Funktionspointer deklarierst und ihm die Adresse der Funktion im Spiel zuweist, kannst du den Aufruf über den Pointer tätigen ohne inline asm oder dergleichen missbrauchen zu müssen:
Code:
typedef void (__stdcall* EndSequence_t)(); // typedef für leichtere Handhabung
EndSequence_t EndSequence = (EndSequence_t)0x405980;
...
EndSequence(); // Aufruf
Das Überschreiben des einzelnen Bytes ist natürlich in C / C++ ebenfalls möglich. Dazu halt einfach einen Pointer nehmen und dereferenzieren.
Mit freundlichen Grüßen
Jeoni
12/07/2014 18:06 MrSm!th#8
Quote:
Ob nun über Funktionspointer (die ich noch nicht kenne) oder über MemoryWrite.
Mit MemoryWrite kannst du keine Funktion direkt aufrufen. Ich dachte, es geht darum, erst den Parameter zu manipulieren und dann die Funktion aufzurufen?

Quote:
Ein "mov [aRubish], X" erfüllt nicht den gewünschten Zweck, da es (zumindest im MSVC inline asm) auch lediglich den Variablenwert ändert. Mit einer einzigen Instruktion ist das auch quasi anders gar nicht möglich, da die Variable selbst eine Adresse, entweder absolut (wenn Variable global) oder relativ zum Frame- / Stackpointer (bei lokaler Variable), ist, welche dereferenziert werden muss.
Du hast zwar Recht, was den technischen Hintergrund angeht, aber MSVC macht es hier meiner Erfahrung nach so, dass du mit mov aRubish, X einen Wert in die Variable schiebst (sprich die Adresse implizit dereferenzierst), obwohl es technisch gesehen eine sinnlose Instruction wäre (mov AdresseVonARubish, Wert). Ich habe es in der Konstellation des TEs noch nicht verwendet, ging aber aufgrund dieser Tatsache davon aus, dass mov [aRubish], X dann auch den Wert in aRubish dereferenziert und an die gewünschte Adresse den Wert schreibt. Dafür müssten aber natürlich zwei Instructions generiert werden, von daher kann es gut sein, dass du Recht hast und diese Sache mit mov aRubish, X von MSVC nur der Bequemlichkeit halber bei so einfachen Zugriffen unterstützt wird.
12/10/2014 01:35 Benhero#9
Ich habe es jetzt so Probiert wie es Jeoni vorgeschlagen hat, jedoch ohne erfolg.
Es ändert sich weiterhin die Adresse. Aber nicht der Wert der Adresse. Da es sich in diesem Fall um ein 4 Byte Wert handelt habe ich es folgendermaßen probiert:
[Only registered and activated users can see links. Click Here To Register...]
Wie man vermuten mag ist es mein Wunsch erst den Wert der Adresse 0x421F7C auf 0 zu setzen und dannach die End Sequenz aufzurufen.
Zweiteres funktioniert ohne Probleme. Nur wird beim ersten wie gesagt die adresse umgeschrieben. Siehe screen:
[Only registered and activated users can see links. Click Here To Register...]

Als zweites möchte ich einen nochmals einen Wert schreiben und dann wie schon vermutet den 2 Parameter einer SUB-Instruktion auf 0 setzen. Auch dafür habe ich schon verschiedene Wege Probiert. Leider ohne erfolg.

Auf folgender Adresse liegt die Instruktion:
[Only registered and activated users can see links. Click Here To Register...]

in diesem fall habe ich
Code:
mov byte ptr [0x40508D], 0
call endSequence
verwendet. Da das "01" auf dieser Adresse lag wie man hier sehen kann:
[Only registered and activated users can see links. Click Here To Register...]

Entweder mache ich etwas wirklich falsch ó.o.. oder es geht wirklich nicht...

ICh hoffe nochmals auf eure Hilfe.

Danke
12/11/2014 11:08 Computerfreek#10
Mal versucht, den Wert einfach in C++ zu ändern? So wie ich das verstanden habe, bist du an der Stelle sowieso im Prozess.
Versuchs mal mit:
Code:
*(DWORD*)(aRubbish) = 0;
Nebenbei: Funktionszeiger sind an sich nicht schwieig und lohnen sich wirklich. Versuch vilt. dir das ganze doch nochmal anzuschauen wenn du Zeit findest.
12/11/2014 12:33 Benhero#11
Habe es mitlerweile schon geregelt.
z.B. über:
Code:
mov eax, dword ptr ds : [aScore]
mov dword ptr ds : [eax], 999999