AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Datei an bestimmten Offsets editieren

Ein Thema von Quick_silver · begonnen am 28. Jun 2006 · letzter Beitrag vom 2. Jul 2006
Antwort Antwort
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#1

Datei an bestimmten Offsets editieren

  Alt 28. Jun 2006, 19:38
Guten Tag,
foglendes.. Ich habe eine .exe datei welche ich editieren will. Manuell habe ich sie im HexEditor geöffnet und darin rumgeschrieben. Genau das soll nun mein Delpiprogramm machen.
Wie frage ich in einer Datei bestimmte positionen (offsets) ab und wie editiere ich sie.

Wäre sehr dankbar wenn ich wenigstens Ansätze bekomme.

Güsse Quick_silver
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#2

Re: Datei an bestimmten Offsets editieren

  Alt 28. Jun 2006, 21:10
schau dir mal TFileStream an, dort kannst du mit per seek oder position an die jeweilige position springen und per write (und noch einige andere) schreiben.
per strtoint('$'+hexwert); kannst du hexwerte in dezimalwerte umrechnen.

HTH Frank
  Mit Zitat antworten Zitat
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#3

Re: Datei an bestimmten Offsets editieren

  Alt 29. Jun 2006, 16:40
Von: http://www.dsdt.info/tipps/?id=122
Zitat:
Mit folgender Routine ist es möglich, in einer Datei nach einer Zeichenkette zu suchen und diese durch eine gleichlange Zeichenkette zu ersetzen. Vorsicht ist bei Dateien geboten, bei denen zwischendurch das Zeichen #0 vorkommt (beispielsweise bei EXE-Dateien). Die Routine bricht an einer solchen Stelle ab.
Ansonsten ist die Routine ja ganz gut. Aber wie schaffe ich es das der Stream auch die #0 mit nimmt?
  Mit Zitat antworten Zitat
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#4

Re: Datei an bestimmten Offsets editieren

  Alt 1. Jul 2006, 21:36
Nach vielem rumbasteln habe ich es gesschafft. Es gibt nur ein kleines problem. Der Code sieht so aus:

Delphi-Quellcode:
procedure TForm1.PatchFile(const path, searchFor, replaceWith:string);
var
r,i,j:integer;
f: file of byte;
offset:array of integer;
buf:array [0..8] of byte; //Zu Testzwecken so kurz gehalten
workBuf:array of byte;
begin
ProgressBar.Max := GetFileSizeEx(path);
ProgressBar.Position := 0;

//searchFor -> workbuf
SetLength(workBuf, Length(searchFor));
for i:=0 to Length(workBuf)-1 do
  workBuf[i]:=Ord(searchFor[i+1]);


//Durchsuchen
assignfile(f,path);
reset(f);

repeat
  blockread(f,buf,Length(buf),r); //Block einlesen
  ProgressBar.StepBy(Length(buf));
  //buf nach workBuf durchsuchen
  for i:=0 to Length(buf)-1 do //buf durchgehen
  begin
    for j := 0 to Length(workBuf)-1 do //Suchstring bei i durchgehen
    begin
      if buf[i+j] = workBuf[j] then //Anfang gefunden!
      begin
        if j = Length(workBuf)-1 then //Komplett gefunden!
        {///// PROBLEM: Dies tritt nicht ein wenn der Block in "buf" mitten im Suchstring endet... /////}
        begin
          SetLength(offset,Length(offset)+1);
          offset[Length(offset)-1] := filepos(f) - Length(buf) + i;
          //offset[n] gibt die Position des workBuf[0] wieder
        end;
      end else //Nicht kmoplett gefgunden!
      begin
        break;
      end; //else
    end;// for
  end;//for
until r < Length(workBuf);

//Alles was gefunden wurde steht in offset...
//Gefundenes ersetztn:

//replaceWith -> als Byte -> workBuf
SetLength(workBuf,Length(replaceWith)+1);
for i:=0 to Length(workBuf)-1 do
  workBuf[i] := Ord(replaceWith[i+1]);

//An jedem Offset ersetzen:
for i:=0 to Length(offset)-1 do
begin
  Seek(f, offset[i]);
  BlockWrite(f, workBuf[0], Length(workBuf),r);
end;
      
closefile(f);
end;
Hat Spaß gemact das alles so hin zu basteln. nichtmal ein #0 in der Datei stört die Routine.
Nur denke ich das die Suchfunktion endweder viel einfacher geht. Und wenn nicht einfacher, dann brauche ich eine Lösung für das oben beschriebene Problem. Wenn der Suchstring also zwischen 2 "BlockRead(..)" liegt.

Ein anderes problem, eher eine Frage ist: Wieso kann man das Array Buf nicht als Dynamisches array nutzen? Er Meckert dann komischer Weise immer. Denn mit einem Dynamischen Array könnte man auch Dateien die < Length(buf) sind mit dieser Routine bearbeiten.
  Mit Zitat antworten Zitat
Quick_silver

Registriert seit: 2. Jan 2003
78 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Datei an bestimmten Offsets editieren

  Alt 2. Jul 2006, 09:57
Ich hab nun sleber eine Lösung, ich denke es gibt auch shcnellere Lösungen, für Hinweise in die Richtung wäre ich dankbar. Auch wenn das Aktuelle für mich vollkommen ausreicht.

Dies hat mein Problem ersteinmal gelößt.
Delphi-Quellcode:
  if filepos(f) > Length(workBuf) then
    seek(f, filepos(f)-Length(workBuf));
Ausserdem habe ich noch andere "Bugs" behoben:
- Dateien können kleiner < buf bytes sein
- Nur tatsächlich neu ausgelesenes wird behandelt
Delphi-Quellcode:
procedure TForm1.PatchFile(const path, searchFor, replaceWith:string);
var
r,i,j:integer;
f: file of byte;
offset:array of integer;
buf:array [0..1023] of byte;
workBuf:array of byte;
begin
ProgressBar.Max := GetFileSizeEx(path);
ProgressBar.Position := 0;

//searchFor -> workbuf
SetLength(workBuf, Length(searchFor));
for i:=0 to Length(workBuf)-1 do
  workBuf[i]:=Ord(searchFor[i+1]);

//Durchsuchen
assignfile(f,path);
reset(f);

repeat
  if filepos(f) > Length(workBuf) then
    seek(f, filepos(f)-Length(workBuf));

  blockread(f,buf,Length(buf),r);
  ProgressBar.StepBy(Length(buf));
  //buf nach workBuf durchsuchen
  for i:=0 to Length(buf)-1 do //buf durchgehen
  begin
    if i >= r then break; //Ausserhalb des Buffers abbrechen

    for j := 0 to Length(workBuf)-1 do //Suchstring bei i durchgehen
    begin
      if buf[i+j] = workBuf[j] then //Anfang gefunden!
      begin
        if j = Length(workBuf)-1 then //Komplett gefunden!
        begin
          SetLength(offset,Length(offset)+1);
          offset[Length(offset)-1] := filepos(f) - r + i;
          //offset[n] gibt die Position des workBuf[0] wieder
        end;
      end else //Nicht kmoplett gefgunden!
      begin
        break;
      end;
    end;// for
  end;
until r < Length(Buf);

//Alles was gefunden wurde steht in offset...
//Gefundenes ersetztn:

//replaceWith -> als Byte -> workBuf
SetLength(workBuf,Length(replaceWith)+1);
for i:=0 to Length(workBuf)-1 do
  workBuf[i] := Ord(replaceWith[i+1]);

//An jedem Offset ersetzen:
for i:=0 to Length(offset)-1 do
begin
  Seek(f, offset[i]);
  BlockWrite(f, workBuf[0], Length(workBuf),r);
end;
      
closefile(f);
end;
Da es nun fertig ist würde ich mich über Verbesserungsvorschläge und Kritik freuen.
  Mit Zitat antworten Zitat
Antwort Antwort


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 14:26 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