AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Hexwert in Binärdatei suchen und Position ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Hexwert in Binärdatei suchen und Position ermitteln

Ein Thema von fringer · begonnen am 2. Mär 2018 · letzter Beitrag vom 7. Mär 2018
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.069 Beiträge
 
Delphi 12 Athens
 
#11

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 4. Mär 2018, 13:10
Bei TMemoryStream kann man auch direkt auf die Daten zugreifen.
Delphi-Referenz durchsuchenTMemoryStream.Memory
Und in diesem Fall hilft auch noch ein kleiner Cast:
Delphi-Quellcode:
PByte(MemoryStream.Memory)
PByte(MemoryStream.Memory)[i] // die Dereferenzierung ist implizit, aber man kann auch PByte(MemoryStream.Memory)^[i]
(PByte(MemoryStream.Memory) + i)^ // oder mit Pointer-Arithmetic
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
969 Beiträge
 
Delphi 6 Professional
 
#12

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 4. Mär 2018, 13:31
Hmm..


ich würde gern in einer binär Datei einen vordefinierten Hexwert suchen (6 bytes) und mir die Position
davon anzeigen lassen.
Würde hier nicht TFileStream besser sein, da mann dann nicht die ganze, eventuell GB große Datei zunächst in einen MemoryStream oder Buffer laden müsste?

Bei kleinen zu durchsuchenden Daten (eventuell schon direkt im Speicher vorhanden) würde die direkte Suche im Memory mit MemoryStream natürlich deutlich performanter sein, da mann dann ohne Read und Positionierung direkt den Speicher per Pointer an CompareMem gegen kann...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.069 Beiträge
 
Delphi 12 Athens
 
#13

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 4. Mär 2018, 14:28
Alles im Speicher ist einfacher. (mehr als 500 MB werden seine Dateien wohl nicht sein)
Beim stückchenweisem Einlesen muß man beachten, dass Übergreifend gesucht werden muß, also eine Hälfte der Suchdaten kann in einem Block sein und der Rest im nachfolgenden Block.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#14

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 4. Mär 2018, 21:10
Ich hab da was uraltes ausgegraben was mit Ansichar von #0 .. #255 umgehen kann.
Delphi-Quellcode:
(***************************************************************************)
(* Stringsuche in Anlehnung an Boyer Moore                                 *)
(***************************************************************************)
(* 1.0  Adaption an 32-Bit Pascal                                2000/06/23*)
(***************************************************************************)
unit boymoore32;

interface
{Alle String-Typen sind klassische Pascal-Strings: Array [0..255] of char!}
{Dies entspricht unter Delphi dem shortstring mit der Definition ist man auf der sicheren Seite}
{Der Array in dem gesucht wird ist 64K groß (noch) }
{ Die "alten" Typen word etc werden noch an 32-Bit Gepflogenheiten angepasst}
{ !!!! Es gibt nur einen Sucharray   !!!           }
type
  sucharraytyp= packed array [0..255] of byte; {packed um Lücken zu vermeiden}
var
  sucharray : sucharraytyp;

function INITSUCHARR(suchstring:shortstring):boolean;
(*  die 16-Bit version arbeitet mit 16Bit Wörtern
function FINDESTR(sptr:pointer;slang:word;suchstring:shortstring):word;
   die 32-Bit Version mit 32-Bit Integern*)


function FINDESTR(bptr:pointer;blang:integer;suchstring:shortstring):integer;

implementation
function INITSUCHARR(suchstring:shortstring):boolean;
var
  j : word;
begin
  {----- jedem ASCII-Wert die Länge des suchstr zuweisen ------------}
  fillchar(sucharray,sizeof(sucharray),length(suchstring));
  {---- umgekehrt indizieren n...1 !!!!! ----------------------------}
  if length(suchstring)>0 then begin
    INITSUCHARR:=true;
    for j:=1 to length(suchstring) do begin
      sucharray[byte(suchstring[j])]:=length(suchstring)-j;
      sucharray[byte(suchstring[j])]:=sucharray[byte(suchstring[j])];
    end;
  end
  else
    INITSUCHARR:=false;
end;

function FINDESTR(bptr:pointer;blang:integer;suchstring:shortstring):integer;
type
  srt =packed array [1..$FFFF] of byte;
  srtc=packed array [1..$FFFF] of char; { fürs debugging }
var
  bi : integer; { Index des Source Integer für 32Bit!}
  ssi : integer; { Index Suchstr    Integer für 32Bit!}
  ssl : integer; { Länge suchstr    Integer für 32Bit!}
begin
  ssl:=length(suchstring);
  if ssl>blang then { Source ist zu klein }
    FINDESTR:=-1 { nicht gefunden }
  else begin
    bi :=ssl; { erste Vergleichspos ist ende SuchS }
    ssi:=ssl;
    repeat
      if sucharray[srt(bptr^)[bi]]>0 then
        inc(bi,sucharray[srt(bptr^)[bi]])
      else begin
        ssi:=ssl;
        repeat
          dec(bi,1);
          dec(ssi,1);
        until (ssi<1) or (srt(bptr^)[bi]<>byte(suchstring[ssi]));
        if ssi>0 then
          inc(bi,ssl-(ssi-1));
      end;
    until (bi>blang) or (ssi<1);
    { Ergebnis für 0-Basierte Arrays}
    if ssi<1 then FINDESTR:=bi
    else FINDESTR:=-1;
  end;
end;
end.
Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
fringer

Registriert seit: 25. Feb 2018
15 Beiträge
 
#15

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 5. Mär 2018, 15:20
Vielen Dank für die vielen weiteren Antworten.

Die Funktion von @HolgerX funktioniert soweit. Aber leider nicht mit einem Memorystream bzw. wenn dann die "Nullen" im Stream nicht mitgezählt werden.
Ich werde trotzdem noch einmal versuchen einen Lösungsweg zu finden aber vielleicht ist das ganze auch eine Nummer zu hoch für mich.
Das ganze ist doch wesentlich komplexer als ich dachte.

fringer
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#16

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 5. Mär 2018, 16:06
Wenn die Routine von HolgerX nicht zum gewünschten Ergebnis führt, dann weicht Deine formulierte Anforderung von Deinem gewünschten Ergebnis ab.

Die Routine macht genau das, was Du als Anforderung geschrieben hast.
Vermutlich meinst Du aber etwas (geringfügig) anderes, als Du geschrieben hast, daher wäre es hilfreich, wenn Du eine Binärdatei und ein konkretes Beispiel dessen, was gesucht werden soll, zur Verfügung stellen könntest.

Eventuell sind dann nur marginale Änderungen an HolgerXs Routine erforderlich oder der Aufbau des zu Suchenden muss verändert oder das zu Suchende in der Routine nur etwas anders interpretiert werden.
  Mit Zitat antworten Zitat
fringer

Registriert seit: 25. Feb 2018
15 Beiträge
 
#17

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 5. Mär 2018, 19:16
@Delphi.Narium
Vielen Dank für deine Antwort, es kann vielleicht wirklich sein,
das ich meine Anforderung schlecht ausgedrückt habe.

Daher noch einmal mein Anliegen:

In einer Datei xyz.dat (siehe 7zip-Archiv im Anhang, Virengeprüft!)
soll die Hex-Sequenz "58 50 52 30 00 28" (oder Ansi-Sequenz "XPR0.(" gesucht werden. Wenn diese
gefunden werden sollte, soll die Anfangsposition der Sequenz in der Datei via "showmessage" angezeigt werden.

Im Falle dieser Testdatei wäre es die Position "$0040F7F8".

In einem vorangegangenen Projekt habe ich die Position in einer
in den Stream geladenen Datei so definieren können (Siehe Code unten). Daher dachte
ich muss es auch umgekehrt möglich sein, das ich mir die Position
ausgeben lassen kann indem ich den Stream nach der gesuchten
Hex- oder Ansi-Sequenz durchsuchen lassen kann.


Code:
 

var
  loadstrm : TMemorystream;
  offsetadr : Integer;

...

begin
loadstrm := TMemoryStream.Create;        // Eröffne Stream
offsetadr := $003E1000;                  // Setzte Startadresse
try
loadstrm.LoadFromFile(opendialog1.FileName); // Lade Datei in Stream
loadstrm.Position := offsetadr;              // Gehe in Stream an die Startadresse

...
Angehängte Dateien
Dateityp: 7z xyz.7z (1,37 MB, 0x aufgerufen)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#18

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 5. Mär 2018, 19:57
Zwischen Deinem Wunsch und HolgerX Implementierung gibt es eine "Missverständnis":

Wenn ich die Implementierung recht verstehe, müsste der zu übergebende Suchbegriff 'XPR0' + Chr(0)+ '(' sein.

Sei bitte so gut und versuche es mal in der Form:
Delphi-Quellcode:

var
  S : TStringStream;
  i : integer;
  A : array of Byte;
  Data : AnsiString;
begin
  SetLength(A,6);
  A[0] := 58;
  A[1] := 50;
  A[2] := 52;
  A[3] := 30;
  A[4] := 00;
  A[5] := 28;

  S := TStringStream.Create(Memo1.Lines.Text);
  try
    S.Position := 0;
    EditPos.Text := IntToStr( FindPosInStream(S,A));
  finally
    S.Free;
  end;
end;
Das Verständnisproblem ist bisher: HolgerXs Routine erwartet einen String. Dieser wird dann byteweise in ein Array geschrieben und dann wird der Inhalt dieses Arrays im Stream gesucht.

Du hast jedoch bereits eine Zeichenfolge in Hex-Werte umgewandelt und dann diese übergeben. Das passt nicht zusammen.

Andererseits enthält die zu suchende Sequenz eine hexadezimale 0. Diese könnte man aber per Eingabefeld, wie von HolgerX im Beispiel vorgeschlagen, nicht übergeben.

Wenn Du also zwingend die Hexwerte eingeben musst, was hier durchaus sinnvoll erscheint, muss der Aufruf von HolgerXs Routine angepasst werden.

Ungetesteter Vorschlag:
Delphi-Quellcode:
procedure TForm1.ButtonSearchClick(Sender: TObject);
var
  S : TStringStream;
  i : integer;
  k : Integer;
  x : String;
  A : array of Byte;
  Data : AnsiString;
begin
  // Eingabe übernehmen und diese von führenden und folgenden Leerzeichen befreien.
  // Da die Leerzeichen als Trenner für die Einzelwerte dienen, benötigen wir am Ende
  // für den letzten Einzelwert noch ein Leerzeichen.
  Data := Trim(EditSearch.Text) + ' '; // hier: 58 50 52 30 00 28
  // Zuerst zählen wir nun, wieviele Leerzeichen es in der Eingabe gibt.
  k := 0;
  for i := 1 to Length(Data) do begin
    case Data[i] of
      #32 : Inc(k);
    end;
  end;
  // Das Array für den Suchbegriff wird entsprechend dimensioniert.
  SetLength(A,k);
  x := '';
  k := 0;
  // Nun suchen wir wieder unsere oben gezählzen Leerzeichen.
  For i := 1 to Length(Data) do begin
    case Data[i] of
      #32 : begin
              // Wird eins gefunden, so machen wir aus dem bisher
              // gefundenen eine Zahl und übergeben diese ans Array.
              A[k] := StrToInt(x);
              // Den Zähler für die Position im Array erhöhen.
              Inc(k);
              // Leermachen für den nächsten Hexwert.
              x := '';
            end;
    else
      // Zeichen aus der Eingabe "sammeln", bis ein Leerzeichen kommt.
      x := x + Data[i];
    end;
  end;

  S := TStringStream.Create(Memo1.Lines.Text);
  try
    S.Position := 0;
    EditPos.Text := IntToStr(FindPosInStream(S,A));
  finally
    S.Free;
  end;
end;
(Ist jetzt nur als Idee gedacht und etwas aufwändig, aber dadurch (hoffentlich) etwas verständlicher.)
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
969 Beiträge
 
Delphi 6 Professional
 
#19

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 6. Mär 2018, 00:02
Hmm....

Schon hier ist ein Fehler!

die Hex-Sequenz "58 50 52 30 00 28" (oder Ansi-Sequenz "XPR0.(" gesucht werden.
Die Hex-Sequenz "58 50 52 30 00 28" ist nicht "XPR0.("!
Die 00 kann nur nicht dargestellt werden, weshalb wohl dein Text-Editor, mit welchem Du die Datei geöffnet hast, diese gegen '.' austauscht..

Wenn Du nach genau dieser Hex-Sequenz in der Datei xyz.dat suchen willst, dann geht folgendes:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  B : Array[0..5] of Byte = ($58, $50, $52, $30, $00, $28); // "XPR0 ("
var
  F : TFileStream;
begin
  F := TFileStream.Create('xyz.dat', fmOpenRead);
  try
    EditPos.Text := IntToStr(FindPosInStream(F,B));
  finally
    F.Free;
  end;
end;
Im Edit steht dann die erste Position der Hex-Sequenz "58 50 52 30 00 28".

Mein Letztes Beispiel (vorheriger Post) zeigte nur das Suchen eines (ANSI) Textes in einem (ANSI) StringStream.
Die FindPosInStream-Funktion arbeitet jedoch mit jedem Stream und sucht darin eine Bytefolge.
Würde ich die Bytefolge z.B. mit 00 58 00 50 00 52 00 30 00 00 00 28 füllen, dann würde im Stream nicht nach einem ANSI-String "XPR0 (" sondern einem WideString "XPR0 (" gesucht. (Kann auch sein, dass die Low/BigEndian Reihenfolge im ByteArray gedeht werden muss )
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#20

AW: Hexwert in Binärdatei suchen und Position ermitteln

  Alt 6. Mär 2018, 11:10
In meinem Beispiel oben ist übrigens diese Zeile falsch: A[k] := StrToInt(x); Da muss man irgendwie aus z. B. FF 255 machen. Und da ist StrToInt irgendwie ungünstig

Aber wenn man statt HEX-Werten die entsprechenden Dezimalwerte nimmt, sollte es auch so funktionieren.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:23 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