Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [asm]JMP bei Delphi-Inline-Assemlber (https://www.delphipraxis.net/72631-%5Basm%5Djmp-bei-delphi-inline-assemlber.html)

SirThornberry 4. Jul 2006 10:57


[asm]JMP bei Delphi-Inline-Assemlber
 
Hallo,

ich will per Assemblerbefehl an die Adresse $00112233 springen

die Anweisung
Code:
jmp dword ptr [$00112233]
sorgt dafür das dorthin gesprungen wird worauf $00112233 zeigt
wenn ich
Code:
jmp [$00112233]
schreibe, wird automatisch von Delphi die erste Anweisung wieder daraus generiert (jmp dword ptr...)
Wie lautet die Anweisung um direkt zu einer Adresse zu springen?

Hawkeye219 4. Jul 2006 11:10

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Hallo,

vielleicht kannst du es mit einem kleinen Umweg lösen:

Code:
mov eax,$00112233
jmp eax
Es sollte aber auch eine direkte Möglichkeit geben.

Gruß Hawkeye

SirThornberry 4. Jul 2006 11:15

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
auf so einfaches zeug bin ich natürli nicht gekommen. wobei ich trotzdem noch nach dem direkten weg suche

NicoDE 4. Jul 2006 11:32

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Zitat:

Zitat von SirThornberry
wobei ich trotzdem noch nach dem direkten weg suche

BASM möchte unbedingt einen Relozierungseintrag erzeugen (die Adresse würde gefixt werden falls das Modul nicht an die gewünschte Adresse geladen werden kann). Du würdest diese Logik umgehen...

SirThornberry 4. Jul 2006 12:02

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
achso... und weiß dann jemand wie der direkte Sprung binär aussieht?

die Anweisung
jmp dword ptr [$00564774]
sieht ja binär so aus
FF2574475600
also FF25 ist der Befehl und dahinter die Adresse.

Wie sieht das ganze bei einem direkten Sprung aus?

himitsu 4. Jul 2006 12:53

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Ansonsten war deine Angabe eh falsch, in Betracht auf dein Ziel,
Delphi-Quellcode:
jmp [$00112233]
denn du wolltest doch bestimmt dieses verwirklichen? :zwinker:
Delphi-Quellcode:
jmp $00112233
die eckigen Klammern geben ja schließlich an, daß es dich bei der Angabe um einen "Zeiger" handeln soll.

Flocke 4. Jul 2006 12:54

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Der Opcode für einen direkten unbedingten Sprung ist $E9 - das wird dir aber nicht viel helfen: danach muss nämlich nicht die Zieladresse angegeben werden sondern das "Displacement", also die Differenz zwischen der neuen und der aktuellen Code-Adresse. Darum erzeugen Assembler für so einen Befehl auch eine Relokation - der Linker muss die Adressdifferenz beim Binden nämlich erst noch berechnen.

Mache es doch wie vorgeschlagen:
Code:
mov eax, $11223344
jmp eax

SirThornberry 4. Jul 2006 12:56

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Zitat:

Zitat von himitsu
Ansonsten war deine Angabe eh falsch, in Betracht auf dein Ziel,
Delphi-Quellcode:
jmp [$00112233]
denn du wolltest doch bestimmt dieses verwirklichen? :zwinker:
Delphi-Quellcode:
jmp $00112233
die eckigen Klammern geben ja schließlich an, daß es dich bei der Angabe um einen "Zeiger" handeln soll.

Ich bin in asm nicht so bewandert. Delphi hat immer rumgemeckert wenn ich die "[]" vergessen hab.
Desweiteren bin ich davon ausgegangen das "ptr" angibt das es sich um einen Pointer handelt.
Jetzt weiß ich aber wenigstens das man die eckigen Klammern bei einem direkten Sprung weg lassen muss/soll.
Nur die Binäre code für diese Anweisung (jmp $00112233) fehlt mir noch.

@Flocke: Ich hab einfach direkt hinter meinem Jmp-Befehl zur Zeit die eigentliche Sprungadresse hinterlegt.
Ich verweise somit also bei meinem Sprung auf die Adresse hinter dem Sprungbefehl wo wiederum die richtige steht.
Die Variante mit dem moven auf EAX hab ich nicht gewählt da ich nicht weiß ob EAX bereits belegt ist und ich somit den Wert überschreibe (bin nicht so bewandert in asm - ich guck in der Regel nur was Delphi für asm-code aus den Befehlen erzeugt und leite mir dann die Bedeutung durch Zunahme einer kleinen Hilfe her - somit sind mir die ganzen Register, deren Reihenfolge etc. unbekannt)

@Flocke: Bei E9 wird die Differenz angegeben? Das heißt man nimmt keinen "dword" mehr sondern einen Integer? Ist dabei sichergestellt das der Wertebereich des Integers auch groß genug ist?

benötigt hab ich das ganze für folgendes:
http://www.delphipraxis.net/internal...=573675#573675

Flocke 4. Jul 2006 13:31

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Zitat:

Zitat von SirThornberry
Die Variante mit dem moven auf EAX hab ich nicht gewählt da ich nicht weiß ob EAX bereits belegt ist und ich somit den Wert überschreibe (bin nicht so bewandert in asm - ich guck in der Regel nur was Delphi für asm-code aus den Befehlen erzeugt und leite mir dann die Bedeutung durch Zunahme einer kleinen Hilfe her - somit sind mir die ganzen Register, deren Reihenfolge etc. unbekannt)

Da MessageBoxA dir das Ergebnis in EAX zurückliefert ist der Inhalt beim Aufruf irrelevant.

Zitat:

Zitat von SirThornberry
@Flocke: Bei E9 wird die Differenz angegeben? Das heißt man nimmt keinen "dword" mehr sondern einen Integer? Ist dabei sichergestellt das der Wertebereich des Integers auch groß genug ist?

Die CPU interessiert eigentlich das Vorzeichen überhaupt nicht, Integer und Cardinal werden mit denselben Maschinenbefehlen addiert und subtrahiert. Da die CPU hier modulo 2^32 rechnet kommt das selbe heraus.

Alle "near jumps" sind PC-relativ, man gibt also nur den Adressversatz an und nicht die Zieladresse selbst. Dadurch müssen lokale Sprünge in Maschinensprache nicht reloziert werden (z.B. bedingte Sprünge bei if / while), denn der Versatz innerhalb deiner Prozedur ist nicht abhängig von der wirklichen Adresse. Im Grunde steht im Kompilat dann nicht "Springe zu Adresse X" sondern "Springe ab hier Y Byte nach vorne/hinten".

Wenn du unbedingt eine "inline"-Variante mit absoluter Adresse haben willst, dann nimm:
Code:
$68 aa:bb:cc:dd    // push aa:bb:cc:dd <- hier die Adresse einsetzen
$C3                 // ret
das ist äquivalent zu einem Sprung (jmp).

SirThornberry 4. Jul 2006 13:39

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
bei
Code:
$68 aa:bb:cc:dd    // push aa:bb:cc:dd <- hier die Adresse einsetzen
$C3                 // ret
wird doch aber der Stack angefasst oder nicht? ich wollte eigentlich eine allgemeine Funktion schreiben welche die Funktion umleitet auf eine mit gleichen Parameter ohne berücksichtigung ob diese EAX verwendet oder nicht.

Danke für den Excurs mit der relativen Sprungadresse. Allerdings versteh ich das nicht ganz.
Wenn ich mich zur Zeit an Adresse 500 befinde und dann realtiv angebe das ich vor/zurück 50 springen will. Woher weiß dann der Prozessor ob ich zu 550 oder 450 springen will?

himitsu 4. Jul 2006 13:40

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Zitat:

Zitat von Flocke
Der Opcode für einen direkten unbedingten Sprung ist $E9

nö, dat is der Opcode für einen direkten short jump oder wie dat nochmal hieß.
Also einen sozusagen ein relativer Sprung, von der Stelle aus, wo er steht.

Den Opcode für einen absoluten Sprung hab ich auch gerade nicht im Kopf ... könnte höchstens mal heut abend nachseh ^^


Zitat:

Zitat von SirThornberry
Desweiteren bin ich davon ausgegangen das "ptr" angibt das es sich um einen Pointer handelt.

im Grunde gibt das PTR (Pointer) ja auch an, daß es sich um einen solchen handelt, aber dieses muß nicht immer angegeben werden, wenn klar ist, worum es sich handelt.

Es ist so ähnlich wie mit Flocke's Code...
Delphi-Quellcode:
mov eax, $11223344
jmp eax
so ginge es ja auch
Delphi-Quellcode:
mov eax, dword $11223344
jmp eax
da [] eh auf 'nen Pointer hinweißt, ist es also nicht nötig ... genauso wie das dword, da im Win32 doch eh alles erstmal als LongInt/LongWord/32-Bit-Pointer angesehn wird.
Delphi-Quellcode:
// das ist also dat "Selbe"
mov eax, dword ptr [$11223344]
mov eax, ptr [$11223344]
mov eax, [$11223344]

// wohingegen das mal was Anderes ist ^^
mov eax, byte ptr [$11223344]
Zitat:

Zitat von SirThornberry
@Flocke: Bei E9 wird die Differenz angegeben? Das heißt man nimmt keinen "dword" mehr sondern einen Integer? Ist dabei sichergestellt das der Wertebereich des Integers auch groß genug ist?

Na ja, es gibt verschiedene Varianten ... also mit auch solche mitr ShortInt und SmallInt.
Ist praktischer, weil die ja weniger Speicher verbrauchen, man kann damit allerdings nicht so weit springen ... was aber och klar sein sollte ^^


Zitat:

Zitat von SirThornberry
Ich bin in asm nicht so bewandert. Delphi hat immer rumgemeckert wenn ich die "[]" vergessen hab.

Wie gesagt ... syntaktisch würde es stimmen, aber wie Nico schon sagte will der Delphi-ASM sowas nicht. :zwinker:
Also ich kann höchstens dann nochmal nachgucken was der richtig Opcode hierfür wäre oder du nimmst den indirekten Weg :roll:


Aber was ich mich bisher immer grfragt hab ... woher will eigentlich Windows wissen was ein Pointer ist und ob der eventuell gefixt werden muß?
Weil oftmals ist es ja nicht gerade eindeutig, was einer ist, oder ob der schon gefixt wurde.

z.B.
Delphi-Quellcode:
JMP EAX
Windows kann doch shcließlich nicht wissen was das für ein Wert in EAX ist :gruebel:

SirThornberry 4. Jul 2006 13:45

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
über das Fixen von Windows hab ich mir bisher gar keine Gedanken gemacht. Aber so wie du das schreibst würds mich auch interessieren woher windows weiß was gefixt werden muss und was nicht. Wobei Windows das früh oder Später ja ausführt und von daher schon wissen sollte was durch die Befehle passiert.

himitsu 4. Jul 2006 13:53

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
aso
Zitat:

Zitat von SirThornberry
benötigt hab ich das ganze für folgendes:
http://www.delphipraxis.net/internal...=573675#573675

OK, an dieser Stelle wäre natürlich der direkte Sprung nicht schlecht ^^
Obwohl du dort natürlich auch relativ springen könntest

Code:
JMP (neueFunktion - aktuellePosition)
also in etwa:
Delphi-Quellcode:
lBuffer : Array[0..4] of Byte;
...
PByte(@lBuffer)^ := $e9;
PCardinal(@lBuffer[1])^ := Cardinal(ANewFunction) - Cardinal(AOldFunction);
PS: wenn du es schon so aufschlüsselt, dann wäre es so wohl "richtiger" ;)
Delphi-Quellcode:
lBuffer : Array[0..(2 + 4 + 4) - 1] of Byte;

