2010-02-22 19 views
12

Nur aus Neugier Ich frage mich, ob es möglich ist, ein Stück Code während die Ausführung eines Programms zu verschieben. Zum Beispiel habe ich eine Funktion und diese Funktion sollte im Speicher jedes Mal ersetzt werden, nachdem es ausgeführt wurde. Eine Idee, die uns in den Sinn kam ist die Verwendung von selbst modifizierenden Code, um das zu tun. Laut einigen Online-Ressourcen kann der selbstmodifizierende Code unter Linux ausgeführt werden, aber ich bin mir nicht sicher, ob eine solche dynamische Verlagerung möglich ist. Hat jemand Erfahrung damit?Dynamische Verlagerung von Code Abschnitt

+0

Wie rleir suggeriert, wäre es nicht einfacher, um Funktionszeiger zu tauschen, anstatt Dinge tatsächlich zu verschieben? – joveha

Antwort

8

Ja dynamischer Umzug ist definitiv möglich. Sie müssen jedoch sicherstellen, dass der Code vollständig eigenständig ist oder dass er auf globale/externe Funktionen durch absolute Referenzen zugreift. Wenn Ihr Code vollständig positionsunabhängig sein kann, dh die einzigen Referenzen, die er erstellt, sind relativ zu sich selbst, sind Sie festgelegt. Andernfalls müssen Sie die Korrekturen zur Ladezeit selbst durchführen.

Mit GCC können Sie -fpic verwenden, um positionsunabhängigen Code zu generieren. Übergeben -q oder --emit-relocs an den Linker wird es Verlagerungsinformationen emittieren. Die ELF specification (PDF-Link) enthält Informationen zur Verwendung dieser Umzugsinformationen. Wenn Sie ELF nicht verwenden, müssen Sie die entsprechende Dokumentation für Ihr Format finden.

0

Wenn diese verschiedenen Funktionen zur Kompilierzeit vorhanden sind, können Sie einfach einen Funktionszeiger verwenden, um den nächsten zu protokollieren, der aufgerufen werden soll. Wenn Sie die Funktion zur Laufzeit unbedingt ändern müssen und diese Änderung nicht vor Ort durchgeführt werden kann, können Sie auch einen Funktionszeiger verwenden, der beim Anlegen/Laden der Adresse der neuen Funktion aktualisiert wird. Der Rest Ihres Systems würde dann die selbstmodifizierende Funktion über den Funktionszeiger aufrufen und muss daher den selbstmodifizierenden Code nicht kennen oder sich darum kümmern, und Sie müssen die Korrektur nur an einer Stelle vornehmen.

3

Wie Carl sagt, es kann getan werden, aber Sie öffnen eine Dose Würmer. In der Praxis sind die einzigen Leute, die sich die Mühe machen, Akademiker oder Malware-Autoren (die jetzt meinen flammfesten Mantel anziehen).

Sie können einen Code in eine Malloc'd-Heap-Region kopieren und dann über Funktionszeiger aufrufen, aber je nach Betriebssystem müssen Sie möglicherweise die Ausführung im Segment aktivieren. Sie können versuchen, Code in das Codesegment zu kopieren (achten Sie dabei darauf, die folgende Funktion nicht zu überschreiben), aber das Betriebssystem hat dieses Segment wahrscheinlich schreibgeschützt gemacht. Vielleicht möchten Sie sich den Linux-Kernel anschauen und sehen, wie er seine Module lädt.

+1

+1 fasst einige schöne Punkte zusammen. Über die Seitenmodi zum Schreiben/Ausführen: Sie können diese im laufenden Betrieb mit VirtualProtect auf win32 und mprotect auf Linux ändern. Und alle lesbaren Seiten sollten auch ausführbar sein, weil unsere Vorfahren etwas falsch verstanden haben – joveha