![]() |
Hexwert in Binärdatei suchen und Position ermitteln
Hallo Leute,
ich würde gern in einer binär Datei einen vordefinierten Hexwert suchen (6 bytes) und mir die Position davon anzeigen lassen. Da mir hier letztens so gut geholfen wurde, wollte ich wieder fragen ob ich auf dem richtigen Weg bin. Hier mal die Theorie: 1. eine Funktion schreiben die Hexwerte in Zeichen umwandelt und in einen String übergibt 2. Binärdatei in einen Stream laden (Tmemorystream oder Tfilestream) 3. Mit pos im Stream nach dem String suchen Wäre das die richtige Herangehensweise? Oder bin ich da auf dem Holzweg? Meine Delphiversion ist die Version 7. Vielen Dank im Voraus. fringer |
AW: Hexwert in Binärdatei suchen und Position ermitteln
![]() also das Binäre erstmal nach Text umwwandeln. (hier alles nach HEX und du kannst wirklich nach einem HexWert suchen, aber aufpassen wegen halben Werten, also nur ungerade Positionen sind gültig) und seit Delphi 2009 auch noch aufpassen wegen Unicode (2 Byte pro Zeichen) oder Hex nach Binär umwandeln, für den Vergleich Byteweise oder nach Typen wie Byte, Word, LongWord/Integer oder Int64 casten oder ![]() und dann mit einer Schleife in den Daten suchen (alles Stück für Stück vergleichen) oder ![]() |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Ich gehe so vor
Datei Öffnen und einen Puffer damit füllen was auch immer ich suchen will nach hexformat umwandeln in einer loop den puffer[X]+puffer[X]+puffer[X] usw durchforsten lassen, falls ein teilerfolg am ende vom puffer auftritt, beim nachladen des puffers da weitermachen puffer mit neuen daten nachladen bis dateiende und immer dateiposition merken auf diese Weise kontrolliere ich Signaturen die dynamische Positionen haben. |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Hi!
Also nach Hex-Werten kann man nicht suchen... "Hexwerte" ist kein Type... Du kannst nach Bytes oder auch nach Zeichen suchen... Und Du kannst sicherlich Hexwerte in Zeichen $FF -> '$'+'F'+'F' umwandeln... Bei einem Unicode String hast Du dann im Speicher aber '$'+#0+'F'+#0+'F'+#0 stehen. Bei 6 Hexwerten ist die Frage der Reihenfolge... Der Wert(Word) $AABB steht im Speicher $BB,$AA. Liegen Deine "Hexwerte" in der gleichen Reihenfolge, oder willst Du nach $1A2B3C4D5E6F als Wert suchen? Naja und dann die Suche ist ganz einfach... Irgendwo musst Du die Werte in einen Puffer laden, falls die Datei zu groß ist um komplett in den Speicher zu passen, ansonsten einfach bei einem TMemoryStream Mit Memory^ auf die Bytes zugreifen und vergleichen... Wenn Du die Fragen beantwortest, können wir Dir sicherlich besser helfen! Mavarik |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Hallo,
vielen Dank für die bisherigen Tipps und Infos. Bisher habe ich es noch nicht geschafft zu einer Lösung zu kommen. Bin aber weiter dran ;) Wie ich schon in diesem Thread ![]() vor über 10 Jahren etwas programmiert und viele Dinge die ihr Profis täglich macht fallen mir da doch schwer. Lange rede kurzer Sinn, hier noch mal meine Problematik: Ich habe eine xyz.dat Datei, in dieser Datei muss ich eine Zeichenfolge suchen lassen und mir davon die Anfangs-Position ausgeben lassen. Die Zeichenkette wäre in folgenden Formaten diese: Ascii/Ansi = XPR0�( Decimal = 88 80 82 48 0 40 Binary = 01011000 01010000 01010010 00110000 00000000 00101000 Hex = 58 50 52 30 00 28 Meine Datei habe ich in ein TMemorystream geladen. Dann habe ich versucht die Zeichenfolge in ein Array (Ansistring) zu laden. Aber so richtig klappt das alles noch nicht. Und wichtig ist mir vor allem die Position in der Datei damit ich den Memorystream von dieser Stelle aus weiterverarbeiten kann. Wenn ihr mir da wieder mit etwas Pseudocode unter die Arme greifen könntet wäre das klasse. Vielen Dank schon mal. fringer |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Wenn du die Datei komplett in den Speicher laden kannst (ungetestet):
Delphi-Quellcode:
function Search(_Stream: TStream): Boolean; var data: array of Byte; search: array of Byte; i: int64; j: int64; fnd: Boolean; begin // daten sind im stream _Stream.Position := 0; Result := False; if _Stream.Size = 0 then Exit; // --> SetLength(data, _Stream.Size); if _Stream.read(data[0], _Stream.Size) <> _Stream.size then raise Exception.Create('Fehler beim Lesen der Daten'); SetLength(search, 6); search[0] := $58; search[1] := $50; search[2] := $52; search[3] := $30; search[4] := $00; search[5] := $28; for i := Low(Data) to High(Data) - Length(search) + 1 do begin fnd := True; for j := Low(search) to High(Search) do begin if data[i] <> search[j] then begin fnd := False; break; // --> end; end; if fnd then begin Result := True; _Stream.Position := i; Exit; // -> end; end; end; |
AW: Hexwert in Binärdatei suchen und Position ermitteln
@brechi
vielen Dank für deine Funktion. Ich habe diese mal in mein Programm eingearbeitet. Beim ausführen bekomme ich jedoch einen FOR-Schleifen Fehler "FOR Schleifenvariable muss vom ordinalen Typ sein), daher habe ich aus den Variablen "i" und "j" den Datentyp "integer" anstelle von "int64" gemacht. Damit läuft die For-Schleife zwar aber die Funktion gibt nicht mehr das gewünschte Ergebnis aus. Und ich muss gestehen das ich die Funktion noch nicht komplett verstanden habe. Wäre eine Erläuterung möglich? Herzlichen Dank und noch einen schönen Sonntag. fringer |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Im Prinzip läuft alles auf einen Byte-Vergleich hinaus.
Delphi-Quellcode:
Die innere Schleife kann man z.B. durch CompareMemory ersetzen
var
Daten, Suche: TBytes; i, i2: Integer; B: Boolean; for i := 0 to Hight(Daten) - High(Suche) do // for i := 0 to Hight(Daten) - (Length(Suche) - 1) do for i2 := 0 to High(Suche) do if Daten[i] <> Suche[i2] then Break else if i2 = High(Suche) then Gefunden(i); und noch an anderen Stellen bissl optimieren, aber im Prinzip macht so ein Such-Code immer das Gleiche.
Delphi-Quellcode:
for i := 0 to Hight(Daten) - High(Suche) do begin
{$REGION 'umgedrehte Suchlogik sie Antwort #6'} B := False; for i2 := 0 to High(Suche) do if Daten[i] <> Suche[i2] then Break else if i2 = High(Suche) then B := True; {$ENDREGION} if B then Gefunden(i); end;
Delphi-Quellcode:
for i := 0 to Hight(Daten) - High(Suche) do
if CompareMemory(@Daten[i], @Suche[0], Length(Suche)) then Gefunden(i); |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Delphi-Quellcode:
Was für ein Fehler?
if _Stream.read(data[0], _Stream.Size) <> _Stream.size then
raise Exception.Create('Fehler beim Lesen der Daten');
Delphi-Quellcode:
>
_Stream.ReadBuffer(data[0], _Stream.Size);
![]() ![]() |
AW: Hexwert in Binärdatei suchen und Position ermitteln
Hmm..
Hab das mal etwas zusammengefast und für Streams verallgemeinert:
Delphi-Quellcode:
Als Beispiel einfach eine Verwendung mit einem StringStream, kann aber auch ein FileStream sein, so dass nicht die ganze Datei in den Speicher geladen werden muss..
function FindPosInStream(AStream : TStream; AData : Array of Byte):int64;
var P : int64; B : Array of Byte; L : integer; begin Result := -1; // Rückgabe -1, wenn nicht vorhanden!! L := length(AData); SetLength(B,L); while (Result = -1) do begin // Suche beginnt an aktueller Streamposition! P := AStream.Position; // Gleiche Anzahl Bytes einlesen, wie gesucht wird // Wenn keine/ungenügende Bytes verfügbar, dann ist der Suchstring nicht mehr möglich if AStream.Read(B[0],L) = L then begin // Absolute Vergleich if CompareMem(@B[0], @AData[0],L) then begin // Gefunden Result := P; Break; end; // zurück zur nächsten Startposition im Stream AStream.Position := P+1; end else Break; end; end; procedure TForm1.ButtonSearchClick(Sender: TObject); var S : TStringStream; i : integer; A : array of Byte; Data : AnsiString; begin Data := EditSearch.Text; SetLength(A,Length(Data)); For i := 0 to Length(Data)-1 do A[i] := Ord(Data[i+1]); S := TStringStream.Create(Memo1.Lines.Text); try S.Position := 0; EditPos.Text := IntToStr( FindPosInStream(S,A)); finally S.Free; end; end; Es ist nicht auf Speed optimiert, da dann immer die Daten in größeren Blöcken gelesen würden und Teile davon mit den Suchdaten verglichen werden würden. (Erstellt mit D6, somit Memo mit AnsiStrings) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:36 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