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!