Ein Multiedit im Speicher

Der folgende Artikel bezieht sich auf die Betriebsysteme Windows2000/XP. Die hier aufgeführten Tests wurden unter Windows2000 unter einem Administratoraccount durchgeführt.
Für das Nachvollziehen der hier gemachten Aussagen sind folgende Zusatzprogramme erforderlich:
- Tasks and Token
- Eine Version von Profan² bzw. XProfan.
- Profan2Cpp

Als Ausgangspunkt soll folgender Quelltext dienen:

Windowstyle 31

Windowtitle "Multiedit"

Window 0,0-640,440

Def @Globalsize(1) !"KERNEL32","GlobalSize"

Def @Globallock(1) !"KERNEL32","GlobalLock"

Def @Copymemory(3) !"kernel32","RtlMoveMemory"

Def @Globalrealloc(3) !"KERNEL32","GlobalReAlloc"

Def @Setparent(2) !"USER32","SetParent"

Def @Getwindowlong(2) !"USER32","GetWindowLongA"

Declare Edit&,Text$,Addr&,Handle&,Text#,Wind_proc&

Dim Text#,256

Let Edit&=@Createmultiedit(%Hwnd,"Test ",20,130,200,200)

Let Text$="ABCD"

Let Handle&=@Sendmessage(Edit&,$Bd,0,0)

Print "Handle des Edits: "+@Str$(Edit&)

Settext Edit&,@Str$(Handle&)

Let Addr&=@Globallock(Handle&)

@Copymemory(Addr&,@Addr(Text$),32)

@Copymemory(Text#,Addr&,32)

Print "Adresse: "+@Str$(Addr&)

Print "Breichshandle: "+@Str$(Handle&)

Print "Kopierter Text: "+@String$(Text#,0)

Print "Bereichgröße: "+@Str$(@Globalsize(Handle&))+" Bytes"

Let Wind_proc&=@Getwindowlong(Edit&,$Fffffffc)

Print "Adresse der Fensterprozedur: "+@Str$(Wind_proc&)

Dispose Text#

While 0=0

Waitinput

Wend


Danach starten wir Tasks and Token, klicken im Fenstermenü auf 'Zahl in Bytefolge umwandeln' und geben hier das Fensterhandle (bei mir 131840) ein. Nun klicken wir den Prozess an, den unser Quelltext erzeugt hat und wählen nach einem Rechtsklick ins Treeview 'Speicher durchsuchen'. Die Startadresse setzen wir auf 0, hinter die Bytefolge hängen wir eine 01 an und klicken dann auf 'Speicher durchsuchen'. Die letzte gefundene achtstellige Adresse schauen wir uns mal etwas genauer an und lassen uns 4000 Bytes ab dieser Adresse als dezimale Doublewords auslesen:


Das steht bei mir (der Windows-Taschenrechner hilft beim Umwandeln der hexadezimalen Fensterstile ins Dezimalsystem):

X1=131840 => Handel des Fensters

X2=1

X3=-497068184

X4=-30007432

X5=-1607067536

X6=537526278

X7=-2147482864

X8=512 => erweiterter Fensterstil

X9=1345392964 => Fensterstil

X10=4194304 => Instancehandle

X11=44236800

X12=0

X13=-1607067760

X14=0

X15=0

X16=24 => X-Koordinate der oberen linken Ecke auf dem BIldschirm

X17=153 => Y-Koordinate der oberen linken Ecke auf dem BIldschirm

X18=224 => X-Koordinate der unteren rechten Ecke auf dem BIldschirm

X19=353 => Y-Koordinate der unteren rechten Ecke auf dem BIldschirm

X20=26 => Clientbereich X-Koordinate der oberen linken Ecke auf dem BIldschirm

X21=155 => Clientbereich Y-Koordinate der oberen linken Ecke auf dem BIldschirm

X22=206 => Clientbereich X-Koordinate der unteren rechten Ecke auf dem BIldschirm

X23=335 => Clientbereich Y-Koordinate der unteren rechten Ecke auf dem BIldschirm

X24=2011246703 => Adresse der Fensterprozedur

X25=-1607072328

X26=0

X27=0

X28=-1607067368

X29=0

X30=1000 => ID des Fensters im Prozess

X31=0

X32=18

X33=20

X34=-1607067320

X35=6

X36=0

X37=0

X38=0

X39=36685600 => An dieser Adresse findet man ein Doubleword, das das Handle des Textes im Edit angibt

X40=0

X41=1376262

X42=786688 => Scheint u.a. das Ende des Bereiches mit Fensterinformationen für das Handle 131840 zu markieren

X43=15

X44=0

X45=64

X46=65

X47=0

X48=0

X49=0

X50=1

X51=0

X52=0

X53=393220

X54=786688

X55=6619220

X56=7602291

X57=2097184

X58=2097184

X59=32

X60=0 ....



Mittels EM_GETHANDLE läßt sich dann das Handle des Textes (der DLL) im Edit ermitteln. Mittels folgendem Quelltext wollen wir uns jetzt mal etwas näher um die Adresse kümmern - unter 2000/XP natürlich:

Windowstyle 31

Windowtitle "Multiedit"

Window 0,0-640,440

Def @Globalsize(1) !"KERNEL32","GlobalSize"

Def @Globallock(1) !"KERNEL32","GlobalLock"

Def @Copymemory(3) !"kernel32","RtlMoveMemory"

Def @Globalrealloc(3) !"KERNEL32","GlobalReAlloc"

Def @Setparent(2) !"USER32","SetParent"

Declare Edit&,Text$,Addr&,Handle&,Text#

Dim Text#,256

Let Edit&=@Createmultiedit(%Hwnd,"Test ",20,130,200,200)

Let Text$="ABCD"

Let Handle&=@Sendmessage(Edit&,$Bd,0,0)

Print "Handle des Edits: "+@Str$(Edit&)

Settext Edit&,@Str$(Handle&)

'Let Addr&=@val(@Input$("Adresse des Edits:","Addresse",""))

Let Addr&=@Globallock(Handle&)

'@CopyMemory(Addr&,@ADDR(Text$),32)

@Copymemory(Text#,Addr&,32)

Print "Adresse: "+@Str$(Addr&)

Print "Breichshandle: "+@Str$(Handle&)

Print "Kopierter Text: "+@String$(Text#,0)

Print "Bereichgröße: "+@Str$(@Globalsize(Handle&))+" Bytes"

Dispose Text#

While 0=0

Waitinput

Wend


Da Profan etwas verschwenderisch mit Heaps umgeht, sollte man den Quelltext mit Profan2Cpp compilieren. Beim mir sieht das ganze dann in etwa so aus:


Im Edit steht hier das Handle des Textes. Nun starten wir
Tasks and Token, wählen den Testprozess mit dem Multiedit aus und lassen uns dessen Heaps listen.


Nun tun wir mal so als wäre das Handle des Textes (bei mir 44630028) eine Adresse und lassen uns das Doubleword an dieses Adresse von
Tasks and Token einmal auslesen.



Heraus kommt bei mir: X1=38184920
Jetzt tun wir wiederum so, als wäre 38184920 und schauen unter den Heaps nach, ob wir irgendwo diese Adresse finden und lassen uns den Inhalt des Heapblocks als String darstellen:


Wie man sieht, haben wir die Adresse des Textes im Edit gefunden!


Impressum