Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi StringReplace verursacht AV (https://www.delphipraxis.net/190480-stringreplace-verursacht-av.html)

EWeiss 7. Okt 2016 17:43


StringReplace verursacht AV
 
Delphi-Quellcode:
var
  Txt: PWideChar;
  tmpTxt: WideString;

Txt := PWideChar(SkinEngine.GetCTLText(PDis.hwndItem));
tmpTxt := StringReplace(string(Txt), '&','', [rfReplaceAll]);
txt Rückgabe ist "Ö&ffnen"
tmpTxt soll jetzt den Char "&" entfernen aber es kracht mal wieder.

Kann nicht erkennen wo hier wieder ein Fehler sein soll.
read of address ...

gruss

Jim Carrey 7. Okt 2016 17:48

AW: StringReplace verursacht AV
 
Ich habe bei mir mal folgendes getestet und ich habe keine AV bekommen:
Delphi-Quellcode:
var
 Txt: PWideChar;
 tmpTxt: WideString;
begin
 Txt := 'Ö&ffnen';
 tmpTxt := StringReplace(string(Txt), '&', '', [rfReplaceAll]);
end;
Also entweder wird hier auf eine andere StringReplace-Funktion zurückgegriffen oder es gibt einen Fehler in der Zeile, wo der Variable "Txt" etwas zugewiesen wird.

himitsu 7. Okt 2016 17:50

AW: StringReplace verursacht AV
 
Delphi-Quellcode:
string(Txt)

Weg mit dem schrottigen Cast und wenn nicht, dann soll man sich auch nicht wundern, wenn man die automatische Speicherverwaltung der Strings durcheinander bringt.


Delphi-Referenz durchsuchenStripHotkey

Jim Carrey 7. Okt 2016 17:56

AW: StringReplace verursacht AV
 
Frage neben bei:
was macht StripHotkey anders als StringReplace?

Dalai 7. Okt 2016 18:06

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Jim Carrey (Beitrag 1350154)
was macht StripHotkey anders als StringReplace?

StripHotkey entfernt nicht nur die im Westen üblichen Ampersands sondern auch die in Asien üblichen Hotkeys in Klammern, z.B. "Open (O)".

Grüße
Dalai

Luckie 7. Okt 2016 18:32

AW: StringReplace verursacht AV
 
Aber warum nur? :? Woher soll der Nutzer denn wissen, welches der Hotkey für die Schaltfläche ist?

himitsu 7. Okt 2016 18:47

AW: StringReplace verursacht AV
 
Und es lässt geqoutede Hotkeys dequoted zurück.

Delphi-Quellcode:
&Hallo && Tschüss

EWeiss 7. Okt 2016 18:59

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Luckie (Beitrag 1350158)
Aber warum nur? :? Woher soll der Nutzer denn wissen, welches der Hotkey für die Schaltfläche ist?

Weil er in meiner DrawText Funktion es so zeichnet wie angegeben.

Ohne das entfernen steht auf meinen Button der Text so "Ö&ffnen"
Warum GDI Plus das nicht erkennt da fragst du mich zu viel.

gruss

EWeiss 7. Okt 2016 19:01

AW: StringReplace verursacht AV
 
Zitat:

Zitat von himitsu (Beitrag 1350153)
Delphi-Quellcode:
string(Txt)

Weg mit dem schrottigen Cast und wenn nicht, dann soll man sich auch nicht wundern, wenn man die automatische Speicherverwaltung der Strings durcheinander bringt.


Delphi-Referenz durchsuchenStripHotkey

Wird gemacht ;)

EDIT:
Ok hat sich erledigt..
Nach dem aktivieren des Combo Hook um eigene Bilder in den Button zu zeichnen habe ich das HDC Array zu klein ausgelegt.
Da kam es dann beim zeichnen des Button Text zu Problemen.

Bedingt durch die Events Probleme die bei meinem Ownerdraw FileDialog auftraten muss ich nun die ganzen Controls Original belassen und diese Hooken.
Button und der Button der Combo sind fertig der Rest kommt noch.
Hab ja sonst nix zu tun.


gruss

EWeiss 10. Okt 2016 11:22

AW: StringReplace verursacht AV
 
Kann es sein das StringReplace intern einen Fehler verursacht.
Also die Funktion selbst?

Folgendes Szenario.

Delphi-Quellcode:
CTRL_STATE = (Normal, Focus, Down, Disabled);

Delphi-Quellcode:
TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase);


CTRL_STATE = 0..3
TReplaceFlags = 0..1

Ich erstelle mir jetzt einen ImageBuffer.

Delphi-Quellcode:
  SetLength(TmpHdc, 3);
  SetLength(hBmp, 3);
  SetLength(hBmpOld, 3);

  Wnd := GetDesktopWindow;
  DC := GetWindowDC(Wnd);

  for IntI := 0 to 3 do
  begin
0..3 ist das jeweilige Bitmap im ImageStrip. (Ich hoffe ihr wist was gemeint ist.)
0 wäre dann normal
1 Focus usw..

Eigentlich korrekt.

Aber wenn ich nun das Programm starte bekomme ich in der Zeile
Delphi-Quellcode:
  Caption := StringReplace(Caption, '&', '', [rfReplaceAll]);


einen AV das seltsame ist in einer ganz anderen Unit die eigentlich nichts mit dieser zu tun hat wo der ImageBuffer erstellt wird.
Die Procedure für den Buffer ist privat deklariert in einer eigenen Classe außerhalb da wo StringReplace den Fehler verursacht.

Ändere ich nun die länge also erhöhe sie mit 1
Delphi-Quellcode:
SetLength(TmpHdc, 4);
SetLength(hBmp, 4);
SetLength(hBmpOld, 4);
Ist das Problem verschwunden.. Warum?
Was hat StringReplace mit der Dimension meines Array zu tun das eigentlich korrekt sein sollte.
Ich habe ja keine 5 sondern nur 4 Bilder aneinanderhängend im ImageStrip.
also 0..3

Also! Was hat StringReplace mit der Dimension meines Array zu tun? Das auch noch Privat in einer ganz anderen Classe definiert ist.

gruss

Zacherl 10. Okt 2016 11:33

AW: StringReplace verursacht AV
 
Delphi-Quellcode:
for IntI := 0 to 3 do
= 4

Klassischer Buffer-Overflow.

SetLength etc. erwartet die Größe des Array und nicht den höchsten Index. Also entweder SetLength(3) und die Schleife von 0..2 oder SetLength(4) und die Schleife von 0..3.

EWeiss 10. Okt 2016 11:45

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Zacherl (Beitrag 1350335)
Delphi-Quellcode:
for IntI := 0 to 3 do
= 4

Klassischer Buffer-Overflow.

SetLength etc. erwartet die Größe des Array und nicht den höchsten Index. Also entweder SetLength(3) und die Schleife von 0..2 oder SetLength(4) und die Schleife von 0..3.

Argg.. Ja du hast recht.
Erklärt aber nicht warum der Fehler in einer anderen Unit bei StringReplace auftritt was eigentlich mit dem Problem nichts zu tun hat.
Und das direkt zweimal einmal in der Form und einmal in einer anderen Unit also überall da wo StringReplace Verwendung findet.

Die Form ist kein Teil meiner DLL.. Sehr komisch oder?

gruss

himitsu 10. Okt 2016 12:11

AW: StringReplace verursacht AV
 
Zitat:

Zitat von EWeiss (Beitrag 1350338)
Die Form ist kein Teil meiner DLL.. Sehr komisch oder?

Weil die ganze Anwendung EINEN gemeinsamen (vituellen) Arbeitsspeicher besitzt und du demnach "irgendwas" in dem Speicher überschreiben kannst, auch was nicht zu deiner DLL gehört.

Damals, als noch ALLE Programme und Windows sich den gesamten Arbeitsspeicher teilten und es nicht getrennt war, da hättest du statt Deinem auch ein fremdes Programm oder gleich das Windows zerschrotten können.


PS: Bei solchen Fehlern kann man sich in den Projektoptionen auch mal die Überlauf- und Bereichsprüfungen aktivieren.

EWeiss 10. Okt 2016 12:20

AW: StringReplace verursacht AV
 
Zitat:

Zitat von himitsu (Beitrag 1350346)
Zitat:

Zitat von EWeiss (Beitrag 1350338)
Die Form ist kein Teil meiner DLL.. Sehr komisch oder?

Weil die ganze Anwendung EINEN gemeinsamen (vituellen) Arbeitsspeicher besitzt und du demnach "irgendwas" in dem Speicher überschreiben kannst, auch was nicht zu deiner DLL gehört.

Damals, als noch ALLE Programme und Windows sich den gesamten Arbeitsspeicher teilten und es nicht getrennt war, da hättest du statt Deinem auch ein fremdes Programm oder gleich das Windows zerschrotten können.


PS: Bei solchen Fehlern kann man sich in den Projektoptionen auch mal die Überlauf- und Bereichsprüfungen aktivieren.

Jup hast recht ;)
Bei StripHotkey trat das Problem aber nicht auf. Warum also bei StringReplace.. LOL

Wie gesagt schon seltsam.

gruss

Fritzew 10. Okt 2016 13:21

AW: StringReplace verursacht AV
 
Code:
Wie gesagt schon seltsam.
Nein ist nicht seltsam. Du schreibst in Speicher herum der Dir nicht gehört.
Da kann alles passieren.

EWeiss 10. Okt 2016 13:29

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Fritzew (Beitrag 1350366)
Code:
Wie gesagt schon seltsam.
Nein ist nicht seltsam. Du schreibst in Speicher herum der Dir nicht gehört.
Da kann alles passieren.

Erklärt aber immer noch nicht warum es ausgerechnet nur bei StringReplace passiert.

gruss

Zacherl 10. Okt 2016 13:42

AW: StringReplace verursacht AV
 
Zitat:

Zitat von EWeiss (Beitrag 1350367)
Zitat:

Zitat von Fritzew (Beitrag 1350366)
Code:
Wie gesagt schon seltsam.
Nein ist nicht seltsam. Du schreibst in Speicher herum der Dir nicht gehört.
Da kann alles passieren.

Erklärt aber immer noch nicht warum es ausgerechnet nur bei StringReplace passiert.

Das ist auch garantiert nicht der Fall. Ob sowas zum Crash führt oder nicht, hängt von tausenden Faktoren ab. Mit der StripHotkey Funktion hast du einfach nur Glück gehabt.

himitsu 10. Okt 2016 14:22

AW: StringReplace verursacht AV
 
Es hätte auch schon in der FOR-Schleife knallen können.
Wenn der zu überschreibende Speicherbereich nicht reserviert ist, oder etwas überschrieben wird, was bereits in der Schleife verwendet wird.

Und ob es später knallt oder nicht, das hängt davon ab was überschrieben wird.

EWeiss 10. Okt 2016 14:34

AW: StringReplace verursacht AV
 
Zitat:

Zitat von himitsu (Beitrag 1350371)
Es hätte auch schon in der FOR-Schleife knallen können.
Wenn der zu überschreibende Speicherbereich nicht reserviert ist, oder etwas überschrieben wird, was bereits in der Schleife verwendet wird.

Und ob es später knallt oder nicht, das hängt davon ab was überschrieben wird.

Das hätte ich verstanden da hier ja auch der Fehler produziert wurde.
Aber der andere Fall bleibt ein Rätzel.

Denn nach dem deaktivieren von StringReplace trat kein Fehler mehr auf.
Zu spekulieren es hätte auch woanders auftreten können ist eine Vermutung wie gesagt nach dem deaktivieren kam kein Fehler mehr.
Er hätte also dann an anderer stelle auftreten müssen wenn man der Behauptung nachgehen würde "Es hätte auch schon"

Zitat:

Und ob es später knallt oder nicht, das hängt davon ab was überschrieben wird.
Und das tut es eben nicht.
Immer nur an der gleichen stelle in Verbindung mit StringReplace.
Überall da wo es Verwendung findet.

Zitat:

Das ist auch garantiert nicht der Fall.
Aber 100% 'tig ;)
Andernfalls erkläre mir mal warum es dann nirgends anders kracht nachdem ich diese Zeile/n deaktiviert habe.

gruss

Fritzew 10. Okt 2016 14:49

AW: StringReplace verursacht AV
 
Du willst es nicht verstehen oder?
Was da gerade im Speicher steht den Du überschreibst ist "Zufall". Zufall aus Deiner Sicht, für den Speichermanager
hat das alles Seine Richtigkeit. In Deiner Konstellation passiert es beim Stringreplace. Wenn Du aber sonst noch was änderst im Code kann der aktuelle Speicher schon wieder ganz anders aussehen.
Dr Fehler ist 100% Deiner und sonst nichts.

EWeiss 10. Okt 2016 14:57

AW: StringReplace verursacht AV
 
Zitat:

Was da gerade im Speicher steht den Du überschreibst ist "Zufall". Zufall aus Deiner Sicht, für den Speichermanager
Tja warum legt man dann nicht alles als Zufall aus?

Ihr wollt nicht verstehen das es Unit übergreifend passiert.
Egal wo ich Stringreplace verwende kracht es das hat nix mit dem Speicher zu tun.

Wenn ich in Unit 1 die länge eines Arrays falsch definiere.

Warum gibt mir dann Unit 3 und Unit 5 nur an den Stellen wo ich Stringreplace verwende einen AV aus?
Was hat das jetzt mit dem Speicher zu tun? Und Zufall ist das schon gar nicht.
Wenn ich nun an gleicher stelle im Code eine andere Funktion verwende passiert nichts.. das soll Zufall sein? Bei nichten.

Und ja wie schon gesagt das Array wird in einer privaten Classe generiert.

gruss

Zacherl 10. Okt 2016 15:40

AW: StringReplace verursacht AV
 
Zitat:

Zitat von EWeiss (Beitrag 1350376)
Zitat:

Was da gerade im Speicher steht den Du überschreibst ist "Zufall". Zufall aus Deiner Sicht, für den Speichermanager
Tja warum legt man dann nicht alles als Zufall aus?

StringReplace erzeugt jedes Mal eine AV bei deiner speziellen Konstellation. Dennoch ist dies Zufall und du kannst nicht vorraussagen, ob andere Funktionen nicht auch zur selben AV führen würden. Wenn du philosophieren willst, dann kannst du natürlich gerne alles als Zufall betrachten, oder eben auch nicht. Könntest du die Position und den Impuls jedes Atoms im Universum feststellen, dann wäre es dir möglich die Zukunft vorrauszusagen. Das dies nicht geht hat Heisenberg bereits bewiesen, aber Zufall ist nunmal trotzdem der Begriff, den man verwendet, wenn ein Ergebnis von einer nicht zu überblickenden Anzahl an Variablen abhängt.

Zitat:

Zitat von EWeiss (Beitrag 1350376)
Ihr wollt nicht verstehen das es Unit übergreifend passiert.

Irrelevant ..

Zitat:

Zitat von EWeiss (Beitrag 1350376)
Und ja wie schon gesagt das Array wird in einer privaten Classe generiert.

Ebenfalls irrelevant ..

Wie schon erklärt wurde, ist es komplett egal in welcher Unit oder Klasse sich dein Code befindet. Letzten Endes steht alles im selben virtuellen Speicherbereich des Prozesses.

Zitat:

Zitat von EWeiss (Beitrag 1350376)
Wenn ich nun an gleicher stelle im Code eine andere Funktion verwende passiert nichts.. das soll Zufall sein? Bei nichten.

Doch! Nehmen wir an StringReplace erzeugt eine AV, wenn an Adresse 1234 die Zahl 1 steht. Normal steht an dieser Adresse 0, aber durch deinen Buffer Overflow schreibst du "zufällig" eine 1 dorthin. Ergebnis: StringReplace crasht. Auf der anderen Seite hast du die StripHotkey Funktion. Diese greift aber gar nicht auf Adresse 1234 zu und funktioniert deshalb trotzdem.

EWeiss 10. Okt 2016 16:29

AW: StringReplace verursacht AV
 
Zitat:

Doch! Nehmen wir an StringReplace erzeugt eine AV, wenn an Adresse 1234 die Zahl 1 steht. Normal steht an dieser Adresse 0, aber durch deinen Buffer Overflow schreibst du "zufällig" eine 1 dorthin. Ergebnis: StringReplace crasht. Auf der anderen Seite hast du die StripHotkey Funktion. Diese greift aber gar nicht auf Adresse 1234 zu und funktioniert deshalb trotzdem.
Ok das ist verständlich von der warte ausgesehen ist es ein Speicherproblem.
War halt nur verstutzt weil es immer nur bei StringReplace auftrat.

gruss

Uwe Raabe 10. Okt 2016 16:46

AW: StringReplace verursacht AV
 
Der Unterschied zwischen StringReplace und StripHotKey ist, daß StripHotKey ausschließlich mit Delete arbeitet und dabei den String im selben Speicherbereich hält, während StringReplace einen neuen String zurück gibt. Danach wird dann der alte String freigegeben - was auch problemlos funktioniert, wenn es denn ein richtiger String ist und nicht per string-Cast aus einem PWideChar entstanden ist.

EWeiss 10. Okt 2016 16:53

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1350402)
Der Unterschied zwischen StringReplace und StripHotKey ist, daß StripHotKey ausschließlich mit Delete arbeitet und dabei den String im selben Speicherbereich hält, während StringReplace einen neuen String zurück gibt. Danach wird dann der alte String freigegeben - was auch problemlos funktioniert, wenn es denn ein richtiger String ist und nicht per string-Cast aus einem PWideChar entstanden ist.

Ist ein WideString.
Das hätte das Problem nicht ausgelöst.

Aber gut ich weis nun bescheid das es kein StringReplace Problem ist.
Danke.

gruss

Fritzew 10. Okt 2016 16:54

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1350402)
wenn es denn ein richtiger String ist und nicht per string-Cast aus einem PWideChar entstanden ist.

Das must Du jetzt aber erklären. Wann führt ein String(pchar) zu einem Problem?

Aviator 10. Okt 2016 17:01

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Fritzew (Beitrag 1350406)
Zitat:

Zitat von Uwe Raabe (Beitrag 1350402)
wenn es denn ein richtiger String ist und nicht per string-Cast aus einem PWideChar entstanden ist.

Das must Du jetzt aber erklären. Wann führt ein String(pchar) zu einem Problem?

Würde mich jetzt auch interessieren. Hatte das Thema auch gerade erst in einem meiner Threads. Und dort wurde bestätigt, dass das kein Problem macht. Siehe den Beitrag von Zacherl.

himitsu 10. Okt 2016 17:18

AW: StringReplace verursacht AV
 
Dein "Zufall":
Delphi-Quellcode:
const
  PositionVonStringReplace = 14346027;
  Gott: array[0..3] of AnsiChar = 'Himi';
var
  MeinSpeicherDenIchGleichÜberschreibenWill: {Pointer}Integer;
begin
  RandSeed := Integer(Gott);

  MeinSpeicherDenIchGleichÜberschreibenWill := Random(999999999); // Zufällige Speicherposition suchen
  if MeinSpeicherDenIchGleichÜberschreibenWill = PositionVonStringReplace then
    ShowMessage('Gleich ist StringReplace kaputt :(');
end;

Rein theoretisch kann neu zu reservierender Speicher überall im RAM landen, genauso wie DLLs nicht immer an selber Stelle liegen müssen, ABER ...

