Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   RawByteString in Exe modifizieren (https://www.delphipraxis.net/203328-rawbytestring-exe-modifizieren.html)

DieDolly 6. Feb 2020 20:59

RawByteString in Exe modifizieren
 
Ich komme leider nicht weiter. Ich habe eine ausführbare Datei die an irgendeiner Stelle einen const RawByteString deklariert hat.
Den Inhalt dieses Strings kann ich auch wiederfinden, wenn ich die Exedatei in ein Bytes Array schreibe und dann mit TEncoding.ANSI.GetString() in eine Txt-Datei schreibe.

Das Problem ist aber, dass ich es nicht schaffe diesen String richtig zu ersetzen. Eine Exe-Datei 1 soll diesen RawByteString in der Exe-Datei 2 ersetzen.
Der String wird ersetzt aber der neue String, also der, der durch den alten ersetzt wird, wird auch an den Anfang der Datei geschrieben und ich habe keine Ahnung warum.

Delphi-Quellcode:
 const MyRawByte: RawByteString = '___ABCD';

 RawByteTmp:= MyRawByte;
 RawBytePos := Pos(string(RawByteTmp), StringOf(ByteStream.Bytes) + 3; // 3 = die 3 Unterstriche. Die UNterstriche bleiben bestehen. Nur das ABC wird ersetzt.

 // Das Ersetzen passiert hier
 ReplaceWith := 'EFGH';
 Move(ReplaceWith[1], ByteStream.Bytes[RawBytePos - 1], 4); // 4 = die Länge des Strings der ersetzt wird, hier ABCD
 ByteStream.SaveToFile('newfile.exe');
Das funktioniert soweit ja auch und ABCD wird durch DEFG in der fertigen Exe ersetzt. Aber warum wird EFGH auch an Position 0 der Datei geschrieben?

TiGü 7. Feb 2020 07:52

AW: RawByteString in Exe modifizieren
 
Bau uns doch bitte eine Projektgruppe mit zwei Konsolenprojekten A und B, in dem B dann entsprechend die EXE A modifiziert.

himitsu 7. Feb 2020 08:48

AW: RawByteString in Exe modifizieren
 
Was ist ReplaceWith für ein Typ? (ich hoffe doch auch irgendeiner ANSI-Typen)

Und im POS würde ich den String nicht casten, denn dann bekommst du die Position im Unicode-String, anstatt im Original, auch wenn RawByteString zumindestens CodrpageConvertierungen umgewandelt werden sollty, also die Ord(Char) sollten gleich bleiben und demnach die Indize theoretisch gliech bleiben.


Besser über die String-Helper gehen, denn dort sind Indize immer 0-basiert.
Bei den Strings selber liegt Low(string) normal bei 1, aber in den NextGen-Compilern (Android, iOS, ...) fängt der String standardmäßig bei 0 an. (so wie normale Arrays)

freimatz 7. Feb 2020 10:19

AW: RawByteString in Exe modifizieren
 
Weil bei Pos die Fehlerbehandlung fehlt?

himitsu 7. Feb 2020 13:03

AW: RawByteString in Exe modifizieren
 
Abgesehn davon:
Warum kein RessourceString?

Delphi-Quellcode:
resourcestring
  deineKonstante = 'asdfasdfsda'; // wird über einen "zufälligen" String-Index in den Ressourcen gespeichert
bei Verwendung dieser Konstante wird intern LoadString vewendet

oder über den Ressourcen-Manager von Delphi (in die *.res jedes Projekte)
oder über eine eigene RC/RES-Datei
> hier jeweils über MSDN-Library durchsuchenLoadString bzw. MSDN-Library durchsuchenLoadResource/MSDN-Library durchsuchenFindResource/... den String laden



und dann entweder selber mit MSDN-Library durchsuchenUpdateResource oder über einen der vielen Resource-Editoren (teilweise lassen sie sich auch via Parameter steuern) diese Ressorce ändern, ohne bösswillig den "Programmcode" zu verändern.

und sowas lässt sich auch zur Laufzeit anpassen
* z.B. durch hooken der Load-Funktion (wird z.B. von einigen Lokalisierungskomponenten verwendet, um eine andere Sprache zu laden)
* oder über zusätzliche Dateien (z.B. siehe die .DE-Dateien neben den .BPL der Delphi-Packages)

freimatz 7. Feb 2020 13:07

AW: RawByteString in Exe modifizieren
 
Warum? Vermutlich weil die "Exe-Datei 2" gar nicht von ihm ist.

himitsu 7. Feb 2020 13:54

AW: RawByteString in Exe modifizieren
 
Nee nee, die Liebe Dolly macht sowas doch nicht. :zwinker:
Fremde Dateien hacken ist aber böse.
(vor allem wenn es gegen die Lizenzbedingen verstoßen könnte)



Sowas wie TEncoding.ANSI.xyz ist sowieso das Schlimmste, was man einer Binärdatei antun kann.

Wenn schon mit Unicode rumgepfuscht wird, dann besser ohne Zeichenübersetzungen.
Delphi-Quellcode:
E := TMBCSEncoding.Create($FFFF, 0, 0); // $FFFF ist auch die CodePage, welche der RawByteString benutzt
E.GetString();
Ansonsten gibt es viele Wege, um Binärdaten auch binär zu behandeln.
Delphi-Quellcode:
var R: RawByteString;
M := TFileStream.Create('.\file.exe');
SetLength(R, M.Size);
M.ReadBuffer(R[1], M.Size);
...
Und dann besser niemals mit Unicode-Funktionen darauf zugreigen
Pos und Copy gibt es standardmäßig überladen, auch als "ANSI"-Version (für AnsiString und seine Verwandten ala RawByteString)
und ansonsten gibt es auch noch die Unit AnsiStrings.

--

M := TMemoryStream.Create;
M.LoadFromFile('.\file.exe'));
...
M.Memory // ein Pointer auf den Dateiinhalt
...
M.SaveToFile('.\newfile.exe'));
M.Free;

--

B := TFile.ReadAllBytes('file');
... // B = ein Byte-Array
TFile.WriteAllBytes('newfile', B);

--

R := TFile.OpenText('file'); // bzw. direkt TStreamReader.Create
W := TFile.CreateText('file'); // bzw. TStreamWriter.Create
// geht nicht, weil hier der Encoding-Parameter fehlt,
// aber

E := TMBCSEncoding.Create($FFFF, 0, 0);
S := TFile.ReadAllText('file', E);
...
E.Free;

uvm.
Leider gibt es Pos/PosEx unverständlicher Weise nicht für normale Arrays.
Es gibt StrPos-Funktionen für PAnsiChar, die man auf Pointer/Arrays loslassen könnte, aber bei der ersten #0 brechen die ab.
Also bleibt nur selber was basteln.

Aber so oder so ist es immer besser Binärdaten niemals in Text-Strings zu speichern
und stattdessen "ordentlich" mit Streams oder Pointer bzw. ByteArrays zu arbeiten.

DieDolly 7. Feb 2020 17:16

AW: RawByteString in Exe modifizieren
 
Ich sehe gerade alles hat jetzt seine Richtigkeit. Der Fehler lag an der Ausgabe. Die Ausgabe war nur für mich. Ich hab mich schon gewundert, wo die 4 zusätzlichen KB herkamen!
Zur Klarstellung. Ich bearbeite hier ausschließlich meine eigenen Dateien!

Zitat:

E := TMBCSEncoding.Create($FFFF, 0, 0); // $FFFF ist auch die CodePage, welche der RawByteString benutzt
E.GetString();
Wenn ich das so nutze, erhalte ich EEncodingError. Der Fehler kommt, sobald ich E := TMBCSEncoding.Create($FFFF, 0, 0); irgendwo schreibe.

himitsu 7. Feb 2020 18:42

AW: RawByteString in Exe modifizieren
 
Mist, Windows weigert sich. (früher ging das mal :oops:)
Das MSDN-Library durchsuchenGetCPInfo im Constructor zickt rum, aber die anschließenden MSDN-Library durchsuchenMultiByteToWideChar arbeiten problemlos mit $FFFF.

Ich sehe in der Liste aber grade keine passenden CodePage https://docs.microsoft.com/de-de/win...ge-identifiers

Nja, man kann sich TEncoding auch selbst ableiten und dort eine 1-1-Übersetzung zusammenbauen.
Oder TMBCSEncoding erst mit einer anderen CodePage erstellen und anschließend böswillig die CodePage überschreiben. :stupid:

DieDolly 8. Feb 2020 16:21

AW: RawByteString in Exe modifizieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt ein Teilergebnis.
Es muss wohl irgendwas mit
Delphi-Quellcode:
str := TEncoding.ANSI.GetString(ByteStream.Bytes) ...
zu tun haben. Auf einem System mit türkischem Windows, aber englishcer Benutzeroberfläche kommt da nicht das raus, was rauskommen soll. Ich kopiere eine bestimmte Anzahl Zeichen von einer Position A an bis zu einer Position B. Das funktioniert in 99% der Fälle einwandfrei nur hier scheinbar nicht. Es handelt sich übrigens um einen Kunden-PC.

Normalerweise soll eine normale Zeichenkette mit Zeichen von a bis z und 0 bis 9 rauskommen. Länge, sagen wir mal, 48 Zeichen. Ist aber egal wie lang.
Auf dem Kunden-PC kommt das raus, was im Bild zu sehen ist.

Hilft hier vielleicht ASCII statt ANSI weiter? Ich kann das Problem leider nicht reproduzieren. Der Kunde sagt auch selber, dass es auf dem einen PC auftaucht und auf dem anderen nicht.
Ich habe das Problem jetzt aber durch andere, benutzerfreundliche Mittel beseitigt.

himitsu 8. Feb 2020 22:12

AW: RawByteString in Exe modifizieren
 
Zitat:

Zitat von himitsu (Beitrag 1456926)
Sowas wie TEncoding.ANSI.xyz ist sowieso das Schlimmste, was man einer Binärdatei antun kann.

Was soll man dazu noch weiteres sagen?

ASCII?

Nee, Binärdateien gehören binär behandelt ... jegliche Behandlung mit irgendwelche Texten und vor allem irgendwelches Umrechnen/Umcodieren in Unicode über Codepages hat hier einfach garnichts zu suchen.

ANSI ist bei uns und den Amis zugfällig 1 Byte pro Zeichen, aber das ist nicht überall so. (nur leider erfinden gerade die dann sowas Krankes, wie Binärdaten in Textstrings)
PS: UTF-8 ist ein gutes Beispiel dafür, was jeder verstehen können dürfte, wo also ein Index im Unicode nicht die selbe Position ist, wie in der Codierung.

DieDolly 8. Feb 2020 22:20

AW: RawByteString in Exe modifizieren
 
Zitat:

Was soll man dazu noch weiteres sagen?
Irgendwie muss man die paar Bytes die man von Position X bis Y (maximal 48 wie gesagt, nicht die ganze Datei) ausliest ja lesbar machen.

Zitat:

ANSI ist bei uns und den Amis zugfällig 1 Byte pro Zeichen
Die Bytes die ich auslesen und umwandeln möchte ergeben mit absoluter Sicherheit immer Zeichen A bis Z und 0 bis 9.
Welche Möglichkeit gibt es denn sonst noch diese paar Bytes lesbar zu machen? Das ergeben am Ende ziemlich sicher rund 48 Zeichen.
Sonst hätte ich noch StringOf aus den System.SysUtils im Angebot. Ich denke das ist besser als selbst mit TEncoding zu spielen.

himitsu 9. Feb 2020 17:41

AW: RawByteString in Exe modifizieren
 
ASCII, also das Ursprüngliche hat nur 7 Bit
EASCII (das was aktuell alle als ASCII bezeichnen) ist auch nur eine der vielen 8-Bit-Codepages.

und Default = ANSI

Zitat:

Zitat von DieDolly (Beitrag 1456995)
Die Bytes die ich auslesen und umwandeln möchte ergeben mit absoluter Sicherheit immer Zeichen A bis Z und 0 bis 9.

Aber der Rest nicht, somit ist es unmölich damit sicher die Position im Unicode zu bestimmen und dann 1:1 auf die Bytes der Datei umzurechnen.

Also egal was du machst, sobald auch nur irgendwie etwas mit Unicode im Spiel ist, war es dass, also im Prinzip ist alles mit Codepage und Encoding der falsche Weg.
Man kann zwar den Inhalt einer Datei 1:1 im einen AnsiString alle AnsiString, RawByteString usw. kopieren (SetLength+Stream.Read) und dann ANSI-Pos und Dergleichgen benutzen, aber der kleinste Fehler und schon gibt es massivr Probleme, sobald auch nur irgendwie ausversehn eine Umcodierung der Zeichen alles durcheinander bringt.

Darum ist es immer besser direkt bei ByteArrays bzw. ByteStreams zu bleiben.

DieDolly 9. Feb 2020 19:18

AW: RawByteString in Exe modifizieren
 
Zitat:

Darum ist es immer besser direkt bei ByteArrays bzw. ByteStreams zu bleiben.
95% dieses Codes sind auf Basis von ByteStream und alles ist gut. Ich benutze StringOf(bytes) und danach Pos() um an die Positition von ein paar bestimmten Zeichen zu kommen. Das funktioniert auch auf allen Systemen scheinbar. Dann lese ich von dieser Position aus 48 weitere Zeichen (Bytes) mit ByteStream.Read aus aus und forme es am Ende in einen String um.
Das scheint jetzt augenscheinlich auch auf dem Problem-Windows zu funktionieren.

Delphi-Quellcode:
ByteStream.Position := RawBytePos - 1;
ByteStream.Read(ByteStream.Bytes[0], 48);
Str := StringOf(ByteStream.Bytes);
Das Ergebnis ist das was ich in der Exe suche.
Ist hier StrOf() oder RawByteString() besser? Dass TEncoding.ANSI wegfällt ist klar.


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