himitsu 4. Jul 2006 14:01

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
[ä bissl OT]
Zitat:

Zitat von SirThornberry
Wobei Windows das früh oder Später ja ausführt und von daher schon wissen sollte was durch die Befehle passiert.

gerade da ligt ja z.B. eines der Probleme ... es kann es eben nicht wissen.
wenn ich z.B. irgendwo im Quellcode einer Variable einen hardcodierten Wert übergeben, welcher z.B. die Position einer Funktion ist,
Delphi-Quellcode:
Variable := @Funktion;
(wenn funktion eine eigene Funktion im eigenem Programm ist, dann wird der Wert ja vom Compiler hardgecodet)

dort vielleicht noch ein bissl rumrechne
Delphi-Quellcode:
Variable := Variable + irgendwas;
und dann wohinspringen will,
Delphi-Quellcode:
JMP &Variable
dann muß hier gefixt werden, wenn die der Programmcode nicht an seiner vorgesehenen Position ist.

Wenn ich das ganze aber mit aktuellen Werten aus dem laufenden Programm mache, dann sind die Positionen ja schon gefixt (da dort die verwendete Funktion schließlich bereits verschoben wurde) und müssen demnach ja nichtmehr gefixt werden. o.O

SirThornberry 4. Jul 2006 14:18

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
@Himitus: das "JMP &Variable" muss eignetlich nicht gefixt werden da der Inhalt der Variablen bereits vorher gefixt wird. Der Inhalt von "Variable" ergibt sich ja aus anderen Adressen und diese sind bereits gefixt.

