Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Maschinencode ausführen


Boldar - Mi 14.04.10 17:29
Titel: Maschinencode ausführen
Hallo,
mal nur interessehalber:
Kann man beliebigen Maschinencode als prozedur ausführen?
Also quasi zur Laufzeit im Code-Segment speicher reservieren, da das entsprechend reinschreiben, ein ret dahinter und dann dorthin springen?
Und wenn ja: wie ginge das?
mfg Boldar


Moderiert von user profile iconNarses: Topic aus Windows API verschoben am Mi 14.04.2010 um 22:24


Jakob_Ullmann - Mi 14.04.10 17:36

Meinst du Maschinencode oder Assembler? Das geht z. B. so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure MacheWas(a1: DWORD); assembler;
asm
  push  eax
  mov   eax, a1
  mul   eax, 2
  mov   x, eax
  pop   eax
end;


Boldar - Mi 14.04.10 17:38

Nein, ich möchte nicht asm eincompilieren, sondern zur Laufzeit beliebigen Maschinencode ausführen.
Also z.B. vom user eingegebenen.


BenBE - Mi 14.04.10 18:00

Musst Du dir nen kleinen Assembler schreiben, oder den User fragen, dass er bitte den Code als Binary ins Edit hackt.


Boldar - Mi 14.04.10 18:27

Ich sprach ja auch von Maschinencode, nicht von Assembler.
Die Problematik ist nur, den Maschinencode auszuführen.


Jakob_Ullmann - Mi 14.04.10 20:00

Bitte Bescheid sagen, wenn ich jetzt groben Unsinn erzähle, aber prinzipiell sollte der Maschinencode doch dann als COM / EXE vorliegen und wäre nur noch an der richtigen Stelle in die EXE zu schreiben (bei EXE müsste man halt den Header entfernen).


elundril - Mi 14.04.10 20:06

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Bitte Bescheid sagen, wenn ich jetzt groben Unsinn erzähle, aber prinzipiell sollte der Maschinencode doch dann als COM / EXE vorliegen und wäre nur noch an der richtigen Stelle in die EXE zu schreiben (bei EXE müsste man halt den Header entfernen).


und den einstiegspunkt finden, oder?


ALF - Mi 14.04.10 20:09

Das machen doch auch die, die uns die Vieren an den exe'n oder com hineinschreiben! :wink:
Wie ist mhhh... ganz einfach. Nur ist die Frage ob man sowas Public macht! :?

Gruss Alf


BenBE - Mi 14.04.10 20:49

@ALF: Wer Doku liest, ist klar im Vorteil. Da steht (zumindest bei M$) alles Nötige drinnen ;-) Man muss es nur zusammensetzen.

Aber gut. Angenommen, wir haben an einer Stelle im RAM den Maschinenkot bereits stehen, dann geht das Ausführen ganz einfach mit:


Delphi-Quelltext
1:
2:
3:
4:
procedure ExecMem(const Entry: TProcedure);
asm
    PUSH    EAX
end;


Man kann aber auch komplett ohne ASM arbeiten und einfach:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
    P: Pointer;

type
    TProc = procedure;

{...}

    TProc(P);


machen. Wenn man dann zusätzlich Parameter übergeben will, geht das mit:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
    P: Pointer;

type
    TFunc = Function(const A; var B; const C const D): Quz;

{...}

    Result := TFunc(P)(Foo, Bar, Baz, Quo);


Boldar - Mi 14.04.10 21:47

Nun gut.
Aber: Wie kriegt man den Code in den Ram?
und wie springt man danach wieder zurück?
Und: geht das Üerhaupt so einfach, ohne das Windows dazwischenfunkt?


BenBE - Mi 14.04.10 22:05

Ich weiß nicht, was Du hast:


Delphi-Quelltext
1:
const Code: array[0..4of Byte = ($33$C0$CC$90$C3);                    


Noch ein wenig Rumpointern und man ist fertig ;-)


Kha - Mi 14.04.10 22:50

Sobald es allerdings um etwas dynamischeren Code geht, dürfte man schnell einen GPF [http://en.wikipedia.org/wiki/General_protection_fault] kassieren. Aber wie du schon sagtest, Microsoft hat das alles schön dokumentiert [http://support.microsoft.com/kb/127904] :D .


ALF - Do 15.04.10 04:36

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
@ALF: Wer Doku liest, ist klar im Vorteil. Da steht (zumindest bei M$) alles Nötige drinnen ;-) Man muss es nur zusammensetzen.

Ja ich weis, wer es drauf anlegt, macht es ja auch. Erleben wir ja leider immer wieder. :(

Gruss Alf


Steve1024 - Sa 24.04.10 22:20

hmmm... was ist mit globalalloc umd GMEM_EXECUTABLE oder so ähnlich.
damit kann man doch einen speicherbereich reservieren, denn dann als ausführbar markiert ist. d.h. wenn da maschienencode drin steht sollte das funktionieren.

Hab da aber nicht so 100%ig ne ahnung.
aber man kann mal nach DLL aus speicher laden suchen. da passiert sowas ja auch.

Hoffe ich konnte helfen und schönen abend noch!