Maschienencode zur laufzeit ausführen

Guten Abend,

Ich stehe momentan vor einem Problem. Und zwar möchte ich beliebigen Maschienencode zur Laufzeit ausführen können und auslesen. Also zum Beispiel Code der vom Benutzer eingegeben wurde soll ausgeführt werden. Natürlich müsste der Nutzer dann den Code als binary eingeben :wink:. Das müsste doch theoretisch machbar sein wenn man ihn an die richtige Stelle schreit oder?
Ich habe allerdings bisher noch 0 Ansatzpunkte wie ich das anstelle. Ich hab mir überlegt das es wahrscheinlich auf C oder besser C++ hinauslaufen wird. Oder muss ich doch Assembler verwenden?

Ich wäre sehr dankbar wenn ihr ein paar Tipps für mich hättet. Bin für alles dankbar.

Liebe Grüße cantharis

Howdy,

zunächst einmal ist das Ganze vom Programmieransatz her keine besonders gute Idee. Viren und Trojanerprogrammierer versuchen gerne zur Laufzeit, Fremdcode einzuschleusen. Was genau soll denn dein „Benutzer“ eingeben und zu welchem Zweck?

Zum Zweiten solltest du bei Fragen zu Byte Code/Assembler immer sagen, auf welcher Platform du denn überhaupt entwickeln willst (also mindestens Betriebssystem und Prozessortyp).

Zum dritten kann dein Programm durchaus ein Object Module oder eine shared Library zur Laufzeit erzeugen und danach dynamisch in den Speicher laden (siehe aber 1.). Die Programmiersprache ist dabei nahezu egal.

Gruss
norsemanna

Hallo,

vielen Dank für die schnelle Rückmeldung.
Also das der Benutzer Code eingibt war nur zur Veranschaulichung.
Ich will den Binärcode auslesen und nach Möglichkeiten verändern.

Verwenden tue ich Windows 7. Habe einen AMD Athlon X2 Dual-Core BE-2350, kann dir allerdings nicht sagen was für ein Prozessortyp das ist. Denke mal ganz normaler x86?

Hast du vielleicht ein paar Seiten für mich die ich mir mal ansehen kann?

Hallo,

vielen Dank für die schnelle Rückmeldung.
Also das der Benutzer Code eingibt war nur zur
Veranschaulichung.
Ich will den Binärcode auslesen und nach Möglichkeiten
verändern.

Das ist kein Problem. Man sollte aber
wissen, was man tut. Im Grunde: Binärcode
in C/C++ in ein unsigned-char Array einlesen
oder sonstwie hineinbringen, die Adresse dieses
Arrays dann Funktionszeiger casten und das ganze
aufrufen.

Geht nicht, glaubst Du? Versuch es! Unter
Win7 mußt Du ggf. die Executeable-Protektion
des Speichers des Arrays ausschalten.
http://msdn.microsoft.com/en-us/library/aa366898%28v…

Grüße

CMБ

1 Like

Hey,

und wie kann ich das ganze einlesen? Ich muss ja wissen wo der Codes anfängt und aufhört.

Grüße cantharis

Howdy,

und wie kann ich das ganze einlesen? Ich muss ja wissen wo der
Codes anfängt und aufhört.

lies mal die Dokumentation zum NASM, oder lass dir von Intel die blaue Reihe schicken

IA32 Intel Architecture Software Developers Manual
Vol 1: Basic Architecture
Vol 2: Instruction Set Reference
Vol 3: System Programming Guide

Die Bücher wurden von Intel fuer lau verschickt. Wenn ich mich richtig erinnere, dann musste man nur einen sehr kleinen Betrag für’s Porto zahlen.

Wenn du die grundlegenden Informationen zu Assembler und Codierungen nicht kennst, macht es sonst auch keinen Sinn, hier weiter zu diskutieren.

Gruss
norsemanna

Hallo,

vielleicht hast du mich ja nur falsch verstanden.
Also ich lese den Maschienencode in ein unsigned char Array ein. Verändere den Code und führe in dann anschließend aus. Mein Problem bei der Sache ist nur das ich nur einen bestimmten „Code-Teil“ meines Programmes einlesen möchte. Zum Beispiel eine Funktion. Wenn ich auf die einen Zeiger setzte weiß ich zumindest wo sie anfängt aber ich weiß nicht wo sie aufhört.

Grüße cantharis

Hallo nochmal,

void ausgabe()
{
cout

Howdy,

unsigned long myFuncLen = (long)Ende - (long)ausgabe;

also, das funktioniert nur in Ausnahmefaellen, und zwar dann, wenn der Compiler die beiden Funktionen tatsächlich hintereinander ablegt. Dazu ist er aber gar nicht verpflichtet … De-facto koennte sogar Ende vor ausgabe im Zielspeicher abgelegt werden. Auch kann es sein, dass eins oder mehrere der nachfolgenden asserts fehlschlaegt

assert(sizeof(long) == sizeof(void*));
assert(sizeof(long) >= sizeof(void*));
assert(sizeof(long) == sizeof(func_ptr));
assert(sizeof(long) >= sizeof(func_ptr));

sodass ein „long“ auf deinem System ueberhaupt nicht in der Lage ist, eine derartige Adresse zu halten sizeof(func_ptr) kann sogar wesentlich grösser als sizeof(long) sein, sizeof(method_ptr) in C++ ist es in der Regel sogar.

Aber Wie bekomm ich nun den Code der hinter dem Zeiger steckt?
Außerdem habe ich grade Fehlermeldungen bekommen weil ich für
den Array eine feste größe eingeben muss und einen
Funktionszeiger anscheinend nicht incrementieren kann.

Die Laenge der Funktion bekommst du aus dem darunter liegenden Object File (welches z.B. ELF oder COFF Format haben koennte).

Funktionspointer wie auch „void*“ kann man zu Recht nicht inkrementieren. Du muesstest auf char* casten und diesen dann nach deinen Wuenschen erhoehen.

Gruss
norsemanna

Hallo,

„Die Laenge der Funktion bekommst du aus dem darunter liegenden Object File (welches z.B. ELF oder COFF Format haben koennte).“

-> Das das sagt mir leider garnichts :\

Grüße cantharis