brechi 4. Jul 2006 14:36

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
es gibt keinen assembler befehl für einen 'absoluten' jump so wie du ihn suchst.

entweder

Delphi-Quellcode:
mov eax, addr
jmp eax
oder

Delphi-Quellcode:
push addr
ret
nehmen oder den Umweg über eine globale/lokale variable machem.

Delphi-Quellcode:
jmp [variable]
und 0xE9 ist kein relative short distance jump, das wäre 0xEB

und wenn du die einen relativen jump brauchst, die berechnung wäre zieladresse-vonadresse-5

Boombuler 4. Jul 2006 15:00

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
PS: http://faydoc.tripod.com/cpu/jmp.htm
Merke: Der Link ist natürlich nur für x86

Wenn ich das nu Spontan Richtig sehe wäre also ein FF ein direkter Jump auf die Addy!

(Nich hauen wenns falsch ist ;) )

Greetz
Boombuler

SirThornberry 4. Jul 2006 16:34

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
ich habs jetzt erstmal mit dem ablegen auf dem Stack, und dann mit "ret" zur Adresse "zurück" springen gemacht. Das spaart im Gegensatz zu meiner Ursprünglichen Variante schon ganze 4 Byte.
Den Link werd ich mir gleich mit ansehen.

[Edit]
Ein reines FF reicht nicht aus. Und sobald 1 Byte mehr dazu kommt bin ich wieder bei der gleichen Anzahl wie bei der Variante mit push + ret