Vorallem Delphi DLLs liegen gern nicht dort, wo sie sollen, denn fast niemand gibt eine ordentliche ImageBaseAddress an, womit fast alle Delphi-DLLs eigentlich an selber Stelle liegen würden und Windows sowieso Diese immer an dererer Stelle laden muß,
aber Windows cached sich gern gepatchte Module und läd die DLLs dann oftmals wieder an selber Sellte, wo sie schonmal geladen wurden. Bzw. wiederverwendet die selben Module, welche bereits in einer anderen Anwendung geladen sind.
FastMM/VirtualAlloc könnte jedesmal beim GetMem was Anderes liefern, aber es reagiert auch gern mal gleich, da das Programm beim Start ja auch jedesmal das Selbe macht.
Auch der ProgrammCode (EXE/DLL/...) liegt im Arbeitsspeicher ... eigentlich sollte der vorm Überschreiben geschützt sein, aber man kann ihn womöglch dennoch überschreiben und jetzt muß nur noch etwas von der Funktion StringReplace überschrieben werden.

Aber ganz genau kann man es letztendlich nur sagen, wenn man DEIN Programm analysiert, was es nun wirklich macht,
also z.B. die letzte falsche Schleife debuggen und gucken ob und was wo überschrieben wurde.

Uwe Raabe 10. Okt 2016 19:06

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Aviator (Beitrag 1350407)
Zitat:

Zitat von Fritzew (Beitrag 1350406)
Das must Du jetzt aber erklären. Wann führt ein String(pchar) zu einem Problem?

Würde mich jetzt auch interessieren. Hatte das Thema auch gerade erst in einem meiner Threads. Und dort wurde bestätigt, dass das kein Problem macht. Siehe den Beitrag von Zacherl.

Ihr habt ja Recht! Ich hatte mich dadurch verleiten lassen, daß der erste Parameter von StringReplace als
Delphi-Quellcode:
const
deklariert ist, aber der Compiler legt dafür eine versteckte, lokale String-Variable an.

EWeiss 10. Okt 2016 19:08

AW: StringReplace verursacht AV
 
Ich habe es nochmal getestet mit meiner CTRL_Hook DLL.
Dort ist ja der Fehler mit der falschen Zuordnung der Array länge.

Dort tritt das Problem nicht auf trotz falscher länge.
Allerdings zeichne ich dort den String auch nicht mit GDI+.

Gut ohne einschalten der Bereichs Prüfung bekomme ich da auch keinen Fehler angezeigt.
Und krachen tut's auch nicht.

Zitat:

Vorallem Delphi DLLs liegen gern nicht dort, wo sie sollen, denn fast niemand gibt eine ordentliche ImageBaseAddress an
Ich gebe zu das ich diese auch nicht ändere sollte das nicht eigentlich automatisch geschehen?
Was bringt mir das diese ändern zu wollen.. bzw.. Von welchen Kriterien ist das abhängig.
Es muss ja irgendeinen sinn machen das diese von Borland oder wem auch immer mal festgelegt worden ist.

gruss

Zacherl 10. Okt 2016 19:49

AW: StringReplace verursacht AV
 
Zitat:

Zitat von EWeiss (Beitrag 1350415)
Ich gebe zu das ich diese auch nicht ändere sollte das nicht eigentlich automatisch geschehen?
Was bringt mir das diese ändern zu wollen.. bzw.. Von welchen Kriterien ist das abhängig.
Es muss ja irgendeinen sinn machen das diese von Borland oder wem auch immer mal festgelegt worden ist.

Nene, macht ab Win8 keinen Unterschied mehr, da die Dlls eh durch ASLR bei jedem Start an zufällige Adressen relocated werden.

EWeiss 10. Okt 2016 20:45

AW: StringReplace verursacht AV
 
Zitat:

Zitat von Zacherl (Beitrag 1350418)
Zitat:

Zitat von EWeiss (Beitrag 1350415)
Ich gebe zu das ich diese auch nicht ändere sollte das nicht eigentlich automatisch geschehen?
Was bringt mir das diese ändern zu wollen.. bzw.. Von welchen Kriterien ist das abhängig.
Es muss ja irgendeinen sinn machen das diese von Borland oder wem auch immer mal festgelegt worden ist.

Nene, macht ab Win8 keinen Unterschied mehr, da die Dlls eh durch ASLR bei jedem Start an zufällige Adressen relocated werden.

Ok.. Hab zwar Win7 aber damit bisher keine Probleme gehabt denke das ich die eingestellte Standard Adresse weiterhin verwende.

gruss

Luckie 11. Okt 2016 00:12

AW: StringReplace verursacht AV
 
Beispiel. Wir haben die aufeinander folgenden Adressen 1, 2, 3, 4. Die Exe wird immer an Adresse 1 geladen, da Exe-Dateien standardmäßig die ImagebaseAddress 1 haben. DLLs haben standardmäßig die ImageBaseAddress 2. Dahin wird auch die erste DLL geladen. Wird jetzt eine zweite DLL geladen (standard ImageBaseAddress 2), kann sie nicht mehr an die Standardadresse geladen werden, denn da befindet sich ja schon die erste DLL. Also wird sie an Adresse 3 geladen. Jetzt beziehen sich aber alle Sprünge im Code auf die Adresse 2. Das hat zur Folge dass alle Sprungadressen in der DLL, wenn sie geladen wird neu berechnet werden müssen. Dazu existiert in der DLl der sogenannte Realocation Table mit den relativen Sprungadressen zur standard ImagebaseAddress. Auf Basis des Realocation Tables werden jetzt die Sprungadressen neu berechnet. Gibt man jetzt eine andere ImageBaseAddress an, entfällt diese neu Berechnung. Theoretisch. Denn man kann sich nicht sicher sein, ob nicht auch an der anderen ImageBaseAddress sich schon eine DLL befindet.

Es gibt Programme, die den Realocation Table entfernen, um die Exe zu verkleinern. (Gibt sich aber nicht viel.) Exe-Dateien funktionieren dann immer noch, da sie standardmäßig immer an Adresse 1 geladen werden. Es müssen also keine Sprünge neu berechnet werden. Bei DLLs sollte man den Realocation Table aber nicht entfernen, da er gegebenenfalls benötigt wird, wenn die DLL nicht an die vorgegebene Adresse geladen werden kann.

http://michael-puff.de/Programmierun...eAddress.shtml

himitsu 11. Okt 2016 03:36

AW: StringReplace verursacht AV
 
Jo, die EXE ist halt das Erste, was geladen wird, drum ist ihre ImageBaseAddress eigentlich immer frei. (außer man setzt 'ne EXE-Komporimierung/Verschlüsselung ein, wo sich 'ne MiniEXE vorschaltet, die dann die eigentliche Anwendung nachlädt und entpackt/entschlüsselt)

Noch schöner ist aber das Ergebnis der Address-Reallocation.
Standardmäßig sind die Code- und Data-Segmente der DLL/EXE nur im RAM verlinkt (MemoryMappedFile auf die Datei), aber wird im Code rumgeschrieben, z.B. weil überall die Zeiger angepasst werden müssen, dann wird der umgebende Speicherbereich (je mindestens 4KB) in den RAM kopiert (CopyOnWrite) und das dann verändert.
Also belegt das Programm dann auch noch mehr physischen RAM. (zum Glück haben wir ja immer mehr RAM zur Verfügung)
Und noch besser wird das, wenn Windows durch ASLR für jede Anwendungsinstanz einen andere Position wählt, dann kann mindestens der Codeteil nicht mehr geshared werden, da jeder eine andere ImageBase und somit "anders" überschriebenen Code benötigt.

Aber eigentlich ist ASLR halt ein Schutz vor Schadprogrammen (Viren/Trojaner/Würmer) und selbst Hacker haben es bei Spielen bissl schwerer, um z.B. in die Variable "SoVielGoldHabeIch" eine 2.000.000.000 reinzuschreiben. :stupid:
Denn sie können nicht "blind" auf eine bestimmte Speicheradresse zugreifen (ImageBase + Offset = Variable/Konstante/Programmcode), da die Adressen nicht statisch ist.
Man konnte früher z.B. im Browser/Acrobat/Flash/... einen Bug geziehlt ausnutzen, indem man z.B. einen Bufferoferflow ausnutzte und den "zufällig" fast immer dahinterligenden Code/Variablen "ausversehn" überschieb. Und wenn man das gut getroffen hatte, dann wurde später der so eingeschleußte Code heimlich ausgeführt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:09 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