如在PE文件中一段字节 ... 12 21 21 54 4F 35 1F 65 22 ... 我要搜索其中的 21 54 4F 35 1F 并让他返回地址.请问该如何处理.这是一段搜索流中字符的一段代码.请问我要改为搜索字节数组的话要怎么改function ScanStream(mStream: TStream; mStr: string): Integer; //搜索字符窜
const
cBufferSize = $8000;
var
S : string;
T : string;
I : Integer;
L : Integer;
begin
Result := -1;
if not Assigned(mStream) then Exit;
if mStr = '' then Exit;
L := Length(mStr);
mStream.Position := 0;
SetLength(S, cBufferSize);
T := '';
for I := 1 to mStream.Size div cBufferSize do begin
mStream.Read(S[1], cBufferSize);
Result := Pos(mStr, T + S) - 1; //保留上次搜索的尾部字符~~
T := Copy(S, cBufferSize - L, MaxInt);
if Result >= 0 then begin
Result := Result + Pred(I) * cBufferSize - Length(T);
Exit;
end;
end;
I := mStream.Size mod cBufferSize;
SetLength(S, I);
if I > 0 then begin
mStream.Read(S[1], I);
Result := Pos(mStr, T + S) - 1;
if Result >= 0 then begin
Result := Result + mStream.Size - I - Length(T);
Exit;
end;
end;
end;
const
cBufferSize = $8000;
var
S : string;
T : string;
I : Integer;
L : Integer;
begin
Result := -1;
if not Assigned(mStream) then Exit;
if mStr = '' then Exit;
L := Length(mStr);
mStream.Position := 0;
SetLength(S, cBufferSize);
T := '';
for I := 1 to mStream.Size div cBufferSize do begin
mStream.Read(S[1], cBufferSize);
Result := Pos(mStr, T + S) - 1; //保留上次搜索的尾部字符~~
T := Copy(S, cBufferSize - L, MaxInt);
if Result >= 0 then begin
Result := Result + Pred(I) * cBufferSize - Length(T);
Exit;
end;
end;
I := mStream.Size mod cBufferSize;
SetLength(S, I);
if I > 0 then begin
mStream.Read(S[1], I);
Result := Pos(mStr, T + S) - 1;
if Result >= 0 then begin
Result := Result + mStream.Size - I - Length(T);
Exit;
end;
end;
end;
function ScanStreamMuti(mStream: TStream; mStr:array of string): Integer;
var
i : integer;
begin
Assert(Assigned(mStream));
result := -1;
if Length(mStr) = 0 then Exit;
for i := low(mStr) to high(mStr) do begin
result := ScanStream(mMStream, mStr[i]);
if result>=0 then break;
end
end;还有你上面代码效率和处理上也有问题:1. mStream.Read(S[1], cBufferSize); 最好处理它的返回值,特别是在扩展流中屏掉了错误
,导致返回值为空或都小于时,这时查找会一直以S缓存中的数据(如果执行过一次的话)来查找.结果不可预料的.
2.
T := Copy(S, cBufferSize - L, MaxInt);
if Result >= 0 then begin
Result := Result + Pred(I) * cBufferSize - Length(T);
Exit;
end;
==>
if Result >= 0 then begin
Result := Result + Pred(I) * cBufferSize - Length(T);
Exit;
end;
T := Copy(S, cBufferSize - L, MaxInt);
在查找成功时,这句代码根本就无所用处.
3.
Result := Pos(mStr, T + S) - 1; //保留上次搜索的尾部字符~~
T := Copy(S, cBufferSize - L, MaxInt);
如果在大文件查找时,这两句代码进行的内存COPY是有点代价的.
既然每次都要COPY文件的保留上次搜索的尾部字符,不如在分配缓冲S时候就加上这个长度
[Length(mStr)] + [cBufferSize]
每次查完一次,只复制尾部到S到前面即可,减少了T + S和Copy函数又执的一次内存分配动作还有其它一些问题和算法效率,我就不说了
var S: string;
//vBytes: array of byte;//假设已经赋值
begin
SetLength(S, Length(vBytes));
Move(vBytes[0], S[1], Length(vBytes));
I := ScanStream(vStream, S);
end;