Die Variante mit push + ret sieht so aus
$68$33$22$11$00
$C3
[/Edit]

himitsu 4. Jul 2006 16:39

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Delphi-Quellcode:
Variable := @Funktion;
entspricht
Delphi-Quellcode:
MOV &Variable, $00123456
hier kann nichts von windows gefixt werden, denn für Windows ist es nur eine "normale" Zahl, welche in irgendeinen peicherbereich kopiert wird ... und da es nicht wissen kann, daß es eigentlich ein Pointer ist, kann es dort definitiv nicht fixen und später fixen ginge och nicht, da dort Windows eigentlich nicht wissen kann, ob gefixt werden muß, oder nicht, da es ja nicht weiß was für ein Wert in der Variable drinsteht, also ob das schon ein gefixter ist, oder eben noch ein ungefixter (aus 'nem hardgecodeten Pointer).

denn wenn ich sowas mache, dann würde ja ein "gefixter" Wert in die Variable geschrieben, da ja die Adresse der bereits verschobenen Prozedur zurückgegeben wird.
Delphi-Quellcode:
Variable := GetProcAddr('irgendwas');
also liebe als letztes nur noch der Jump-Befehl, wo windows fixen könnte, aber da es ja nicht weiß was in Variable für ein Wert ist ... woher soll es denn dann wissen, was es machen soll?
Delphi-Quellcode:
JMP &Variable

brechi 4. Jul 2006 16:58

Re: [asm]JMP bei Delphi-Inline-Assemlber
 
Delphi-Quellcode:
Variable := @Funktion;
in dem Fall weiß der Compiler, dass er einen Eintrag in die Relocation Table packen muss

Delphi-Quellcode:
MOV &Variable, $00123456
in dem Fall nicht. Wer auch immer nu Recht hat, wollte das nur noch mal sagen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz