AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

What's incorrect with this

Ein Thema von mohfa · begonnen am 23. Jan 2009 · letzter Beitrag vom 23. Jan 2009
Antwort Antwort
mohfa

Registriert seit: 11. Feb 2007
97 Beiträge
 
Delphi 7 Enterprise
 
#1

What's incorrect with this

  Alt 23. Jan 2009, 03:38
This an antivirus scanner i'm working on , i want to add the Wildcard search function but , it doesn't work

could somebody take a look at it , and tell me what's the Problem with it

The attachment contains 3 files :

+ The scanner.pas = the main Scanner Engine
+ FastStrings.pas = i use for FastPos + i adapted it with patternPos to be able to Use the WildCards
+ MD5.pas = Use it in my Databases
+ DB.txt = the Main database .

SO if i add a Signature Like this : AB??EFG it won't work although the patternPos works very well .

// Here an extract from the scanner.pas

// I use this in the WildCard Search :
Delphi-Quellcode:
function Matches(const AString, Pattern: string; startpos:integer): boolean;
var
   j, n, n1, n2: integer ;
   p1, p2: pchar ;
label
   match, nomatch;
begin
   n1 := Length(AString) ;
   n2 := Length(Pattern) ;
   if n1 < n2 then
     n := n1
   else
     n := n2;
   p1 := pchar(AString) +startpos-1;
   p2 := pchar(Pattern) ;
   for j := 1 to n do
   begin
     if p2^ = '*then
       goto match;
     if (p2^ <> '?') and ( p2^ <> p1^ ) then
       goto nomatch;
     inc(p1) ; inc(p2) ;
   end;
   if n1 > n2 then
   begin
     goto match;
nomatch:
     Result := False;
     exit;
   end else
     if n1 < n2 then
     begin
       for j := n1 + 1 to n2 do
       begin
         if not ( p2^ in ['*','?'] ) then
           goto nomatch ;
         inc(p2) ;
       end;
     end;
match:
   Result := True
end;
 
function patternPos(const ASourceString, APatternString : string; StartPos:integer):integer;
var l, ll,i,delta:integer;
    p:string;
begin
  Assert(StartPos>0);
  Assert(length(APatternString)>0);
  result:=0;
  l:=length(ASourceString);
  if StartPos>l then
    exit;

  p:=findText(APatternString, delta);
  if p='then
  begin
    if Matches(ASourceString, APatternString, StartPos) then
      result:=StartPos;
    exit;
  end else
  begin
    i:=StartPos-1;
    ll:=length(p);
    repeat

    {
    FastPos( s,lVirus^.Signature,sLen,lVirus^.SigLen, 1) > 0
    }

      i:=FastPos(ASourceString, p, length(ASourceString), ll, i+1);
      if i=0 then
        exit;
      if Matches(ASourceString, APatternString, i-delta) then
      begin
        if APatternString[1]='*then
          result:=StartPos
        else
          result:=i-delta;
        exit;
      end;
    until i=0;
  end;
end;
 //-----------pattern
// I use it like this way :

Delphi-Quellcode:

if ((FastPos( s,
                  lVirus^.Signature,
                  sLen,
                  lVirus^.SigLen, 1) > 0)Or
                  (patternPos(s,lVirus^.Signature,1) > 0)) then
                    result := gSignatures.IndexOf(lVirus);
But all this doesn't work with WildCard .


It makes me crazy why the patternPos doesn't give any result .


Please see the Attachment
Angehängte Dateien
Dateityp: rar scanner_124.rar (14,6 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#2

Re: What's incorrect with this

  Alt 23. Jan 2009, 08:08
Da hier glaube ich kaum einer mit GoTo arbeitet, haben wahrscheinlich alle Mühe den Codefluss zu verstehen - du vielleicht auch?.
Uwe Raabe
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.753 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: What's incorrect with this

  Alt 23. Jan 2009, 08:45
Goto statement is considered harmful: Link to a PDF http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF

Sherlock
Oliver
  Mit Zitat antworten Zitat
mohfa

Registriert seit: 11. Feb 2007
97 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: What's incorrect with this

  Alt 23. Jan 2009, 21:23
I think i have a Little Problem in the patternPos function , But where is this Problem , That's what i'm trying to find out .

Any Help please .
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: What's incorrect with this

  Alt 23. Jan 2009, 21:38
where is the init for delta in patternPos?
why do you need exit and goto?
where is FastPos?
where is findText?

Sorry, for my bad English.
  Mit Zitat antworten Zitat
mohfa

Registriert seit: 11. Feb 2007
97 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: What's incorrect with this

  Alt 23. Jan 2009, 22:12
Thank you omata , if you have downloaded the Attachment you will see :

FastPos is function declared in FastStrings Unit Copyrighted by Peter Morris . and here is it declaration :

function FastPos(const aSourceString, aFindString : string; const aSourceLen, aFindLen, StartPos : Integer) : Integer; And Here is the Declaration of FindText :

Delphi-Quellcode:
function findtext(const pattern:string; var delta:integer):string;
var i,j:integer;
begin
  i:=1;
  while (i<=length(pattern)) and ((pattern[i]='?') or (pattern[i]='*')) do
    inc(i);
  j:=i;
  delta:=j-1;
  while (i<=length(pattern)) and (pattern[i]<>'?') and (pattern[i]<>'*') do
    inc(i);
  result:=copy(pattern, j, i-j);
end;
Any way here is the whole Unit Scanner.pas :

Delphi-Quellcode:
interface
unit Scanner;

interface

Function Search(const AFilename:PChar;Const AVirusName:PChar;const ANameLength: integer;
                Wnd, MsgID: integer): Boolean; stdcall;

implementation

uses
  SysUtils,
  Classes,
  Windows,
  FastStrings;

const
 BUF_SZ = 1024 *1000; //1 MB
 PROGRESS_MIN_STEPS = 5;


{$DEFINE USEWORKERS} //use TWorkerThreads

{$IFDEF USEWORKERS}

const
  FWorker_Max = 9;

//!! TWorkerThread vars ( NO TOUCHING! )
// **********************************************************

var
  FWorker_Buffers : array[0..FWorker_Max]of string;
  FWorker_BufLen : array[0..FWorker_Max]of integer;

// **********************************************************
//!! TWorkerThread vars ( NO TOUCHING! )


//TWorkerThread...
 //------pattern
 function findtext(const pattern:string; var delta:integer):string;
var i,j:integer;
begin
  i:=1;
  while (i<=length(pattern)) and ((pattern[i]='?') or (pattern[i]='*')) do
    inc(i);
  j:=i;
  delta:=j-1;
  while (i<=length(pattern)) and (pattern[i]<>'?') and (pattern[i]<>'*') do
    inc(i);
  result:=copy(pattern, j, i-j);
end;
 

function Matches(const AString, Pattern: string; startpos:integer): boolean;
var
   j, n, n1, n2: integer ;
   p1, p2: pchar ;
label
   match, nomatch;
begin
   n1 := Length(AString) ;
   n2 := Length(Pattern) ;
   if n1 < n2 then
     n := n1
   else
     n := n2;
   p1 := pchar(AString) +startpos-1;
   p2 := pchar(Pattern) ;
   for j := 1 to n do
   begin
     if p2^ = '*then
       goto match;
     if (p2^ <> '?') and ( p2^ <> p1^ ) then
       goto nomatch;
     inc(p1) ; inc(p2) ;
   end;
   if n1 > n2 then
   begin
     goto match;// we are searching for a match, not testing if the entire string matches the pattern
nomatch:
     Result := False;
     exit;
   end else
     if n1 < n2 then
     begin
       for j := n1 + 1 to n2 do
       begin
         if not ( p2^ in ['*','?'] ) then
           goto nomatch ;
         inc(p2) ;
       end;
     end;
match:
   Result := True
end;
 
function patternPos(const ASourceString, APatternString : string; StartPos:integer):integer;
var l, ll,i,delta:integer;
    p:string;
begin
  Assert(StartPos>0);
  Assert(length(APatternString)>0);
  result:=0;
  l:=length(ASourceString);
  if StartPos>l then
    exit;

  p:=findText(APatternString, delta);
  if p='then
  begin
    if Matches(ASourceString, APatternString, StartPos) then
      result:=StartPos;
    exit;
  end else
  begin
    i:=StartPos-1;
    ll:=length(p);
    repeat
      i:=FastPos(ASourceString, p, length(ASourceString), ll, i+1);
      if i=0 then
        exit;
      if Matches(ASourceString, APatternString, i-delta) then
      begin
        if APatternString[1]='*then
          result:=StartPos
        else
          result:=i-delta;
        exit;
      end;
    until i=0;
  end;
end;

type
  TWorkerThread = class(TThread)
  private
     FWaitEvent : THandle;
     FDone : boolean;
     FSearchResult : integer;
     FTag : integer;
     function _SignatureSearch(const s: string; sLen: integer): integer;
  protected
     procedure Execute; override;
  public
     property WaitEvent: THandle read FWaitEvent;
     constructor Create;
     destructor Destroy; override;
     property Done: boolean read FDone write FDone;
     //returns the index of the virus
     property SearchResult: integer read FSearchResult write FSearchResult;
     property Tag: integer read FTag;
  end;

constructor TWorkerThread.Create;
begin
   FWaitEvent := CreateEvent(nil, false, false, nil);
   inherited Create(false);

   FreeOnTerminate := true;

   FDone := true;
   FSearchResult := -1;
   FTag := -1;
end;

destructor TWorkerThread.Destroy;
begin
   CloseHandle(FWaitEvent);
   inherited;
end;
//----------------------------------------------------------------------------//
//--------------- From Here i wanted to use WildCard -------------------------//
//----------------------------------------------------------------------------//
function TWorkerThread._SignatureSearch(const s: string; sLen: integer): integer;
var
  lVirus: PVirusDefinition;
  pattern : string;
  res : boolean;
  i:integer;
  AYes:Boolean;
begin
 // AYes:=False;
  result := -1;
  lVirus := PVirusDefinition(gSignatures[0]);
  pattern := '';
  while (lVirus <> nil) and (result < 0) do begin
    if lVirus^.Pattern = 'then begin
      //no pattern
      pattern := '';

      if ((FastPos( s,
                  lVirus^.Signature,
                  sLen,
                  lVirus^.SigLen, 1) > 0)Or
                  (patternPos(s,lVirus^.Signature,1) > 0)) then
                    result := gSignatures.IndexOf(lVirus);
    end else begin
      if lVirus^.Pattern = pattern then begin
        //buffer contains pattern
     if ((FastPos( s,
                  lVirus^.Signature,
                  sLen,
                  lVirus^.SigLen, 1) > 0)Or
                  (patternPos(s,lVirus^.Signature,1) > 0)) then
                      result := gSignatures.IndexOf(lVirus);
      end else begin
        //new pattern


        res := FastPos( s,
                        pattern,
                        sLen,
                        Length(pattern), 1) > 0;

        if not res then begin
          //pattern not found so
          //find next pattern...
          lVirus := lVirus^.NextPattern;
          continue;
        end else begin
          //pattern found

          if ((FastPos( s,
                  lVirus^.Signature,
                  sLen,
                  lVirus^.SigLen, 1) > 0)Or
                  (patternPos(s,lVirus^.Signature,1) > 0)) then
                        result := gSignatures.IndexOf(lVirus);
        end;
      end;
    end;

    lVirus := lVirus^.Next;
  end;

end;

procedure TWorkerThread.Execute;
begin
  while not Terminated do begin
    WaitForSingleObject(FWaitEvent, INFINITE);
    ResetEvent(FWaitEvent);

    if not Terminated then begin

      FDone := false;

      if (FTag > -1) and (FTag <= FWorker_Max) then
        FSearchResult := _SignatureSearch(FWorker_Buffers[FTag], FWorker_BufLen[FTag])
      else
        FSearchResult := -1;

      FDone := true;
    end;
  end;
end;


//...TWorkerThread


var
  FWorkers : array[0..FWorker_Max]of TWorkerThread;



Function Search(const AFilename: PChar; const AVirusName: PChar; const ANameLength: integer;
                Wnd, MsgID: integer): Boolean;
var
 lStream: TStream;
 lVirus: PVirusDefinition;
 red : Integer;
 sz : int64;
 steps, totsteps : integer;
 i, WorkerIndex : integer;
 alldone : boolean;
begin
  result := false;

  if assigned(gSignatures) then
  begin

    for i := 0 to FWorker_Max do begin
      if Length(FWorker_Buffers[i]) <> BUF_SZ then
        SetLength(FWorker_Buffers[i], BUF_SZ);

      FWorker_BufLen[i] := 0;

      FWorkers[i].FSearchResult := -1;
    end;

    try

      lStream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyNone);
      try
        sz := lStream.Size;

        //calc total steps required
        totsteps := 0;
        repeat
          Dec(sz, BUF_SZ);
          Inc(totsteps);
          if (sz > 0) and (gMax_SigLen -1 > 0) and (gMax_SigLen < BUF_SZ) then
            Inc(sz, gMax_SigLen);
        until sz < 1;
        steps := 0;


        if (Wnd > 0) and (MsgID > 0) then
          PostMessage(Wnd, MsgID, 0, 1);

        try
          //read buffer0
          red := lStream.Read(FWorker_Buffers[0][1], BUF_SZ);

          if red > gMin_SigLen -1 then begin
            //reposition file pointer
            if (red = BUF_SZ) and (gMax_SigLen -1 > 0) and (gMax_SigLen < BUF_SZ) then
              lStream.Seek(-(gMax_SigLen -1), soFromCurrent);
            FWorker_BufLen[0] := red;
            FWorkers[0].Done := false;
            SetEvent(FWorkers[0].WaitEvent);

            while (red > 0) and (red > gMin_SigLen -1) and not result do begin

              //get next worker that is done
              WorkerIndex := -1;
              i := 0;
              while (i <= FWorker_Max) and (WorkerIndex < 0) do begin
                if FWorkers[i].Done then
                  WorkerIndex := i;

                Inc(i);
              end;

              if WorkerIndex > -1 then begin
                if FWorkers[WorkerIndex].SearchResult > -1 then begin
                  //signature found...
                  lVirus := PVirusDefinition(gSignatures[FWorkers[WorkerIndex].SearchResult]);
                  StrPLCopy(AVirusName, lVirus^.Name, ANameLength);
                  result := true;
                end else begin
                  //read buffer
                  red := lStream.Read(FWorker_Buffers[WorkerIndex][1], BUF_SZ);
                  //reposition file pointer
                  if (red = BUF_SZ) and (gMax_SigLen -1 > 0) and (gMax_SigLen < BUF_SZ) then
                    lStream.Seek(-(gMax_SigLen -1), soFromCurrent);
                  FWorker_BufLen[WorkerIndex] := red;

                  Inc(steps);
                  if (Wnd > 0) and (MsgID > 0) and (totsteps >= PROGRESS_MIN_STEPS) then
                    PostMessage(Wnd, MsgID, Round((steps/totsteps) *100), 1);

                  FWorkers[WorkerIndex].Done := false;
                  SetEvent(FWorkers[WorkerIndex].WaitEvent);
                end;
              end;

            end;

            //wait for all workers to finish
            repeat
              alldone := true;
              i := 0;
              while (i <= FWorker_Max) and alldone do begin
                alldone := FWorkers[i].Done;
                Inc(i);
              end;
            until alldone;

            if not result then begin
              i := 0;
              while (i <= FWorker_Max) and not result do begin
                if FWorkers[i].SearchResult > -1 then begin
                  lVirus := PVirusDefinition(gSignatures[FWorkers[i].SearchResult]);

                  StrPLCopy(AVirusName, lVirus^.Name, ANameLength);
                  result := true;
                end;

                Inc(i);
              end;

            end;
          end;

        finally
          for i := 0 to FWorker_Max do
            FWorker_BufLen[i] := 0;
        end;


        if (Wnd > 0) and (MsgID > 0) and (totsteps >= PROGRESS_MIN_STEPS) then
          PostMessage(Wnd, MsgID, 100, 1);

      finally
        lStream.Free;
      end;
    except
      // result about not accessable file??
      raise EStreamError.Create('Unable to open file');
    end;

  end;
end;

procedure InitWorkers;
var
  i : integer;
begin
  for i := 0 to FWorker_Max do begin
    SetLength(FWorker_Buffers[i], BUF_SZ);
    FWorker_BufLen[i] := 0;
    FWorkers[i] := TWorkerThread.Create;
    FWorkers[i].FTag := i;
  end;
end;

procedure KillTheWorkers;
var
  i : integer;
begin
  for i := 0 to FWorker_Max do begin
    FWorkers[i].Terminate;
    SetEvent(FWorkers[i].WaitEvent);
  end;
end;

initialization
  InitWorkers;

finalization
  KillTheWorkers;



{$ELSE} //no worker threads

var
 Main_Buffer : string;

Function Search(const AFilename: PChar; const AVirusName: PChar; const ANameLength: integer;
                Wnd, MsgID: integer): Boolean;
var
 lStream: TStream;
 lVirus: PVirusDefinition;
 red : Integer;
 sz : int64;
 steps, totsteps : integer;
 pattern : string;
 res : boolean;
begin
  result := false;

  if assigned(gSignatures) then
  begin

    if Length(Main_Buffer) <> BUF_SZ then //safety net
      SetLength(Main_Buffer, BUF_SZ);

    try

  
      lStream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyNone);
      try
        sz := lStream.Size;

        //calc total steps required
        totsteps := 0;
        repeat
          Dec(sz, BUF_SZ);
          Inc(totsteps);
          if (sz > 0) and (gMax_SigLen -1 > 0) and (gMax_SigLen < BUF_SZ) then
            Inc(sz, gMax_SigLen);
        until sz < 1;
        steps := 0;

        if (Wnd > 0) and (MsgID > 0) then
          PostMessage(Wnd, MsgID, 0, 1);

        red := lStream.Read(Main_Buffer[1], BUF_SZ);

        while (red > 0) and (red > gMin_SigLen -1) do begin

          Inc(steps);
          if (Wnd > 0) and (MsgID > 0) and (totsteps >= PROGRESS_MIN_STEPS) then
            PostMessage(Wnd, MsgID, Round((steps/totsteps) *100), 1);


          lVirus := PVirusDefinition(gSignatures[0]);
          pattern := '';
          while (lVirus <> nil) and not result do begin
            if lVirus^.Pattern = 'then begin
              //no pattern
              pattern := '';
              result := FastPos( Main_Buffer,
                                 lVirus^.Signature,
                                 red,
                                 lVirus^.SigLen, 1) > 0;
            end else begin
              if lVirus^.Pattern = pattern then begin
                //buffer contains pattern
                result := FastPos( Main_Buffer,
                                   lVirus^.Signature,
                                   red,
                                   lVirus^.SigLen, 1) > 0;
              end else begin
                //new pattern
                pattern := lVirus^.Pattern;

                res := FastPos( Main_Buffer,
                                pattern,
                                red,
                                Length(pattern), 1) > 0;

                if not res then begin
                  //pattern not found so
                  //find next pattern...
                  lVirus := lVirus^.NextPattern;
                  continue;
                end else begin
                  //pattern found
                  result := FastPos( Main_Buffer,
                                     lVirus^.Signature,
                                     red,
                                     lVirus^.SigLen, 1) > 0;
                end;
              end;
            end;

            if result then begin
              StrPLCopy(AVirusName, lVirus^.Name, ANameLength);
              exit;
            end;

            lVirus := lVirus^.Next;
          end;

          //reposition file pointer
          if (red = BUF_SZ) and (gMax_SigLen -1 > 0) and (gMax_SigLen < BUF_SZ) then
            lStream.Seek(-(gMax_SigLen -1), soFromCurrent);

          red := lStream.Read(Main_Buffer[1], BUF_SZ);
        end;

        if (Wnd > 0) and (MsgID > 0) and (totsteps >= PROGRESS_MIN_STEPS) then
          PostMessage(Wnd, MsgID, 100, 1);

      finally
        lStream.Free;
      end;
    except
      // result about not accessable file??
      raise EStreamError.Create('Unable to open file');
    end;

  end;
end;

{$ENDIF}


end.
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: What's incorrect with this

  Alt 23. Jan 2009, 22:40
PVirusDefinition?
  Mit Zitat antworten Zitat
mohfa

Registriert seit: 11. Feb 2007
97 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: What's incorrect with this

  Alt 23. Jan 2009, 22:56
PVirusDefinition is Declared like this way :


Delphi-Quellcode:
PVirusDefinition = ^TVirusDefinition;
 TVirusDefinition = record
   Signature: String;
   Name: string;
   SigLen : integer;
   Pattern : string;
   Next,NextPattern : PVirusDefinition;
Omata Any help please
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: What's incorrect with this

  Alt 23. Jan 2009, 23:03
Can you give me an example with function and searchstring + result that you would have?

What is gSignatures?
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:32 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