Слияние кода завершено, страница обновится автоматически
unit FindHexUnit;
interface
uses
Winapi.Windows,System.SysUtils,System.Classes,qrbtree,math,utils.locker,System.SyncObjs;
type
TCompareMemory = class;
TCompareMemoryCall = function (Address:NativeUInt):Boolean of object;
THex = record
Hex:Byte;
IsAny:Boolean;
end;
//分块多线程建模结构
TCompareThreadRecord = record
//内存指针
Memory:Pointer;
//内存大小
MemorySize:NativeUInt;
//分块偏移
Office:NativeUInt;
//哈希表
HashTable:TQHashTable;
end;
PCompareThreadRecord = ^TCompareThreadRecord;
{ TCompareMemory }
/// <summary>
/// 内存特征码比对类
/// </summary>
TCompareMemory = class(TObject)
private
mCallback:TCompareMemoryCall;
HashTable:TQHashTable;
CompareMaxMemory:NativeUInt;
Locker: TCriticalSection;
function Compare(P1, P2: Pointer): Integer;
procedure AfterBucketUsed(ATable: TQHashTable; ABucketIndex: Integer);
function CompareHexs(const hexss:array of THex;var HByte:TBytes;HexsSize:NativeInt):Boolean;
//方便以后包装成多线程
function AddHash(memory:Pointer;office:NativeInt;Size:integer):Boolean;
procedure ForHashTable(HexArray:array of THex;HexSize:NativeUInt);
//返回CPU个数
function GetCPUCount: Integer;
protected
public
/// <summary>
/// 构造类
/// </summary>
/// <param name="hashsize"> 哈希表大小,一般设置为$FF</param>
constructor Create(hashsize:NativeUInt);
/// <summary>
/// 将数据初始化入哈希表
/// </summary>
/// <param name="memory"> 数据指针</param>
/// <param name="size"> 数据大小</param>
/// <remarks>注意,数据大小不可过大</remarks>
procedure MemoryToHashTable(memory:Pointer;size:NativeUInt);
/// <summary>
/// 查找特征码
/// </summary>
/// <param name="hexs"> 特征码数组</param>
/// <param name="HexsSize"> 特征码数组长度</param>
/// <remarks>支持通配符‘??’,第一个特征码不可为??。</remarks>
function CompareHashHexs(hexs:array of PAnsiChar;HexsSize:NativeUInt):Boolean;overload;
/// <summary>
/// 查找特征码
/// </summary>
/// <param name="hexs"> 特征码字符串,格式如‘E0 ?? ?? F0 ??’</param>
/// <remarks>支持通配符‘??’,第一个特征码不可为??。</remarks>
function CompareHashHexs(const hexs:AnsiString):Boolean;overload;
/// <summary>
/// 释放哈希表
/// </summary>
/// <remarks>重新初始化前必须调用。</remarks>
procedure ClearHashTable;
/// <summary>
/// 析构类
/// </summary>
destructor Destroy; override;
/// <summary>
/// 查找回调
/// </summary>
/// <returns>当回调代码返回Flase则终止查找</returns>
/// <remarks>注意,回调代码的效率会影响查找速度。</remarks>
property OnCompareCallBack:TCompareMemoryCall write mCallback;
/// <summary>
/// 查看哈希表使用情况
/// </summary>
function Statics:string;
published
end;
const
tpf:PAnsiChar = '??';
implementation
function TCompareMemory.Statics:string;
var
AResult: TQHashStatics;
begin
HashTable.Statics(AResult);
Result := Format('有效的桶数:%d' + #13#10 +
'最大深度:%d' + #13#10 +
'平均尝试:%f' + #13#10 +
'总深度:%d'
,[AResult.Count,AResult.MaxDepth,AResult.AvgDepth,AResult.TotalDepth]);
end;
function TCompareMemory.CompareHexs(const hexss:array of THex;var HByte:TBytes;HexsSize:NativeInt):Boolean;
var
i:Int64;
begin
if HexsSize = 1 then
begin
Result := True;
Exit;
end;
Result := False;
for I := 1 to HexsSize - 1 do
begin
if not hexss[i].IsAny then
if not (hexss[i].Hex = HByte[i]) then
Exit;
end;
Result := True;
end;
function TCompareMemory.Compare(P1, P2: Pointer): Integer;
begin
//
Result := 0;
end;
procedure TCompareMemory.AfterBucketUsed(ATable: TQHashTable; ABucketIndex: Integer);
begin
//桶被使用时触发
end;
constructor TCompareMemory.Create(hashsize:NativeUInt);
begin
CompareMaxMemory := 0;
Locker := TCriticalSection.Create;
HashTable := TQHashTable.Create(hashsize);
HashTable.OnCompare := Compare;
HashTable.AfterBucketUsed := AfterBucketUsed;
end;
function TCompareMemory.AddHash(memory:Pointer;office:NativeInt;Size:integer):Boolean;
var
i:NativeUInt;
tmpMemory:Pointer;
k:Integer;
begin
Result := True;
NativeUInt(tmpMemory) := office + NativeUInt(tmpMemory);
for i := 0 to size - 1 do
begin
NativeUInt(tmpMemory) := NativeUInt(memory) + i;
//多线程锁
Locker.Enter;
HashTable.Add(tmpMemory,TBYTES(tmpMemory)[0]);
Locker.Leave;
end;
end;
//抄自QWorker
function TCompareMemory.GetCPUCount: Integer;
var
si: SYSTEM_INFO;
begin
GetSystemInfo(si);
Result := si.dwNumberOfProcessors;
end;
procedure TCompareMemory.MemoryToHashTable(memory:Pointer;size:NativeUInt);
begin
CompareMaxMemory := NativeUInt(memory) + size;
//准备扩展为多线程
AddHash(memory,0,size);
end;
procedure TCompareMemory.ForHashTable(HexArray:array of THex;HexSize:NativeUInt);
var
list: PQHashList;
begin
list := HashTable.FindFirst(HexArray[0].Hex);
while list <> nil do
begin
if NativeUInt(list.Data) + HexSize < CompareMaxMemory then
begin
if CompareHexs(HexArray,TBytes(list.Data),HexSize) then
begin
if not mCallback(NativeUInt(list.Data)) then Exit;
end;
end;
list := HashTable.FindNext(list);
end;
end;
function TCompareMemory.CompareHashHexs(hexs:array of PAnsiChar;HexsSize:NativeUInt):Boolean;
var
hex2:Byte;
HexArray:array of THex;
i: NativeUInt;
begin
Result := False;
SetLength(HexArray,hexssize);
for i := 0 to HexsSize - 1 do
begin
if CompareMem(hexs[i],tpf,2) then
begin
//HexArray[i].Hex := $00;
HexArray[i].IsAny := True
end
else
begin
HexToBin(hexs[i],hex2,1);
HexArray[i].Hex := hex2;
HexArray[i].IsAny := False;
end;
end;
ForHashTable(HexArray,HexsSize);
SetLength(HexArray,0);
end;
function TCompareMemory.CompareHashHexs(const hexs:AnsiString):Boolean;
var
hexSize:NativeUInt;
i: NativeUInt;
HexString:PAnsiChar;
HexArray:array of THex;
hex2:Byte;
list: PQHashList;
begin
hexSize := ceil(Length(hexs) / 3);
SetLength(HexArray,hexSize);
Result := True;
for i := 0 to hexSize - 1 do
begin
HexString := PAnsiChar(Copy(hexs,(i+1)*3-2,(i+1)*3-1));
if CompareMem(HexString,tpf,2) then
begin
HexArray[i].IsAny := True
end
else
begin
HexToBin(HexString,hex2,1);
HexArray[i].Hex := hex2;
HexArray[i].IsAny := False;
end;
end;
ForHashTable(HexArray,HexSize);
SetLength(HexArray,0);
end;
procedure TCompareMemory.ClearHashTable;
begin
CompareMaxMemory := 0;
HashTable.Clear;
end;
destructor TCompareMemory.Destroy;
begin
ClearHashTable;
HashTable.Free;
HashTable := nil;
end;
end.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )