バイナリの検索、書き換えをするには?

解決


ME  2005-02-22 06:18:28  No: 13386

特定の場所にあるファイル(例えばEXE)のバイナリデータを検索し、一致したところを書き換えるという処理をさせたいのですが、具体的にどんなプログラムを書けばよいのでしょうか?

検索対象として
12 34 56 AB CD EF が一致したら
EF CD AB 56 34 12 に書き換えるという感じなのですが。


りおりお  2005-02-22 09:35:34  No: 13387

ポインタをずらしながら CompareMem() で一致確認する。一致したら Move() で
上書きする。


ME  2005-02-22 13:43:00  No: 13388

なるほど・・。
CompareMem()の使い方がちょっと不明です。
Googleで検索してみたものの使用例が見つからず。
もうちょっと調べてみます。


ビンゴ  2005-02-22 18:08:36  No: 13389

デルファイのヘルプからです.
−−−−−−−−−−−−−
CompareMem 関数は 2 つのメモリイメージのバイナリ比較を実行します。

ユニット

SysUtils

カテゴリ

比較ルーチン

function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;

説明

CompareMem 関数は,P1 で参照されるメモリの Length バイトと P2 のそれのバイナリ比較を実行します。CompareMem は,P1 の参照するメモリが P2 のそれと同じである場合に True を返します。


りおりお  2005-02-23 02:13:29  No: 13390

関数を作ってみました。何回かテストしてバイナリエディタで結果を確認しました。

type
TBinaryData = array of byte;

function FindReplaceBinaries(const FileName,FindStr,ReplaceStr: string):Boolean;

  function StrToBinaryData(const Data: string; var bd:TBinaryData):integer;
  var
    sl:TStringList;
    j:integer;
  begin
    sl := TStringList.Create;
    try
      sl.CommaText := Data;
      result := sl.Count;
      SetLength(bd,result);
      for j := 0 to result-1 do
        bd[j] := StrToInt('$'+sl[j]);
    finally
      sl.Free;
    end;
  end;

var
  bd1,bd2:TBinaryData;
  i,len:integer;
  ms:TMemoryStream;
  p:PByte;
begin
  result := false;
  len := StrToBinaryData(FindStr,bd1);
  if StrToBinaryData(ReplaceStr,bd2) <> Len then
  begin
    ShowMessage('バイナリデータのサイズが一致しません');
    exit;
  end;
  ms := TMemoryStream.Create;
  try
    ms.LoadFromFile(FileName);
    p := ms.Memory;
    for i := 0 to ms.Size-len do
    begin
      if p^ = bd1[0] then
        if CompareMem(p,@bd1[0],len) then
        begin
         Move(bd2[0],p^,len);
         ms.SaveToFile(FileName);
         result := true;
         Break;
        end;
      inc(p);
    end;
  finally
    ms.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if FindReplaceBinaries('c:\BinaryData.dat','12 34 56 AB CD EF',
        'EF CD AB 56 34 12') then
    ShowMessage('成功');
end;


ME  2005-02-23 02:50:40  No: 13391

>ビンゴさん
Delphiのヘルプは見ましたがそれでも・・勉強が足りないようです。

>りおりお
わざわざ時間を割いてまでプログラムを作って頂き、ありがとうございます。
とても参考になりました。
自力で書けるようになるまでもう少し努力してみるつもりです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加