![]() |
StringReplace verursacht AV
Delphi-Quellcode:
txt Rückgabe ist "Ö&ffnen"
var
Txt: PWideChar; tmpTxt: WideString; Txt := PWideChar(SkinEngine.GetCTLText(PDis.hwndItem)); tmpTxt := StringReplace(string(Txt), '&','', [rfReplaceAll]); 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 |
AW: StringReplace verursacht AV
Ich habe bei mir mal folgendes getestet und ich habe keine AV bekommen:
Delphi-Quellcode:
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.
var
Txt: PWideChar; tmpTxt: WideString; begin Txt := 'Ö&ffnen'; tmpTxt := StringReplace(string(Txt), '&', '', [rfReplaceAll]); end; |
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. ![]() |
AW: StringReplace verursacht AV
Frage neben bei:
was macht StripHotkey anders als StringReplace? |
AW: StringReplace verursacht AV
Zitat:
Grüße Dalai |
AW: StringReplace verursacht AV
Aber warum nur? :? Woher soll der Nutzer denn wissen, welches der Hotkey für die Schaltfläche ist?
|
AW: StringReplace verursacht AV
Und es lässt geqoutede Hotkeys dequoted zurück.
Delphi-Quellcode:
&Hallo && Tschüss
|
AW: StringReplace verursacht AV
Zitat:
Ohne das entfernen steht auf meinen Button der Text so "Ö&ffnen" Warum GDI Plus das nicht erkennt da fragst du mich zu viel. gruss |
AW: StringReplace verursacht AV
Zitat:
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 |
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:
0..3 ist das jeweilige Bitmap im ImageStrip. (Ich hoffe ihr wist was gemeint ist.)
SetLength(TmpHdc, 3);
SetLength(hBmp, 3); SetLength(hBmpOld, 3); Wnd := GetDesktopWindow; DC := GetWindowDC(Wnd); for IntI := 0 to 3 do begin 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:
Ist das Problem verschwunden.. Warum?
SetLength(TmpHdc, 4);
SetLength(hBmp, 4); SetLength(hBmpOld, 4); 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 |
AW: StringReplace verursacht AV
Delphi-Quellcode:
= 4
for IntI := 0 to 3 do
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. |
AW: StringReplace verursacht AV
Zitat:
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 |
AW: StringReplace verursacht AV
Zitat:
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. |
AW: StringReplace verursacht AV
Zitat:
Bei StripHotkey trat das Problem aber nicht auf. Warum also bei StringReplace.. LOL Wie gesagt schon seltsam. gruss |
AW: StringReplace verursacht AV
Code:
Nein ist nicht seltsam. Du schreibst in Speicher herum der Dir nicht gehört.
Wie gesagt schon seltsam.
Da kann alles passieren. |
AW: StringReplace verursacht AV
Zitat:
gruss |
AW: StringReplace verursacht AV
Zitat:
|
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. |
AW: StringReplace verursacht AV
Zitat:
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:
Immer nur an der gleichen stelle in Verbindung mit StringReplace. Überall da wo es Verwendung findet. Zitat:
Andernfalls erkläre mir mal warum es dann nirgends anders kracht nachdem ich diese Zeile/n deaktiviert habe. gruss |
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. |
AW: StringReplace verursacht AV
Zitat:
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 |
AW: StringReplace verursacht AV
Zitat:
Zitat:
Zitat:
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:
|
AW: StringReplace verursacht AV
Zitat:
War halt nur verstutzt weil es immer nur bei StringReplace auftrat. gruss |
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.
|
AW: StringReplace verursacht AV
Zitat:
Das hätte das Problem nicht ausgelöst. Aber gut ich weis nun bescheid das es kein StringReplace Problem ist. Danke. gruss |
AW: StringReplace verursacht AV
Zitat:
|
AW: StringReplace verursacht AV
Zitat:
![]() |
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. |
AW: StringReplace verursacht AV
Zitat:
Delphi-Quellcode:
deklariert ist, aber der Compiler legt dafür eine versteckte, lokale String-Variable an.
const
|
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:
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 |
AW: StringReplace verursacht AV
Zitat:
|
AW: StringReplace verursacht AV
Zitat:
gruss |
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. ![]() |
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 13:44 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz