2013-10-30 17 views
6

Zunächst möchte ich nicht eine DLL injizieren. Ich möchte Code mit WriteProcessMemory() injizieren (wenn das überhaupt möglich ist). Ich habe bereits ReadProcessMemory() verwendet, daher denke ich, dass Schreiben keine große Sache ist.
Nun, können sagen, es ist eine Funktion, bei TargetProgram.exe + D78C612
und lassen Sie uns sagen, dass es wie folgt aufgerufen werden:C++: Code-Injektion zum Aufruf einer Funktion

push eax 
push [esp+08] 
push edx 
push 00 
push TargetProgram.exe+AF76235 
push 04 
call TargetProgram.exe+D78C612 

Wie genau würde ich dies mit Write erreichen()?
Ich meine, wo finde ich einen Abschnitt, in dem ich meinen Code injizieren kann, ohne wichtige Dinge zu überschreiben. Und am wichtigsten, wie würde ich die Funktion nennen?
Einfach einen Sprung zu meinem Code in der aktiven Routine machen, zurück springen und danach löschen? Aber wie würde ich die Routine finden?
So viele Fragen und ich habe keine Ahnung, wie ich anfangen soll ... Ich hoffe, du kannst mir helfen. :)
Und wenn Sie die Zeit haben, würde ich wirklich gerne einen Beispielcode einer Funktion-Aufruf-Injektion sehen.

Antwort

4

Sie können VirtualAllocEx verwenden, um Speicher im Remote-Prozess zu reservieren und dann Ihre Prozedur in diesen Speicher zu kopieren.

Hier sind die Schritte, um die Injektion zu tun:

SuspendThread(hThread); // Suspend the remote thread 
remote_address = VirtualAllocEx(hProcess, ...) // allocate memory for your code 
WriteProcessMemory(hProcess, remote_address, local_address, length, NULL) // copy your code to remote process 
WriteProcessMemory(hProcess, remote_fixup, ...) // insert a jump to your code 
ResumeThread(hThread); // Resume the remote thread 
+0

Ich habe ein ähnliches Problem wie OP, aber ich bekomme nicht Ihren ersten WriteProcessMemory Anruf. Als lokale_Adresse kann ich die Adresse meiner Funktion übergeben, aber ich kann ihre Länge in einem nächsten Argument nicht überschreiten. Einfach weil ich keine Ahnung habe wie groß es ist (da der Compiler es noch nicht kompiliert hat). Ist WriteProcessMemory also geeignet, um eine Funktion/einen Code von meinem Prozess in einen anderen zu schreiben? Edit: oder ist die einzige Key-Writing-Funktion in Assembler (ich kann es dann zählen) anstelle von C++? – Kra

+2

@Kra In den meisten Fällen können Sie Ihre C-Funktion nicht einfach in einen anderen Prozess kopieren, da die Sprungadressen unterbrochen werden. Sie müssen entweder Relocations reparieren oder einen Code schreiben, der verschoben werden kann.In beiden Fällen müssen Sie die Assemblersprache verwenden. Um Ihre Frage nach der Funktionscodelänge zu beantworten, können Sie versuchen, Optimierungen zu deaktivieren und zwei Funktionen f1() und f2() zu schreiben, wobei f2 im Code f1 folgt. Dann können Sie die Adresse von f1 von der Adresse von f2 subtrahieren und [hoffentlich] die Länge von f1 erhalten. Aber die Funktionsgröße ist hier das kleinste Problem. – Max

+0

Bekam den Punkt. Vielen Dank. – Kra

1

Wie Max Antwort erwähnt, VirtualAllocEx ist eine Möglichkeit, Speicherseiten in einem Remote-Prozess zuzuordnen, vorausgesetzt, Sie das PROCESS_VM_OPERATION Zugriffsrecht für den Prozess in Frage. Sie sollten auch sicherstellen, dass die neuen Seiten während des Schreibens als PAGE_EXECUTE_READWRITE mit ihrem Schutzlevel markiert werden und dann später unter Verwendung von VirtualProtectEx in PAGE_EXECUTE_READ geändert werden.

Beachten Sie, dass Verzweigungen und einige Aufrufanweisungen in x86 IP-relativ sind. Das bedeutet, dass ihre Kodierungen davon abhängen, wo sie sich im Speicher befinden, da sie eine vom Vorzeichen der Anweisung entfernte relative Verschiebung verwenden. Wenn Sie also vorhaben, eine vorhandene Funktion aus Ihrem neuen Code aufzurufen, müssen Sie dies berücksichtigen, wenn Sie eine relative Aufrufanweisung verwenden oder stattdessen ein indirektes/sofortiges Formular verwenden.

Ohne genau zu wissen, was Sie hier erreichen möchten, ist es jedoch schwierig, eine Technik zur Ausführung Ihres neuen Zielcodes zu empfehlen. Mit dem neuen Code können Sie einfach einen Remote-Thread mit CreateRemoteThread einfügen, um ihn auszuführen, ohne vorhandene Threads zu unterbrechen. Dies wäre die einfachste Lösung zum Ausführen des neuen Codes, erfordert jedoch, dass der Code, den Sie aufrufen, Thread-sicher ist. Einen bereits laufenden Thread zu picken, ihn zu unterbrechen, EIP zu modifizieren oder einen Umweg einzuführen und ihn ohne Nebeneffekte wieder aufzunehmen (richtiges Speichern des Kontexts über den injizierten Ruf), ist sehr schwierig, um es gelinde auszudrücken.

Persönlicher Hinweis: Als Autor des Code-Coverage-Tools in Visual Studio 2012, das eine Reihe von Tricks verwendet, um Code x86/x86-64 von Drittanbietern im Handumdrehen um Coverage-Daten zu überschreiben, ist dieses Zeug oh-so - viel Spaß zum hacken und nachdenken :)