Page 3 of 3 FirstFirst 123
Results 51 to 64 of 64

Thread: Script Scanner (Scans for malicious scripts)

  1. #51
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Janilabo View Post
    Source code @pastebin: http://pastebin.com/raw.php?i=mcdPXv9A

    EDIT: Attached unofficial version 1.36, removed Find() from the script, because it's just like FindEx() without "regex: Boolean" variable part. So, those Find() parts are now based on FindEx() instead. This change doesn't have any effect on the way script works, just cuts out some unneeded lines.
    ..and source for v1.36: http://pastebin.com/raw.php?i=81b5UDJN

    By the way! With FindEx()-based counting I got this script to detect some sneaky password stealing attempts, good example below (something that none of the older versions could catch):

    The stealing script example:
    Code:
    // {sc} = SNEAKY COMMENT!
    // (*sc*) = SNEAKY COMMENT!
    
    type // This is here for only this example.
      TPlayer = record
        Name, Pass, Nick: string;
      end;
    
    var
      Players: array[0..0] of TPlayer;
      un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := 'StealMyGeepeesPlease!';
      Players[0].Pass := 'MySimplePassword1234';
      Players[0].Nick := 'eepees';
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS {sc}  [ (*sc*)   0 {sc}   ]   (*sc*)   .NAME {sc}; // It will catch this attempt.
      pw := PlAyErs (*sc*)  [ {sc} 0  {sc}  ] {sc} . (*sc*) PaSs (*sc*); // It will catch this attempt.
      WriteLn('USERNAME: "' + un + '"');
      WriteLn('PASSWORD: "' + pw + '"');
    end.
    Scan results for that little example script:

    Code:
    =================Filtered Script=================
    @@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    type @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      TPlayer = record
        Name, Pass, Nick: string;
      end;
    
    var
      Players: array[0..0] of TPlayer;
      un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := %%%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Pass := %%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Nick := %%%%%%%%;
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS @@@@  [ @@@@@@   0 @@@@   ]   @@@@@@   .NAME @@@@;
      pw := PlAyErs @@@@@@  [ @@@@ 0  @@@@  ] @@@@ . @@@@@@ PaSs @@@@@@;
      WriteLn(%%%%%%%%%%%%% + un + %%%);
      WriteLn(%%%%%%%%%%%%% + pw + %%%);
    end.
    =================================================
    
    ============Looking for HTTP threats=============
    =================================================
    
    ============Looking for Abnormal code============
    The variable "Name" is used more then once [Risk level: MEDIUM]
    The variable "Pass" is used more then once [Risk level: MEDIUM]
    =================================================
    
    ==============Looking for bad code===============
    Found no randomness in script [Risk level: MEDIUM], potential ban.
    =================================================
    
    ==================Scan Results===================
    HTTP threats: 0
    Web threats: 0
    Fishy code: 2
    Bad code: 1
    Overall threats: 3
    Over Script Risk: Medium
    Thank you for using, always visit thread for updates
    =================================================
    Also, notice that the scan doesn't look for only NAME/PASS/PIN anymore, it actually requires that there are those "Players[*]." (*=ID) things attached to em. That means, it wont pick up simple "Pass", "Name" or "Pin" words from script, ONLY if those words are attached to players variable[s] aswell.

    It also ignores the comments and spaces, as you can see with the example I added there, so you really cant fool or cheat it with any sneaky attempts like that!
    I tweaked those HTTP threat scans with similar ways, too.
    Very nice, should I add option for it to save filtered script to a .txt file for review?

  2. #52
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    Very nice, should I add option for it to save filtered script to a .txt file for review?
    If you want to mate.

    Do note that, script sees all those STRING_FILTER's (%) and COMMENT_FILTER's (@) as " " (empty char), this is 1 way to detect spaced texts using regex matching.
    Those filter characters I used only to display those parts it will pick up as comments/strings - mainly to see that it detects every comment and string correctly, which it indeed does.

    But yeah, feel free to do just any changes you need/want to!

    -Jani
    Attached Files Attached Files
    Last edited by Janilabo; 06-09-2013 at 08:17 AM. Reason: 1.39 - Fixed endless loop error in TrackCaS function (that occurred with // -comments sometimes)

  3. #53
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Bumping this topic up with a good reason: Version 1.40 is OUT!

    Changelog:
    Code:
    -Fixed FindHTTPThreats (it detected threats only if there were 2 or more of certain HTTP-threat, whereas now it starts picking up from the very first one, just like it should be)
    -Detects now players with ANY ID, even if someone tries to trick the system by using custom integer variable[s] (so it doesn't scan for digits only, like it used to)
    -Detects attempts of using ToStr() with Players[*] variable, this could be used for sending player data to variable (*=any ID)
    Improved the detection a lot.

    Small example below, about password stealing attempt using sneaky tricks, that this script WILL pick up:
    Code:
    // {sc} = SNEAKY COMMENT!
    // (*sc*) = SNEAKY COMMENT!
    
    type // This is here for only this example.
      TPlayer = record
        Name, Pass, Nick, Pin: string;
      end;
    
    var
      ID: Integer;
      Players: array[0..0] of TPlayer;
      pn, un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := 'StealMyGeepeesPlease!';
      Players[0].Pass := 'MySimplePassword1234';
      Players[0].Nick := 'eepees';
      Players[0].Pin := '1234';
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS {sc}  [ (*sc*)   0 {sc}   ]   (*sc*)   .NAME {sc}; // It will catch this attempt.
      pw := PlAyErs (*sc*)  [ {sc} StrToInt(#48)  {sc}  ] {sc} . (*sc*) PaSs (*sc*); // It will catch this attempt.
      ID := 0;
      pn := players[ID].Pin;
      WriteLn('USERNAME: "' + un + '"');
      WriteLn('PASSWORD: "' + pw + '"');
      WriteLn('PIN: "' + pn + '"');
      WriteLn(ToStr(Players[0]));
    end.
    ..and scan results:

    Code:
    =================Filtered Script=================
    @@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    type @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      TPlayer = record
        Name, Pass, Nick, Pin: string;
      end;
    
    var
      ID: Integer;
      Players: array[0..0] of TPlayer;
      pn, un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := %%%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Pass := %%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Nick := %%%%%%%%;
      Players[0].Pin := %%%%%%;
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS @@@@  [ @@@@@@   0 @@@@   ]   @@@@@@   .NAME @@@@; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      pw := PlAyErs @@@@@@  [ @@@@ StrToInt(#48)  @@@@  ] @@@@ . @@@@@@ PaSs @@@@@@; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      ID := 0;
      pn := players[ID].Pin;
      WriteLn(%%%%%%%%%%%%% + un + %%%);
      WriteLn(%%%%%%%%%%%%% + pw + %%%);
      WriteLn(%%%%%%%% + pn + %%%);
      WriteLn(ToStr(Players[0]));
    end.
    =================================================
    
    ============Looking for HTTP threats=============
    =================================================
    
    ============Looking for Abnormal code============
    The variable "Name" is used more then once [Risk level: MEDIUM]
    The variable "Pass" is used more then once [Risk level: MEDIUM]
    The variable "Pin" is used more then once [Risk level: MEDIUM]
    Player data sent to ToStr() [Risk level: MEDIUM]
    =================================================
    
    ==============Looking for bad code===============
    Found no randomness in script [Risk level: MEDIUM], potential ban.
    =================================================
    
    ==================Scan Results===================
    HTTP threats: 0
    Web threats: 0
    Fishy code: 4
    Bad code: 1
    Overall threats: 5
    Over Script Risk: High
    Thank you for using, always visit thread for updates
    =================================================
    Attached Files Attached Files
    Last edited by Janilabo; 06-09-2013 at 10:38 AM.

  4. #54
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Janilabo View Post
    Bumping this topic up with a good reason: Version 1.40 is OUT!

    Changelog:
    Code:
    -Fixed FindHTTPThreats (it detected threats only if there were 2 or more of certain HTTP-threat, whereas now it starts picking up from the very first one, just like it should be)
    -Detects now players with ANY ID, even if someone tries to trick the system by using custom integer variable[s] (so it doesn't scan for digits only, like it used to)
    -Detects attempts of using ToStr() with Players[*] variable, this could be used for sending player data to variable (*=any ID)
    Improved the detection a lot.

    Small example below, about password stealing attempt using sneaky tricks, that this script WILL pick up:
    Code:
    // {sc} = SNEAKY COMMENT!
    // (*sc*) = SNEAKY COMMENT!
    
    type // This is here for only this example.
      TPlayer = record
        Name, Pass, Nick, Pin: string;
      end;
    
    var
      ID: Integer;
      Players: array[0..0] of TPlayer;
      pn, un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := 'StealMyGeepeesPlease!';
      Players[0].Pass := 'MySimplePassword1234';
      Players[0].Nick := 'eepees';
      Players[0].Pin := '1234';
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS {sc}  [ (*sc*)   0 {sc}   ]   (*sc*)   .NAME {sc}; // It will catch this attempt.
      pw := PlAyErs (*sc*)  [ {sc} StrToInt(#48)  {sc}  ] {sc} . (*sc*) PaSs (*sc*); // It will catch this attempt.
      ID := 0;
      pn := players[ID].Pin;
      WriteLn('USERNAME: "' + un + '"');
      WriteLn('PASSWORD: "' + pw + '"');
      WriteLn('PIN: "' + pn + '"');
      WriteLn(ToStr(Players[0]));
    end.
    ..and scan results:

    Code:
    =================Filtered Script=================
    @@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    type @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      TPlayer = record
        Name, Pass, Nick, Pin: string;
      end;
    
    var
      ID: Integer;
      Players: array[0..0] of TPlayer;
      pn, un, pw: string;
    
    procedure DeclarePlayers;
    begin
      Players[0].Name := %%%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Pass := %%%%%%%%%%%%%%%%%%%%%%;
      Players[0].Nick := %%%%%%%%;
      Players[0].Pin := %%%%%%;
    end;
    
    begin
      ClearDebug;
      DeclarePlayers;
      un := PLAYERS @@@@  [ @@@@@@   0 @@@@   ]   @@@@@@   .NAME @@@@; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      pw := PlAyErs @@@@@@  [ @@@@ StrToInt(#48)  @@@@  ] @@@@ . @@@@@@ PaSs @@@@@@; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
      ID := 0;
      pn := players[ID].Pin;
      WriteLn(%%%%%%%%%%%%% + un + %%%);
      WriteLn(%%%%%%%%%%%%% + pw + %%%);
      WriteLn(%%%%%%%% + pn + %%%);
      WriteLn(ToStr(Players[0]));
    end.
    =================================================
    
    ============Looking for HTTP threats=============
    =================================================
    
    ============Looking for Abnormal code============
    The variable "Name" is used more then once [Risk level: MEDIUM]
    The variable "Pass" is used more then once [Risk level: MEDIUM]
    The variable "Pin" is used more then once [Risk level: MEDIUM]
    Player data sent to ToStr() [Risk level: MEDIUM]
    =================================================
    
    ==============Looking for bad code===============
    Found no randomness in script [Risk level: MEDIUM], potential ban.
    =================================================
    
    ==================Scan Results===================
    HTTP threats: 0
    Web threats: 0
    Fishy code: 4
    Bad code: 1
    Overall threats: 5
    Over Script Risk: High
    Thank you for using, always visit thread for updates
    =================================================
    I think I'll be ale to merge this in about 12 hours!

  5. #55
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    I think I'll be ale to merge this in about 12 hours!
    That's grrrreat, OB!
    Can't wait to see those GUI improvements/tweaks you have been talking about..

    By the way, I am still going... Here is v1.41:
    Code:
    {=======================================================================================]
    |                                                                                       |
    |   _____ _       _          _____         _     _      _____                           |
    |  |   __|_|_____| |_ ___   |   __|___ ___|_|___| |_   |   __|___ ___ ___ ___ ___ ___   |
    |  |__   | |     | . | .'|  |__   |  _|  _| | . |  _|  |__   |  _| .'|   |   | -_|  _|  |
    |  |_____|_|_|_|_|___|__,|  |_____|___|_| |_|  _|_|    |_____|___|__,|_|_|_|_|___|_|    |
    |                                         |_|                                           |
    |                                                                                       |
    [=======================================================================================}
    
    {$i SRL/SRL.simba}
    
    const
      VERSION = '1.41'; // Don't touch... Script version.
      FILTER_COMMENTS = True; // Doesn't pay attention to stuff inside comments
                              // Recommended to keep this feature enabled, a lot less false positives!
      COMMENT_FILTER = '@'; // CHAR, NOT STRING! Used in debug box for displaying the filtered comments (doesn't effect scan, as these will be empty chars in filteredScriptText for scan).
      FILTER_STRINGS = True; // Doesn't pay attention to stuff INSIDE string signs.
                             // So, this feature still detects stuff that falls outside those '' signs! :)
      STRING_FILTER = '%'; // CHAR, NOT STRING! Used in debug box for displaying the filtered strings (doesn't effect scan, these will be empty chars in filteredScriptText for scan).
      DEBUG_FILTERED_SCRIPT = True; // Debug the script, that was filtered (used for most script parts), before scan statistics (displays empty chars with COMMENT_FILTER & STRING_FILTER).
      DEFAULT = 'Times New Roman';
    
    type
      TMatchMethod = (mmAll, mmIgnoreCase, mmOverlap, mmWholeWords, mmStrictWW);
      TMatchMethods = set of TMatchMethod;
      TRegexMatch = record
        position, size: Integer;
        text: string;
      end;
      TRegexMatchArray = array of TRegexMatch;
      T2DRegexMatchArray = array of TRegexMatchArray;
      TRange = record
        minimum, maximum: Integer;
      end;
      TRangeArray = array of TRange;
    
    var
      DsgnForm: TForm;
      ScriptEdit: TMemo;
      TitleLabel: TLabel;
      ScanButton, UpdateButton: TButton;
      originalScriptText, filteredScriptText, displayScriptText: string;
      HTTPThreats, WebThreats, BadCode, threats, Fishy: Integer;
      pressed: Boolean;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure PrintReport;
    var
      Points:Integer;
    begin
      Points := (HTTPthreats + WebThreats + BadCode + Fishy);
      WriteLn('');
      WriteLn('==================Scan Results===================');
      WriteLn('HTTP threats: ' + ToStr(HTTPThreats));
      WriteLn('Web threats: ' + ToStr(WebThreats));
      WriteLn('Fishy code: ' + ToStr(Fishy));
      WriteLn('Bad code: ' + ToStr(BadCode));
      WriteLn('Overall threats: ' + ToStr(Points))
      case threats of
        0:    WriteLn('Over Script Risk: None');
        1..2: WriteLn('Over Script Risk: Low');
        3:    WriteLn('Over Script Risk: Medium');
        4..8: WriteLn('Over Script Risk: High');
      end;
      WriteLn('Thank you for using, always visit thread for updates');
      WriteLn('=================================================');
    end;
    
    {==============================================================================]
      Explanation: Finds position from s items in str. Stores the ID of the found s item to index variable.
                   The importance order for d items is from left to right (=>).
                   So place the important ones first and then less important after those.
                   Contains field for offset.
    [==============================================================================}
    function PosMultiIDEx(s: TStringArray; str: string; var index: Integer; offset: Integer): Integer;
    var
      h, i, p, t: Integer;
    begin
      if (offset < 1) then
        offset := 1;
      Result := -1;
      index := -1;
      h := High(s);
      if ((h > -1) and (str <> '')) then
      begin
        t := (Length(str) + 1);
        Result := t;
        for i := 0 to h do
        begin
          p := PosEx(s[i], str, offset);
          if ((p > 0) and (p < Result)) then
          begin
            Result := p;
            index := i;
          end;
        end;
        if (Result = t) then
          Result := 0;
      end;
    end;
    
    function ToRange(minimum, maximum: Integer): TRange;
    begin
      Result.minimum := Integer(minimum);
      Result.maximum := Integer(maximum);
    end;
    
    procedure TRAAppend(var TRA: TRangeArray; x: TRange);
    var
      aL: Integer;
    begin
      aL := (Length(TRA) + 1);
      SetLength(TRA, aL);
      TRA[(aL - 1)] := TRange(x);
    end;
    
    function TrackCaS(str: string; var comments, strings: TRangeArray): Boolean;
    var
      s, i, o, e, x, l, a, ls: Integer;
      t: TStringArray;
    begin
      Result := False;
      SetLength(comments, 0);
      SetLength(strings, 0);
      l := Length(str);
      ls := -1;
      if (l > 0) then
      begin
        o := 1;
        t := ['//', '(*', '{', ''''];
        repeat
          s := PosMultiIDEx(t, str, i, o);
          case (s <= ls) of
            True: Exit;
            False: ls := s;
          end;
          if (s > 0) then
          begin
            o := (s + 1);
            a := 0;
            case i of
              0, 1, 2:
              begin
                case i of
                  0:
                  begin
                    e := PosMultiIDEx([#13#10, #13, #10], str, x, o);
                    if (x = 0) then
                      a := 1;
                    if (e = 0) then
                      e := l;
                    TRAAppend(comments, ToRange(s, e));
                  end;
                  1, 2:
                  begin
                    case i of
                      1:
                      begin
                        e := PosEx('*)', str, o);
                        a := 1;
                      end;
                      2: e := PosEx('}', str, o);
                    end;
                    if (e = 0) then
                      e := l;
                    TRAAppend(comments, ToRange(s, (e + a)));
                  end;
                end;
              end;
              3:
              begin
                e := PosMultiIDEx([#13#10, #13, #10, ''''], str, x, o);
                if (x = 0) then
                  a := 1;
                case (e = 0) of
                  True:
                  begin
                    e := l;
                    TRAAppend(strings, ToRange(s, e));
                  end;
                  False:
                  case x of
                    0, 1, 2: TRAAppend(strings, ToRange(s, e));
                    3: TRAAppend(strings, ToRange(s, (e + a)));
                  end;
                end;
              end;
            end;
            o := ((e + 1) + a);
          end;
        until ((s = 0) or (x = -1) or (o > l));
      end;
    end;
    
    {==============================================================================]
      Explanation: Returns all the positions by items from s array in str. Place s items in importance order (=>)
                   If overlap is set to true, strings can overlap.
                   (['aa'], 'baaaah', False) => [2,3,4]
                   (['aa'], 'baaaah', True) => [2,4]
    [==============================================================================}
    function PosAllMulti(s: TStringArray; str: string; overlap: Boolean): TIntegerArray;
    var
      h, l, p, o, x, i, t, r, y, d: Integer;
    begin
      h := High(s);
      y := Length(str);
      if ((y > 0) and (h > -1)) then
      begin
        SetLength(Result, y);
        o := 1;
        repeat
          p := 0;
          for x := 0 to h do
          begin
            t := PosEx(s[x], str, (l + o));
            case (t < 1) of
              True:
              begin
                for d := x to (h - 1) do
                  s[d] := s[(d + 1)];
                SetLength(s, h);
                Dec(x);
                Dec(h);
              end;
              False:
              if ((p = 0) or (t < p)) then
              begin
                p := t;
                i := x;
              end;
            end;
          end;
          if (p > 0) then
          begin
            Result[r] := p;
            Inc(r);
            l := p;
            if not overlap then
              o := Length(s[i]);
          end;
        until (p <= 0);
      end;
      SetLength(Result, r);
    end;
    
    procedure FillStrRangeEx(var str: string; fillWith: Char; range: TRange; exceptions: TIntegerArray);
    var
      i, l, c: Integer;
    begin
      l := Length(str);
      if ((l > 0) and not (range.minimum > range.maximum)) then
      begin
        if (range.minimum < 1) then
          range.minimum := 1;
        if (range.maximum > l) then
          range.maximum := l;
        if (range.minimum > l) then
          Exit;
        c := iAbs(range.maximum - range.minimum);
        for i := range.minimum to range.maximum do
          if not InIntArray(exceptions, i) then
            str[i] := fillWith;
      end;
    end;
    
    {==============================================================================]
      Explanation: Function for tracing findStr's from data. Stores matched items and positions to 'items' and 'positions' variables.
                   Contains also custom fields for regexTags and regexStrs;
                   each tag performs a regex action, that is set to regexStrs, during the search.
                   If cs variable is set as true, then the search will be case-sensitive.
    [==============================================================================}
    function TraceStrsEx(findStr: string; regexTags: array of Char; regexStrs: TStringArray; data: string; cs: Boolean; var items: TStringArray; var positions: TIntegerArray): Boolean;
    var
      re: TRegExp;
      p, l, r, s, c, h, t: Integer;
      q: string;
    begin
      l := Length(data);
      s := Length(findStr);
      if ((l > 0) and (s > 0)) then
      begin
        h := High(regexTags);
        if (High(regexStrs) < h) then
          SetLength(regexStrs, (h + 1));
        SetLength(items, l);
        SetLength(positions, l);
        q := '.\+*?[^]$(){}=!<>|:-';
        for c := h downto 0 do
        begin
          t := Pos(q, regexTags[c]);
          if (t > 0) then
            Delete(q, t, 1);
        end;
        for c := s downto 1 do
          if (Pos(findStr[c], q) > 0) then
            Insert('\', findStr, c);
        for t := 0 to h do
          findStr := ReplaceWrap(findStr, regexTags[t], regexStrs[t], [rfReplaceAll]);
        re := TRegExp.Create;
        re.ModifierI := not cs;
        re.ModifierG := False;
        re.Expression := findStr;
        re.InputString := data;
        p := 1;
        if re.ExecPos(p) then
        repeat
          if (re.Match[0] <> '') then
          begin
            p := (re.MatchPos[0] + 1);
            positions[r] := re.MatchPos[0];
            items[r] := Copy(data, re.MatchPos[0], re.MatchLen[0]);
            Inc(r);
          end;
        until not re.ExecPos(p);
        re.Free;
      end else
        Result := False;
      Result := (r > 0);
      SetLength(positions, r);
      SetLength(items, r);
    end;
    
    {==============================================================================]
      Explanation: Function for tracing findStr's from data.
                   Contains also custom fields for regexTag and regexStr;
                   tag performs a regex action, that is set to regexStr, during the search.
                   If cs variable is set as true, then the search will be case-sensitive.
    [==============================================================================}
    function TraceStrPositions(findStr: string; regexTag: Char; regexStr, data: string; cs: Boolean): TIntegerArray;
    var
      tmp: TStringArray;
    begin
      TraceStrsEx(findStr, [regexTag], [regexStr], data, cs, tmp, Result);
      SetLength(tmp, 0);
    end;
    
    {==============================================================================]
      Explanation: Function for tracing findStr's from data.
                   Contains also custom fields for regexTag and regexStr;
                   tag performs a regex action, that is set to regexStr, during the search.
                   If cs variable is set as true, then the search will be case-sensitive.
    [==============================================================================}
    function TraceStrItems(findStr: string; regexTag: Char; regexStr, data: string; cs: Boolean): TStringArray;
    var
      tmp: TIntegerArray;
    begin
      TraceStrsEx(findStr, [regexTag], [regexStr], data, cs, Result, tmp);
      SetLength(tmp, 0);
    end;
    
    function SpacedTextCount(findStr: string; spaceTag: Char; data: string): Integer;
    begin
      Result := Length(TraceStrPositions(findStr, spaceTag, '(\s)*', data, False));
    end;
    
    function DetectSpacedText(findStr: string; spaceTag: Char; data: string): Boolean;
    begin
      Result := (SpacedTextCount(findStr, spaceTag, data) > 0);
    end;
    
    function FilterScriptData(data: string): string;
    var
      h, i, l: Integer;
      newLines: TIntegerArray;
      comments, strings: TRangeArray;
    begin
      Result := string(data);
      displayScriptText := string(Result);
      l := Length(Result);
      if ((Result <> '') and (FILTER_STRINGS or FILTER_COMMENTS)) then
      begin
        newLines := PosAllMulti([#13, #10], Result, False);
        TrackCaS(data, comments, strings);
        h := High(comments);
        if FILTER_COMMENTS then
        for i := 0 to h do
        begin
          FillStrRangeEx(Result, ' ', comments[i], newLines);
          FillStrRangeEx(displayScriptText, COMMENT_FILTER, comments[i], newLines);
        end;
        h := High(strings);
        if FILTER_COMMENTS then
        for i := 0 to h do
        begin
          FillStrRangeEx(Result, ' ', strings[i], newLines);
          FillStrRangeEx(displayScriptText, STRING_FILTER, strings[i], newLines);
        end;
      end;
      SetLength(newLines, 0);
      SetLength(comments, 0);
      SetLength(strings, 0);
    end;
    
    {==============================================================================]
      Explanation: Returns all the positions of found/matching strings (findStr) in text.
                   Uses a set of TMatchMethod (methods) for string matching.
                   Contains field for offset.
                   If regex field is set as true, then this function searches for the regex you use.
    [==============================================================================}
    function FindEx(text, findStr: string; methods: TMatchMethods; offset: Integer; regex: Boolean): TIntegerArray;
    var
      rmArr: TRegexMatchArray;
      rmArr2D: T2DRegexMatchArray;
      sb, sa: string;
      r, i, l, f, p, d, o, x, y, abL, abR, abX, abP, spA, spB, spH, spL, spI, spR, spD: Integer;
      re: TRegExp;
      ma, mb, a, s, ol: Boolean;
      c: TIntegerArray;
      t: T2DIntegerArray;
    begin
      l := Length(text);
      f := Length(findStr);
      if ((l > 0) and (f > 0) and (offset <= (l - f))) then
      begin
        if (offset < 1) then
          offset := 1;
        if not regex then
        begin
          for i := f downto 1 do
            if (Pos(findStr[i], '.\+*?[^]$(){}=!<>|:-') > 0) then
              Insert('\', findStr, i);
          SetLength(Result, l);
          re := TRegExp.Create;
          re.InputString := text;
          re.Expression := findStr;
          if (mmIgnoreCase in methods) then
            re.ModifierI := True;
          a := (mmAll in methods);
          case a of
            False: re.ModifierG := True;
            True: re.ModifierG := False;
          end;
          re.ModifierM := True;
          ol := (mmOverlap in methods);
          if not ol then
            o := (Length(findStr) - 1);
          Inc(o);
          p := offset;
          while re.ExecPos(p) do
          begin
            Result[r] := re.MatchPos[0];
            p := (Result[r] + o);
            Inc(r);
          end;
          p := Offset;
          re.Free;
          SetLength(Result, r);
          if ((r > 0) and (mmWholeWords in methods)) then
          begin
            s := (mmStrictWW in methods);
            if not s then
              c := [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, // A-Z
                    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, // a-z
                    48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // 0-9
            case ol of
              True:
              begin
                spH := High(Result);
                if (spH > -1) then
                begin
                  SetLength(t, (spH + 1));
                  t[0] := [Integer(Result[0])];
                  if (spH > 0) then
                  begin
                    spR := 1;
                    for spI := 1 to spH do
                    begin
                      for spA := 0 to (spR - 1) do
                      begin
                        spL := Length(t[spA]);
                        for spB := 0 to (spL - 1) do
                        begin
                          spD := IAbs(Result[spI] - t[spA][spB]);
                          if (spD <= f) then
                          begin
                            SetLength(t[spA], (spL + 1));
                            t[spA][spL] := Integer(Result[spI]);
                            Break;
                          end;
                        end;
                        if (spB < spL) then
                          Break;
                      end;
                      if (spA >= spR) then
                      begin
                        t[spR] := [Integer(Result[spI])];
                        Inc(spR);
                      end;
                    end;
                  end;
                  SetLength(t, spR);
                  spH := High(t);
                  for spI := spH downto 0 do
                  begin
                    spB := Low(t[spI]);
                    spA := High(t[spI]);
                    abX := 1;
                    abP := t[spI][spB];
                    abL := Length(text);
                    case ((abL > 0) and (abP > 1)) of
                      True:
                      begin
                        if ((abP - abX) < 1) then
                          abX := ((abP - abX) + (abX - 1));
                        if (abP > (abL + 1)) then
                        begin
                          abR := ((abP - abL) - 1);
                          abX := (abX - abR);
                        end;
                        sb := Copy(text, ((abP - abX) - abR), abX);
                      end;
                      False: sb := '';
                    end;
                    abX := 1;
                    abP := (t[spI][spA] + f);
                    abL := Length(text);
                    case ((abL > 0) and (abP <= abL)) of
                      True:
                      begin
                        if (abP < 1) then
                        begin
                          abX := (abX - iAbs(abP - 1));
                          abP := 1;
                        end;
                        if ((abX > 0) and ((abP + abX) > abL)) then
                          abX := (abX - (((abP + abX) - abL) - 1));
                        sa := Copy(text, abP, abX);
                      end;
                      False: sa := '';
                    end;
                    case s of
                      True:
                      begin
                        mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                        ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                      end;
                      False:
                      begin
                        mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                        ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                      end;
                    end;
                    if not (mb and ma) then
                    begin
                      for spD := spI to (spH - 1) do
                        t[spD] := t[(spD + 1)];
                      SetLength(t, spH);
                      Dec(spH);
                    end;
                  end;
                  spH := High(t);
                  if (spH > -1) then
                  begin
                    for spI := 0 to spH do
                      IncEx(spR, (High(t[spI]) + 1));
                    SetLength(Result, spR);
                    spR := 0;
                    for spI := 0 to spH do
                    begin
                      spL := High(t[spI]);
                      for spA := 0 to spL do
                      begin
                        Result[spR] := Integer(t[spI][spA]);
                        Inc(spR);
                      end;
                    end;
                    SetLength(Result, spR);
                  end else
                    SetLength(Result, 0);
                end else
                  r := 0;
              end;
              False:
              begin
                for x := (r - 1) downto 0 do
                begin
                  abX := 1;
                  abP := Result[x];
                  abL := Length(text);
                  case ((abL > 0) and (abP > 1)) of
                    True:
                    begin
                      if ((abP - abX) < 1) then
                        abX := ((abP - abX) + (abX - 1));
                      if (abP > (abL + 1)) then
                      begin
                        abR := ((abP - abL) - 1);
                        abX := (abX - abR);
                      end;
                      sb := Copy(text, ((abP - abX) - abR), abX);
                    end;
                    False: sb := '';
                  end;
                  abX := 1;
                  abP := (Result[x] + f);
                  abL := Length(text);
                  case ((abL > 0) and (abP <= abL)) of
                    True:
                    begin
                      if (abP < 1) then
                      begin
                        abX := (abX - iAbs(abP - 1));
                        abP := 1;
                      end;
                      if ((abX > 0) and ((abP + abX) > abL)) then
                        abX := (abX - (((abP + abX) - abL) - 1));
                      sa := Copy(text, abP, abX);
                    end;
                    False: sa := '';
                  end;
                  case s of
                    True:
                    begin
                      mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                      ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                    end;
                    False:
                    begin
                      mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                      ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                    end;
                  end;
                  if not (mb and ma) then
                  begin
                    y := (r - 1);
                    for d := x to (y - 1) do
                      Result[d] := Result[(d + 1)];
                    SetLength(Result, y);
                    Dec(r);
                  end;
                end;
              end;
            end;
          end;
          if (not a and (r > 0)) then
            SetLength(Result, 1);
        end else
        begin
          SetLength(rmArr, l);
          re := TRegExp.Create;
          re.InputString := text;
          re.Expression := findStr;
          if (mmIgnoreCase in methods) then
            re.ModifierI := True;
          a := (mmAll in methods);
          case a of
            False: re.ModifierG := True;
            True: re.ModifierG := False;
          end;
          re.ModifierM := True;
          ol := (mmOverlap in methods);
          p := offset;
          while re.ExecPos(p) do
          begin
            rmArr[r].position := re.MatchPos[0];
            rmArr[r].text := re.Match[0];
            rmArr[r].size := re.MatchLen[0];
            if ol then
              p := (rmArr[r].position + 1)
            else
              p := (rmArr[r].position + rmArr[r].size);
            Inc(r);
          end;
          p := Offset;
          re.Free;
          SetLength(rmArr, r);
          if ((r > 0) and (mmWholeWords in methods)) then
          begin
            s := (mmStrictWW in methods);
            if not s then
              c := [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, // A-Z
                    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, // a-z
                    48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // 0-9
            case ol of
              True:
              begin
                spH := High(rmArr);
                if (spH > -1) then
                begin
                  SetLength(rmArr2D, (spH + 1));
                  rmArr2D[0] := [TRegexMatch(rmArr[0])];
                  if (spH > 0) then
                  begin
                    spR := 1;
                    for spI := 1 to spH do
                    begin
                      for spA := 0 to (spR - 1) do
                      begin
                        spL := Length(rmArr2D[spA]);
                        for spB := 0 to (spL - 1) do
                        begin
                          spD := IAbs(rmArr[spI].position - rmArr2D[spA][spB].position);
                          if (spD <= rmArr2D[spA][spB].size) then
                          begin
                            SetLength(rmArr2D[spA], (spL + 1));
                            rmArr2D[spA][spL] := TRegexMatch(rmArr[spI]);
                            Break;
                          end;
                        end;
                        if (spB < spL) then
                          Break;
                      end;
                      if (spA >= spR) then
                      begin
                        rmArr2D[spR] := [TRegexMatch(rmArr[spI])];
                        Inc(spR);
                      end;
                    end;
                  end;
                  SetLength(rmArr2D, spR);
                  spH := High(rmArr2D);
                  for spI := spH downto 0 do
                  begin
                    spB := Low(rmArr2D[spI]);
                    spA := High(rmArr2D[spI]);
                    abX := 1;
                    abP := rmArr2D[spI][spB].position;
                    abL := Length(text);
                    case ((abL > 0) and (abP > 1)) of
                      True:
                      begin
                        if ((abP - abX) < 1) then
                          abX := ((abP - abX) + (abX - 1));
                        if (abP > (abL + 1)) then
                        begin
                          abR := ((abP - abL) - 1);
                          abX := (abX - abR);
                        end;
                        sb := Copy(text, ((abP - abX) - abR), abX);
                      end;
                      False: sb := '';
                    end;
                    abX := 1;
                    abP := (rmArr2D[spI][spA].position + rmArr2D[spI][spA].size);
                    abL := Length(text);
                    case ((abL > 0) and (abP <= abL)) of
                      True:
                      begin
                        if (abP < 1) then
                        begin
                          abX := (abX - iAbs(abP - 1));
                          abP := 1;
                        end;
                        if ((abX > 0) and ((abP + abX) > abL)) then
                          abX := (abX - (((abP + abX) - abL) - 1));
                        sa := Copy(text, abP, abX);
                      end;
                      False: sa := '';
                    end;
                    case s of
                      True:
                      begin
                        mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                        ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                      end;
                      False:
                      begin
                        mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                        ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                      end;
                    end;
                    if not (mb and ma) then
                    begin
                      for spD := spI to (spH - 1) do
                        rmArr2D[spD] := rmArr2D[(spD + 1)];
                      SetLength(rmArr2D, spH);
                      Dec(spH);
                    end;
                  end;
                  spH := High(rmArr2D);
                  if (spH > -1) then
                  begin
                    for spI := 0 to spH do
                      IncEx(spR, (High(rmArr2D[spI]) + 1));
                    SetLength(rmArr, spR);
                    spR := 0;
                    for spI := 0 to spH do
                    begin
                      spL := High(rmArr2D[spI]);
                      for spA := 0 to spL do
                      begin
                        rmArr[spR] := TRegexMatch(rmArr2D[spI][spA]);
                        Inc(spR);
                      end;
                    end;
                    SetLength(rmArr, spR);
                    r := spR;
                  end else
                    SetLength(rmArr, 0);
                end else
                  r := 0;
              end;
              False:
              begin
                for x := (r - 1) downto 0 do
                begin
                  abX := 1;
                  abP := rmArr[x].position;
                  abL := Length(text);
                  case ((abL > 0) and (abP > 1)) of
                    True:
                    begin
                      if ((abP - abX) < 1) then
                        abX := ((abP - abX) + (abX - 1));
                      if (abP > (abL + 1)) then
                      begin
                        abR := ((abP - abL) - 1);
                        abX := (abX - abR);
                      end;
                      sb := Copy(text, ((abP - abX) - abR), abX);
                    end;
                    False: sb := '';
                  end;
                  abX := 1;
                  abP := (rmArr[x].position + rmArr[x].size);
                  abL := Length(text);
                  case ((abL > 0) and (abP <= abL)) of
                    True:
                    begin
                      if (abP < 1) then
                      begin
                        abX := (abX - iAbs(abP - 1));
                        abP := 1;
                      end;
                      if ((abX > 0) and ((abP + abX) > abL)) then
                        abX := (abX - (((abP + abX) - abL) - 1));
                      sa := Copy(text, abP, abX);
                    end;
                    False: sa := '';
                  end;
                  case s of
                    True:
                    begin
                      mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                      ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                    end;
                    False:
                    begin
                      mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                      ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                    end;
                  end;
                  if not (mb and ma) then
                  begin
                    y := (r - 1);
                    for d := x to (y - 1) do
                      rmArr[d] := rmArr[(d + 1)];
                    SetLength(rmArr, y);
                    Dec(r);
                  end;
                end;
              end;
            end;
          end;
          case (r > 0) of
            True:
            begin
              if not a then
                r := 1;
              SetLength(Result, r);
              for i := 0 to (r - 1) do
                Result[i] := rmArr[i].position;
            end;
            False: SetLength(Result, 0);
          end;
        end;
      end else
        SetLength(Result, 0);
    end;
    
    function CountString(s, str: string): Integer;
    begin
      Result := Length(FindEx(str, s, [mmAll, mmIgnoreCase, mmWholeWords], 1, False));
    end;
    
    function CountStringEx(s, str: string; regex: Boolean): Integer;
    begin
      Result := Length(FindEx(str, s, [mmAll, mmIgnoreCase, mmWholeWords], 1, regex));
    end;
    
    function CountStringMulti(s: TStringArray; str: string): Integer;
    var
      tmp, all: TIntegerArray;
      h, i, l, f, a: Integer;
    begin
      h := High(s);
      if ((str <> '') and (h > -1)) then
      begin
        for i := 0 to h do
        begin
          tmp := FindEx(str, s[i], [mmAll, mmIgnoreCase, mmWholeWords], 1, False);
          f := High(tmp);
          if (h > -1) then
          begin
            l := Length(all);
            SetLength(all, (l + (f + 1)));
            for a := 0 to f do
              all[(a + l)] := Integer(tmp[a]);
            SetLength(tmp, 0);
          end;
        end;
        ClearSameIntegers(all);
        Result := Length(all);
        SetLength(all, 0);
      end;
    end;
    
    function CountStringMultiEx(s: TStringArray; str: string; regex: Boolean): Integer;
    var
      tmp, all: TIntegerArray;
      h, i, l, f, a: Integer;
    begin
      h := High(s);
      if ((str <> '') and (h > -1)) then
      begin
        for i := 0 to h do
        begin
          tmp := FindEx(str, s[i], [mmAll, mmIgnoreCase, mmWholeWords], 1, regex);
          f := High(tmp);
          if (h > -1) then
          begin
            l := Length(all);
            SetLength(all, (l + (f + 1)));
            for a := 0 to f do
              all[(a + l)] := Integer(tmp[a]);
            SetLength(tmp, 0);
          end;
        end;
        ClearSameIntegers(all);
        Result := Length(all);
        SetLength(all, 0);
      end;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindBadCode;
    begin
      WriteLn('');
      WriteLn('==============Looking for bad code===============');
      if DetectSpacedText('mouse ( x , y , 1 , 1 )', ' ', filteredScriptText) then
      begin
        WriteLn('Found "(M)Mouse(x, y, 1, 1) " [Risk level: MEDIUM], potential ban.');
        Inc(BadCode);
        threats := (threats + 1);
      end;
      if not DetectSpacedText('random (', ' ', filteredScriptText) then
      begin
        WriteLn('Found no randomness in script [Risk level: MEDIUM], potential ban.');
        Inc(BadCode)
        threats := (threats + 1);
      end;
      WriteLn('=================================================');
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindAbnormalCode;
    var
      ac: TStringArray;
      i: Integer;
    begin
      WriteLn('');
      WriteLn('============Looking for Abnormal code============');
      ac := ['Name', 'Pass', 'Pin'];
      for i := 0 to 2 do
        if (CountStringEx(ReplaceWrap(('players (\[) (.*) (\]) (\.) ' + Lowercase(ac[i])), ' ', '(\s*)', [rfReplaceAll]), filteredScriptText, True) > 1) then
        begin
          WriteLn('The variable "' + ac[i] + '" is used more then once [Risk level: MEDIUM]');
          Fishy := (Fishy + 1);
          threats := (threats + 1);
        end;
      if (CountStringEx(ReplaceWrap('ToStr (\() players (\[) (.*) (\]) (\))', ' ', '(\s*)', [rfReplaceAll]), filteredScriptText, True) > 0) then
      begin
        WriteLn('Player data sent to ToStr() [Risk level: MEDIUM]');
        Fishy := (Fishy + 1);
        threats := (threats + 1);
      end;
      WriteLn('=================================================');
      SetLength(ac, 0);
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindHTTPThreats;
    var
      tmp: TIntegerArray;
      matches, ht: TStringArray;
      h, i: Integer;
    begin
      WriteLn('');
      WriteLn('============Looking for HTTP threats=============');
      ht := ['AddPostVariable', 'GetPage', 'PostHTTPPage', 'PostHTTPPageEx'];
      for i := 0 to 3 do
        if (CountStringEx((Lowercase(ht[i]) + ReplaceWrap(' (\()(.*)(\))', ' ', '(\s*)', [rfReplaceAll])), filteredScriptText, True) > 0) then
        begin
          WriteLn('Found "' + ht[i] + '" [Risk level: HIGH]');
          Inc(HTTPThreats);
          threats := (threats + 4);
        end;
      SetLength(ht, 0);
      if TraceStrsEx(ReplaceWrap('openwebpage#(%)', '#', ' ', [rfReplaceAll]), [' ', '%'], ['(\s*)', '(.*)'], originalScriptText, False, matches, tmp) then
      begin
        h := High(matches);
        WriteLn('Found attempt to OpenWebpage [Risk level: MEDIUM]');
        for i := 0 to h do
          if (CountStringMulti(['meatspin', 'porn', 'xxx', '18', 'sunny'], matches[i]) > 0)  then
          begin
            WriteLn('Found adult content attempting to be opened via OpenWebpage [Risk level: MEDIUM-HIGH]');
            Break;
          end;
        Inc(WebThreats);
        threats := (threats + 4);
        SetLength(tmp, 0);
        SetLength(matches, 0);
      end;
      WriteLn('=================================================');
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure Scan;
    begin
      WriteLn('=================Filtered Script=================');
      if DEBUG_FILTERED_SCRIPT then
        WriteLn(displayScriptText);
      WriteLn('=================================================');
      FindHTTPThreats;
      FindAbnormalCode;
      FindBadCode;
      PrintReport;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure OpenThread(Sender: TObject);
    begin
      OpenWebPage('http://villavu.com/forum/showthread.php?t=103408');
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure SaveFormInfo(Sender: TObject);
    begin
      DsgnForm.ModalResult := mrOk;
      originalScriptText := ScriptEdit.Text;
      filteredScriptText := FilterScriptData(originalScriptText);
      pressed := True;
      DsgnForm.Close;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure InitForm;
    begin
      DsgnForm := TForm.Create(nil);
      with DsgnForm do
      begin
        Caption := ('Simba Script Scanner v' + VERSION);
        Left := 377;
        Top := 380;
        Width := 750;
        Height := 460;
        Font.Name := default;
        Font.Color := clDefault;
        Font.Size := 0;
      end;
      ScriptEdit := TMemo.Create(DsgnForm);
      with ScriptEdit do
      begin
        Parent := DsgnForm;
        Left := 120;
        Top := 80;
        Width := 481;
        Height := 177;
        Font.Name := default;
        with ScriptEdit.Lines do
          Add('Paste script into this box, it will look for suspicious lines of code!');
        ScrollBars := ssBoth;
        TabOrder := 0;
      end;
      TitleLabel := TLabel.Create(DsgnForm);
      with TitleLabel do
      begin
        Parent := DsgnForm;
        Caption := ('Simba Script Scanner v' + VERSION);
        Left := 225;
        Top := 20;
        Width := 43;
        Height := 14;
        Font.Name := default;
        Font.Color := clDefault;
        Font.Size := 17;
      end;
      ScanButton := TButton.Create(DsgnForm);
      with ScanButton do
      begin
        Parent := DsgnForm;
        Caption := 'Scan';
        Left := 175;
        Top := 300;
        Width := 150;
        Height := 25;
        Font.Size := 12;
        OnClick := @SaveFormInfo;
      end;
      UpdateButton := TButton.Create(DsgnForm);
      with UpdateButton do
      begin
        Parent := DsgnForm;
        Caption := 'Update';
        Left := 400;
        Top := 300;
        Width := 150;
        Height := 25;
        Font.Size := 12;
        OnClick := @OpenThread;
      end;
    end;
    
    procedure SafeInitForm;
    var
      v: TVariantArray;
    begin
      SetLength(V, 0);
      ThreadSafeCall('InitForm', v);
    end;
    
    procedure ShowFormModal;
    begin
      DsgnForm.ShowModal;
    end;
    
    procedure SafeShowFormModal;
    var
      v: TVariantArray;
    begin
      SetLength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end;
    
    begin
      ClearDebug;
      SafeInitForm;
      SafeShowFormModal;
      if pressed then
        Scan;
    end.
    Optimized the regular expression's a little bit...
    ..and also some small changes here and there.

    -Jani
    Attached Files Attached Files
    Last edited by Janilabo; 06-09-2013 at 11:20 PM. Reason: v1.42 - Notable SPEED BOOST for any bigger scripts. :)

  6. #56
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    EDIT: 1.53:
    Code:
    -Removed some unneeded lines - by replacing functions that weren't really needed anymore
    -Added a little bit more eye-candy in (should be enough now!)
    -Tweaks here and there
    MAD PROGRESS!

    Doing another bump here now (sorry!), because I think these improvements, that I added in today, definitely deserves/requires some extra attention..

    So, I am releasing unofficial version "1.50"! Contains line-based scanning - debugs the malicious/bad lines including their kind (HTTP, Web, Fishy, Bad) and the threat-"message" itself.

    Scanning works still the same way as earlier, so its still based on the same regexes, that means any multiline tricks/attempts will be detected just like they have been in the last 3-6 releases (can't remember exactly for which version I added in the regex-based scanning + I am too lazy to check, haha).

    NOTE: Those debugged threats will be reported from the line where each threat start from (so its always debugging the starting position for em).

    Scan example for the script itself (ScannerV1.53):
    Code:
    *************************************************
    *        _  _  _       _  _  _  _  _ __         *
    *       /_`/ `/_//|/  /_//_`/_// //_//          *
    *      ._//_,/ // |  / \/_,/  /_// \/           *
    *                                               *
    *************************************************
                                                     
    =================Filtered Script=================
    *SNIP*
    =================================================
                                                     
    ============Looking for HTTP Threats=============
    =================================================
                                                     
    =============Looking for Web Threats=============
    Found "OpenWebPage" [Risk level: HIGH]
    =================================================
                                                     
    ==============Looking for Fishy Code=============
    =================================================
                                                     
    ==============Looking for Bad Code===============
    Found no randomness in script [Risk level: MEDIUM], potential ban.
    =================================================
                                                     
    ===============Lines with Threats================
     LINE |      KIND      |        THREAT         
    -------------------------------------------------
     1236 | Web Threat     | OpenWebPage(*)
    =================================================
                                                     
    ==================Scan Results===================
    HTTP threats: 0
    Web threats: 1
    Fishy code: 0
    Bad code: 1
    Overall threats: 2
    Over Script Risk: High
    =================================================
                                                     
    =====================FINISHED====================
     Remember to visit the thread for latest updates.
                   Thank you for using!              
    =================================================
    ..and the source code for 1.53:
    Code:
    {=======================================================================================]
    |                                                                                       |
    |   _____ _       _          _____         _     _      _____                           |
    |  |   __|_|_____| |_ ___   |   __|___ ___|_|___| |_   |   __|___ ___ ___ ___ ___ ___   |
    |  |__   | |     | . | .'|  |__   |  _|  _| | . |  _|  |__   |  _| .'|   |   | -_|  _|  |
    |  |_____|_|_|_|_|___|__,|  |_____|___|_| |_|  _|_|    |_____|___|__,|_|_|_|_|___|_|    |
    |                                         |_|                                           |
    |                                                                                       |
    [=======================================================================================}
    
    {$i SRL/SRL.simba}
    
    const
      VERSION = '1.53'; // Don't touch... Script version.
      FILTER_COMMENTS = True; // Doesn't pay attention to stuff inside comments
                              // Recommended to keep this feature enabled, a lot less false positives!
      COMMENT_FILTER = '@'; // CHAR, NOT STRING! Used in debug box for displaying the filtered comments (doesn't effect scan, as these will be empty chars in filteredScriptText for scan).
      FILTER_STRINGS = True; // Doesn't pay attention to stuff INSIDE string signs.
                             // So, this feature still detects stuff that falls outside those '' signs! :)
      STRING_FILTER = '%'; // CHAR, NOT STRING! Used in debug box for displaying the filtered strings (doesn't effect scan, these will be empty chars in filteredScriptText for scan).
      DEBUG_FILTERED_SCRIPT = True; // Debug the script, that was filtered (used for most script parts), before scan statistics (displays empty chars with COMMENT_FILTER & STRING_FILTER).
      DEFAULT = 'Times New Roman';
    
    type
      TMatchMethod = (mmAll, mmIgnoreCase, mmOverlap, mmWholeWords, mmStrictWW);
      TMatchMethods = set of TMatchMethod;
      TRegexMatch = record
        position, size: Integer;
        text: string;
      end;
      TRegexMatchArray = array of TRegexMatch;
      T2DRegexMatchArray = array of TRegexMatchArray;
      TRange = record
        minimum, maximum: Integer;
      end;
      TRangeArray = array of TRange;
      TThreat = record
        line: Integer;
        threat: string;
        kind: (tk_HTTP, tk_Web, tk_Fishy, tk_Bad);
      end;
      TThreatArray = array of TThreat;
    
    var
      DsgnForm: TForm;
      ScriptEdit: TMemo;
      TitleLabel: TLabel;
      ScanButton, UpdateButton: TButton;
      originalScriptText, filteredScriptText, displayScriptText: string;
      HTTPThreats, WebThreats, BadCode, threats, FishyCode: Integer;
      msgHTTP, msgWeb, msgBad, msgFishy: string;
      pressed: Boolean;
      _threats: TThreatArray;
      linePositions: TIntegerArray;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure PrintReport;
    var
      Points: Integer;
      h, i: Integer;
      li, th, kd: string;
    begin
      WriteLn('*************************************************');
      WriteLn('*        _  _  _       _  _  _  _  _ __         *');
      WriteLn('*       /_`/ `/_//|/  /_//_`/_// //_//          *');
      WriteLn('*      ._//_,/ // |  / \/_,/  /_// \/           *');
      WriteLn('*                                               *');
      WriteLn('*************************************************');
      WriteLn('                                                 ');
      WriteLn('=================Filtered Script=================');
      if DEBUG_FILTERED_SCRIPT then
        WriteLn(displayScriptText);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('============Looking for HTTP Threats=============');
      if (msgHTTP <> '') then
        WriteLn(msgHTTP);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('=============Looking for Web Threats=============');
      if (msgWeb <> '') then
        WriteLn(msgWeb);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('==============Looking for Fishy Code=============');
      if (msgFishy <> '') then
        WriteLn(msgFishy);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('==============Looking for Bad Code===============');
      if (msgBad <> '') then
        WriteLn(msgBad);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('===============Lines with Threats================');
      h := High(_threats);
      if (h > -1) then
      begin
        WriteLn(' LINE |      KIND      |        THREAT         ');
        WriteLn('-------------------------------------------------');
        for i := 0 to h do
        begin
          li := IntToStr(_threats[i].line);
          case _threats[i].kind of
            tk_Bad: kd := 'Bad Code';
            tk_Fishy: kd := 'Fishy Code';
            tk_HTTP: kd := 'HTTP Threat';
            tk_Web: kd := 'Web Threat';
          end;
          th := _threats[i].threat;
          WriteLn(' ' + (li + Padr(' ', (Length(' LINE |') - Length(li)) - 2)) + '| ' + (kd + Padr(' ', (Length('      KIND      |') - Length(kd)) - 2)) + '| ' + th);
        end;
      end;
      Points := (HTTPthreats + WebThreats + BadCode + FishyCode);
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('==================Scan Results===================');
      WriteLn('HTTP threats: ' + ToStr(HTTPThreats));
      WriteLn('Web threats: ' + ToStr(WebThreats));
      WriteLn('Fishy code: ' + ToStr(FishyCode));
      WriteLn('Bad code: ' + ToStr(BadCode));
      WriteLn('Overall threats: ' + ToStr(Points))
      case threats of
        0:    WriteLn('Over Script Risk: None');
        1..2: WriteLn('Over Script Risk: Low');
        3:    WriteLn('Over Script Risk: Medium');
        4..8: WriteLn('Over Script Risk: High');
      end;
      WriteLn('=================================================');
      WriteLn('                                                 ');
      WriteLn('=====================FINISHED====================');
      WriteLn(' Remember to visit the thread for latest updates.');
      WriteLn('               Thank you for using!              ');
      WriteLn('=================================================');
    end;
    
    procedure NewThreat(var TTA: TThreatArray; line: Integer; threat: string; kind: (tk_HTTP, tk_Web, tk_Fishy, tk_Bad));
    var
      index, i, l: Integer;
    begin
      l := Length(TTA);
      while (index < l) do
      begin
        if (line < TTA[index].line) then
          Break;
        Inc(index);
      end;
      SetLength(TTA, (l + 1));
      if (l > index) then
        for i := (l - 1) downto index do
          TTA[(i + 1)] := TTA[i];
      TTA[index].line := line;
      TTA[index].threat := threat;
      TTA[index].kind := kind;
    end;
    
    procedure TIAInsert(var TIA: TIntegerArray; index: Integer; int: Integer);
    var
      i, l: Integer;
    begin
      l := Length(TIA);
      SetLength(TIA, (l + 1));
      if (index < 0) then
        index := 0;
      if (index > l) then
        index := l;
      if (l > index) then
        for i := (l - 1) downto index do
          TIA[(i + 1)] := Integer(TIA[i]);
      TIA[index] := Integer(int);
    end;
    
    {==============================================================================]
      Explanation: Returns string of all TSA items binded together. Places glue between the indexes.
    [==============================================================================}
    function TSAConcatEx(TSA: TStringArray; glue: string): string;
    var
      h, i: Integer;
    begin
      Result := '';
      h := High(TSA);
      if (h > -1) then
      begin
        for i := 0 to (h - 1) do
          Result := (Result + string(TSA[i]) + string(glue));
        Result := (Result + string(TSA[i]));
      end;
    end;
    
    {==============================================================================]
      Explanation: Explodes str with multiple separators/delimiters (d).
                   The importance order for d items is from left to right (=>).
                   So place the important ones first and then less important after those.
    [==============================================================================}
    function ExplodeMulti(d: TStringArray; str: string): TStringArray;
    var
      p, h, i, x, o, m, l, y, z: Integer;
    begin
      h := High(d);
      if ((h > -1) and (str <> '')) then
      begin
        o := 1;
        SetLength(Result, Length(str));
        repeat
          l := 0;
          for x := 0 to h do
          begin
            p := Pos(d[x], str);
            case (p < 1) of
              True:
              begin
                z := High(d);
                if ((x <= z) and (x > -1)) then
                begin
                  for y := x to (z - 1) do
                    d[y] := d[(y + 1)];
                  SetLength(d, z);
                end;
                Dec(x);
                Dec(h);
              end;
              False:
              if ((l = 0) or (p < l)) then
              begin
                m := x;
                l := p;
              end;
            end;
          end;
          if (l > 0) then
          begin
            Result[i] := Copy(str, 1, (l - 1));
            Delete(str, 1, ((l + Length(d[m])) - 1));
            Inc(i);
          end else
            Result[i] := Copy(str, 1, Length(str));
        until (l = 0);
        SetLength(Result, (i + 1));
      end else
        Result := [string(str)];
    end;
    
    {==============================================================================]
      Explanation: Finds position from s items in str. Stores the ID of the found s item to index variable.
                   The importance order for d items is from left to right (=>).
                   So place the important ones first and then less important after those.
                   Contains field for offset.
    [==============================================================================}
    function PosMultiIDEx(s: TStringArray; str: string; var index: Integer; offset: Integer): Integer;
    var
      h, i, p, t: Integer;
    begin
      if (offset < 1) then
        offset := 1;
      Result := -1;
      index := -1;
      h := High(s);
      if ((h > -1) and (str <> '')) then
      begin
        t := (Length(str) + 1);
        Result := t;
        for i := 0 to h do
        begin
          p := PosEx(s[i], str, offset);
          if ((p > 0) and (p < Result)) then
          begin
            Result := p;
            index := i;
          end;
        end;
        if (Result = t) then
          Result := 0;
      end;
    end;
    
    function PosAll(s, str: string): TIntegerArray;
    var
      sL, strL, o, p, r: Integer;
    begin
      sL := Length(s);
      strL := Length(str);
      if (sL <= strL) then
      begin
        SetLength(Result, strL);
        repeat
          p := PosEx(s, str, (o + 1));
          if (p > 0) then
          begin
            Result[r] := p;
            o := p;
            Inc(r);
          end;
        until (p <= 0);
      end;
      SetLength(Result, r);
    end;
    
    function ToRange(minimum, maximum: Integer): TRange;
    begin
      Result.minimum := Integer(minimum);
      Result.maximum := Integer(maximum);
    end;
    
    procedure TRAAppend(var TRA: TRangeArray; x: TRange);
    var
      aL: Integer;
    begin
      aL := (Length(TRA) + 1);
      SetLength(TRA, aL);
      TRA[(aL - 1)] := TRange(x);
    end;
    
    function TrackCaS(str: string; var comments, strings: TRangeArray): Boolean;
    var
      s, i, o, e, x, l, a, ls: Integer;
      t: TStringArray;
    begin
      Result := False;
      SetLength(comments, 0);
      SetLength(strings, 0);
      l := Length(str);
      ls := -1;
      if (l > 0) then
      begin
        o := 1;
        t := ['//', '(*', '{', ''''];
        repeat
          s := PosMultiIDEx(t, str, i, o);
          case (s <= ls) of
            True: Exit;
            False: ls := s;
          end;
          if (s > 0) then
          begin
            o := (s + 1);
            a := 0;
            case i of
              0, 1, 2:
              begin
                case i of
                  0:
                  begin
                    e := PosMultiIDEx([#13#10, #13, #10], str, x, o);
                    if (x = 0) then
                      a := 1;
                    if (e = 0) then
                      e := l;
                    TRAAppend(comments, ToRange(s, e));
                  end;
                  1, 2:
                  begin
                    case i of
                      1:
                      begin
                        e := PosEx('*)', str, o);
                        a := 1;
                      end;
                      2: e := PosEx('}', str, o);
                    end;
                    if (e = 0) then
                      e := l;
                    TRAAppend(comments, ToRange(s, (e + a)));
                  end;
                end;
              end;
              3:
              begin
                e := PosMultiIDEx([#13#10, #13, #10, ''''], str, x, o);
                if (x = 0) then
                  a := 1;
                case (e = 0) of
                  True:
                  begin
                    e := l;
                    TRAAppend(strings, ToRange(s, e));
                  end;
                  False:
                  case x of
                    0, 1, 2: TRAAppend(strings, ToRange(s, e));
                    3: TRAAppend(strings, ToRange(s, (e + a)));
                  end;
                end;
              end;
            end;
            o := ((e + 1) + a);
          end;
        until ((s = 0) or (x = -1) or (o > l));
      end;
    end;
    
    {==============================================================================]
      Explanation: Trims all TSA items.
    [==============================================================================}
    procedure TSATrim(var TSA: TStringArray);
    var
      h, i: Integer;
    begin
      h := High(TSA);
      for i := 0 to h do
        TSA[i] := Trim(TSA[i]);
    end;
    
    {==============================================================================]
      Explanation: Returns all the positions by items from s array in str. Place s items in importance order (=>)
                   If overlap is set to true, strings can overlap.
                   (['aa'], 'baaaah', False) => [2,3,4]
                   (['aa'], 'baaaah', True) => [2,4]
    [==============================================================================}
    function PosAllMulti(s: TStringArray; str: string; overlap: Boolean): TIntegerArray;
    var
      h, l, p, o, x, i, t, r, y, d: Integer;
    begin
      h := High(s);
      y := Length(str);
      if ((y > 0) and (h > -1)) then
      begin
        SetLength(Result, y);
        o := 1;
        repeat
          p := 0;
          for x := 0 to h do
          begin
            t := PosEx(s[x], str, (l + o));
            case (t < 1) of
              True:
              begin
                for d := x to (h - 1) do
                  s[d] := s[(d + 1)];
                SetLength(s, h);
                Dec(x);
                Dec(h);
              end;
              False:
              if ((p = 0) or (t < p)) then
              begin
                p := t;
                i := x;
              end;
            end;
          end;
          if (p > 0) then
          begin
            Result[r] := p;
            Inc(r);
            l := p;
            if not overlap then
              o := Length(s[i]);
          end;
        until (p <= 0);
      end;
      SetLength(Result, r);
    end;
    
    procedure FillStrRangeEx(var str: string; fillWith: Char; range: TRange; exceptions: TIntegerArray);
    var
      i, l, c: Integer;
    begin
      l := Length(str);
      if ((l > 0) and not (range.minimum > range.maximum)) then
      begin
        if (range.minimum < 1) then
          range.minimum := 1;
        if (range.maximum > l) then
          range.maximum := l;
        if (range.minimum > l) then
          Exit;
        c := iAbs(range.maximum - range.minimum);
        for i := range.minimum to range.maximum do
          if not InIntArray(exceptions, i) then
            str[i] := fillWith;
      end;
    end;
    
    function FilterScriptData(data: string): string;
    var
      h, i, l: Integer;
      newLines: TIntegerArray;
      comments, strings: TRangeArray;
      tmp: TStringArray;
    begin
      Result := string(data);
      displayScriptText := string(Result);
      l := Length(Result);
      if (Result <> '') then
      begin
        if (FILTER_STRINGS or FILTER_COMMENTS) then
        begin
          newLines := PosAllMulti([#13, #10], Result, False);
          TrackCaS(data, comments, strings);
          h := High(comments);
          if FILTER_COMMENTS then
          for i := 0 to h do
          begin
            FillStrRangeEx(Result, '!', comments[i], newLines);
            FillStrRangeEx(displayScriptText, COMMENT_FILTER, comments[i], newLines);
          end;
          h := High(strings);
          if FILTER_COMMENTS then
          for i := 0 to h do
          begin
            FillStrRangeEx(Result, '!', strings[i], newLines);
            FillStrRangeEx(displayScriptText, STRING_FILTER, strings[i], newLines);
          end;
          SetLength(newLines, 0);
          SetLength(comments, 0);
          SetLength(strings, 0);
          Result := ReplaceWrap(Result, '!', '', [rfReplaceAll]);
        end;
        tmp := ExplodeMulti([#13#10, #13, #10], Result);
        TSATrim(tmp);
        Result := TSAConcatEx(tmp, #13#10);
        SetLength(tmp, 0);
      end;
    end;
    
    {==============================================================================]
      Explanation: Returns all the positions of found/matching strings (findStr) in text.
                   Uses a set of TMatchMethod (methods) for string matching.
                   Contains field for offset.
                   If regex field is set as true, then this function searches for the regex you use.
    [==============================================================================}
    function FindEx(text, findStr: string; methods: TMatchMethods; offset: Integer; regex: Boolean): TIntegerArray;
    var
      rmArr: TRegexMatchArray;
      rmArr2D: T2DRegexMatchArray;
      sb, sa: string;
      r, i, l, f, p, d, o, x, y, abL, abR, abX, abP, spA, spB, spH, spL, spI, spR, spD: Integer;
      re: TRegExp;
      ma, mb, a, s, ol: Boolean;
      c: TIntegerArray;
      t: T2DIntegerArray;
    begin
      l := Length(text);
      f := Length(findStr);
      if ((l > 0) and (f > 0) and (offset <= (l - f))) then
      begin
        if (offset < 1) then
          offset := 1;
        if not regex then
        begin
          for i := f downto 1 do
            if (Pos(findStr[i], '.\+*?[^]$(){}=!<>|:-') > 0) then
              Insert('\', findStr, i);
          SetLength(Result, l);
          re := TRegExp.Create;
          re.InputString := text;
          re.Expression := findStr;
          if (mmIgnoreCase in methods) then
            re.ModifierI := True;
          a := (mmAll in methods);
          case a of
            False: re.ModifierG := True;
            True: re.ModifierG := False;
          end;
          re.ModifierM := True;
          ol := (mmOverlap in methods);
          if not ol then
            o := (Length(findStr) - 1);
          Inc(o);
          p := offset;
          while re.ExecPos(p) do
          begin
            Result[r] := re.MatchPos[0];
            p := (Result[r] + o);
            Inc(r);
          end;
          p := Offset;
          re.Free;
          SetLength(Result, r);
          if ((r > 0) and (mmWholeWords in methods)) then
          begin
            s := (mmStrictWW in methods);
            if not s then
              c := [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, // A-Z
                    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, // a-z
                    48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // 0-9
            case ol of
              True:
              begin
                spH := High(Result);
                if (spH > -1) then
                begin
                  SetLength(t, (spH + 1));
                  t[0] := [Integer(Result[0])];
                  if (spH > 0) then
                  begin
                    spR := 1;
                    for spI := 1 to spH do
                    begin
                      for spA := 0 to (spR - 1) do
                      begin
                        spL := Length(t[spA]);
                        for spB := 0 to (spL - 1) do
                        begin
                          spD := IAbs(Result[spI] - t[spA][spB]);
                          if (spD <= f) then
                          begin
                            SetLength(t[spA], (spL + 1));
                            t[spA][spL] := Integer(Result[spI]);
                            Break;
                          end;
                        end;
                        if (spB < spL) then
                          Break;
                      end;
                      if (spA >= spR) then
                      begin
                        t[spR] := [Integer(Result[spI])];
                        Inc(spR);
                      end;
                    end;
                  end;
                  SetLength(t, spR);
                  spH := High(t);
                  for spI := spH downto 0 do
                  begin
                    spB := Low(t[spI]);
                    spA := High(t[spI]);
                    abX := 1;
                    abP := t[spI][spB];
                    abL := Length(text);
                    case ((abL > 0) and (abP > 1)) of
                      True:
                      begin
                        if ((abP - abX) < 1) then
                          abX := ((abP - abX) + (abX - 1));
                        if (abP > (abL + 1)) then
                        begin
                          abR := ((abP - abL) - 1);
                          abX := (abX - abR);
                        end;
                        sb := Copy(text, ((abP - abX) - abR), abX);
                      end;
                      False: sb := '';
                    end;
                    abX := 1;
                    abP := (t[spI][spA] + f);
                    abL := Length(text);
                    case ((abL > 0) and (abP <= abL)) of
                      True:
                      begin
                        if (abP < 1) then
                        begin
                          abX := (abX - iAbs(abP - 1));
                          abP := 1;
                        end;
                        if ((abX > 0) and ((abP + abX) > abL)) then
                          abX := (abX - (((abP + abX) - abL) - 1));
                        sa := Copy(text, abP, abX);
                      end;
                      False: sa := '';
                    end;
                    case s of
                      True:
                      begin
                        mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                        ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                      end;
                      False:
                      begin
                        mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                        ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                      end;
                    end;
                    if not (mb and ma) then
                    begin
                      for spD := spI to (spH - 1) do
                        t[spD] := t[(spD + 1)];
                      SetLength(t, spH);
                      Dec(spH);
                    end;
                  end;
                  spH := High(t);
                  if (spH > -1) then
                  begin
                    for spI := 0 to spH do
                      IncEx(spR, (High(t[spI]) + 1));
                    SetLength(Result, spR);
                    spR := 0;
                    for spI := 0 to spH do
                    begin
                      spL := High(t[spI]);
                      for spA := 0 to spL do
                      begin
                        Result[spR] := Integer(t[spI][spA]);
                        Inc(spR);
                      end;
                    end;
                    SetLength(Result, spR);
                  end else
                    SetLength(Result, 0);
                end else
                  r := 0;
              end;
              False:
              begin
                for x := (r - 1) downto 0 do
                begin
                  abX := 1;
                  abP := Result[x];
                  abL := Length(text);
                  case ((abL > 0) and (abP > 1)) of
                    True:
                    begin
                      if ((abP - abX) < 1) then
                        abX := ((abP - abX) + (abX - 1));
                      if (abP > (abL + 1)) then
                      begin
                        abR := ((abP - abL) - 1);
                        abX := (abX - abR);
                      end;
                      sb := Copy(text, ((abP - abX) - abR), abX);
                    end;
                    False: sb := '';
                  end;
                  abX := 1;
                  abP := (Result[x] + f);
                  abL := Length(text);
                  case ((abL > 0) and (abP <= abL)) of
                    True:
                    begin
                      if (abP < 1) then
                      begin
                        abX := (abX - iAbs(abP - 1));
                        abP := 1;
                      end;
                      if ((abX > 0) and ((abP + abX) > abL)) then
                        abX := (abX - (((abP + abX) - abL) - 1));
                      sa := Copy(text, abP, abX);
                    end;
                    False: sa := '';
                  end;
                  case s of
                    True:
                    begin
                      mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                      ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                    end;
                    False:
                    begin
                      mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                      ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                    end;
                  end;
                  if not (mb and ma) then
                  begin
                    y := (r - 1);
                    for d := x to (y - 1) do
                      Result[d] := Result[(d + 1)];
                    SetLength(Result, y);
                    Dec(r);
                  end;
                end;
              end;
            end;
          end;
          if (not a and (r > 0)) then
            SetLength(Result, 1);
        end else
        begin
          SetLength(rmArr, l);
          re := TRegExp.Create;
          re.InputString := text;
          re.Expression := findStr;
          if (mmIgnoreCase in methods) then
            re.ModifierI := True;
          a := (mmAll in methods);
          case a of
            False: re.ModifierG := True;
            True: re.ModifierG := False;
          end;
          re.ModifierM := True;
          ol := (mmOverlap in methods);
          p := offset;
          while re.ExecPos(p) do
          begin
            rmArr[r].position := re.MatchPos[0];
            rmArr[r].text := re.Match[0];
            rmArr[r].size := re.MatchLen[0];
            if ol then
              p := (rmArr[r].position + 1)
            else
              p := (rmArr[r].position + rmArr[r].size);
            Inc(r);
          end;
          p := Offset;
          re.Free;
          SetLength(rmArr, r);
          if ((r > 0) and (mmWholeWords in methods)) then
          begin
            s := (mmStrictWW in methods);
            if not s then
              c := [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, // A-Z
                    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, // a-z
                    48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // 0-9
            case ol of
              True:
              begin
                spH := High(rmArr);
                if (spH > -1) then
                begin
                  SetLength(rmArr2D, (spH + 1));
                  rmArr2D[0] := [TRegexMatch(rmArr[0])];
                  if (spH > 0) then
                  begin
                    spR := 1;
                    for spI := 1 to spH do
                    begin
                      for spA := 0 to (spR - 1) do
                      begin
                        spL := Length(rmArr2D[spA]);
                        for spB := 0 to (spL - 1) do
                        begin
                          spD := IAbs(rmArr[spI].position - rmArr2D[spA][spB].position);
                          if (spD <= rmArr2D[spA][spB].size) then
                          begin
                            SetLength(rmArr2D[spA], (spL + 1));
                            rmArr2D[spA][spL] := TRegexMatch(rmArr[spI]);
                            Break;
                          end;
                        end;
                        if (spB < spL) then
                          Break;
                      end;
                      if (spA >= spR) then
                      begin
                        rmArr2D[spR] := [TRegexMatch(rmArr[spI])];
                        Inc(spR);
                      end;
                    end;
                  end;
                  SetLength(rmArr2D, spR);
                  spH := High(rmArr2D);
                  for spI := spH downto 0 do
                  begin
                    spB := Low(rmArr2D[spI]);
                    spA := High(rmArr2D[spI]);
                    abX := 1;
                    abP := rmArr2D[spI][spB].position;
                    abL := Length(text);
                    case ((abL > 0) and (abP > 1)) of
                      True:
                      begin
                        if ((abP - abX) < 1) then
                          abX := ((abP - abX) + (abX - 1));
                        if (abP > (abL + 1)) then
                        begin
                          abR := ((abP - abL) - 1);
                          abX := (abX - abR);
                        end;
                        sb := Copy(text, ((abP - abX) - abR), abX);
                      end;
                      False: sb := '';
                    end;
                    abX := 1;
                    abP := (rmArr2D[spI][spA].position + rmArr2D[spI][spA].size);
                    abL := Length(text);
                    case ((abL > 0) and (abP <= abL)) of
                      True:
                      begin
                        if (abP < 1) then
                        begin
                          abX := (abX - iAbs(abP - 1));
                          abP := 1;
                        end;
                        if ((abX > 0) and ((abP + abX) > abL)) then
                          abX := (abX - (((abP + abX) - abL) - 1));
                        sa := Copy(text, abP, abX);
                      end;
                      False: sa := '';
                    end;
                    case s of
                      True:
                      begin
                        mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                        ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                      end;
                      False:
                      begin
                        mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                        ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                      end;
                    end;
                    if not (mb and ma) then
                    begin
                      for spD := spI to (spH - 1) do
                        rmArr2D[spD] := rmArr2D[(spD + 1)];
                      SetLength(rmArr2D, spH);
                      Dec(spH);
                    end;
                  end;
                  spH := High(rmArr2D);
                  if (spH > -1) then
                  begin
                    for spI := 0 to spH do
                      IncEx(spR, (High(rmArr2D[spI]) + 1));
                    SetLength(rmArr, spR);
                    spR := 0;
                    for spI := 0 to spH do
                    begin
                      spL := High(rmArr2D[spI]);
                      for spA := 0 to spL do
                      begin
                        rmArr[spR] := TRegexMatch(rmArr2D[spI][spA]);
                        Inc(spR);
                      end;
                    end;
                    SetLength(rmArr, spR);
                    r := spR;
                  end else
                    SetLength(rmArr, 0);
                end else
                  r := 0;
              end;
              False:
              begin
                for x := (r - 1) downto 0 do
                begin
                  abX := 1;
                  abP := rmArr[x].position;
                  abL := Length(text);
                  case ((abL > 0) and (abP > 1)) of
                    True:
                    begin
                      if ((abP - abX) < 1) then
                        abX := ((abP - abX) + (abX - 1));
                      if (abP > (abL + 1)) then
                      begin
                        abR := ((abP - abL) - 1);
                        abX := (abX - abR);
                      end;
                      sb := Copy(text, ((abP - abX) - abR), abX);
                    end;
                    False: sb := '';
                  end;
                  abX := 1;
                  abP := (rmArr[x].position + rmArr[x].size);
                  abL := Length(text);
                  case ((abL > 0) and (abP <= abL)) of
                    True:
                    begin
                      if (abP < 1) then
                      begin
                        abX := (abX - iAbs(abP - 1));
                        abP := 1;
                      end;
                      if ((abX > 0) and ((abP + abX) > abL)) then
                        abX := (abX - (((abP + abX) - abL) - 1));
                      sa := Copy(text, abP, abX);
                    end;
                    False: sa := '';
                  end;
                  case s of
                    True:
                    begin
                      mb := ((sb = '') or (sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                      ma := ((sa = '') or (sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                    end;
                    False:
                    begin
                      mb := ((sb = '') or not InIntArray(c, Ord(sb[1])));
                      ma := ((sa = '') or not InIntArray(c, Ord(sa[1])));
                    end;
                  end;
                  if not (mb and ma) then
                  begin
                    y := (r - 1);
                    for d := x to (y - 1) do
                      rmArr[d] := rmArr[(d + 1)];
                    SetLength(rmArr, y);
                    Dec(r);
                  end;
                end;
              end;
            end;
          end;
          case (r > 0) of
            True:
            begin
              if not a then
                r := 1;
              SetLength(Result, r);
              for i := 0 to (r - 1) do
                Result[i] := rmArr[i].position;
            end;
            False: SetLength(Result, 0);
          end;
        end;
      end else
        SetLength(Result, 0);
    end;
    
    function CountString(s, str: string): Integer;
    begin
      Result := Length(FindEx(str, s, [mmAll, mmIgnoreCase, mmWholeWords], 1, False));
    end;
    
    function CountStringEx(s, str: string; regex: Boolean): Integer;
    begin
      Result := Length(FindEx(str, s, [mmAll, mmIgnoreCase, mmWholeWords], 1, regex));
    end;
    
    function CountStringMulti(s: TStringArray; str: string): Integer;
    var
      tmp, all: TIntegerArray;
      h, i, l, f, a: Integer;
    begin
      h := High(s);
      if ((str <> '') and (h > -1)) then
      begin
        for i := 0 to h do
        begin
          tmp := FindEx(str, s[i], [mmAll, mmIgnoreCase, mmWholeWords], 1, False);
          f := High(tmp);
          if (h > -1) then
          begin
            l := Length(all);
            SetLength(all, (l + (f + 1)));
            for a := 0 to f do
              all[(a + l)] := Integer(tmp[a]);
            SetLength(tmp, 0);
          end;
        end;
        ClearSameIntegers(all);
        Result := Length(all);
        SetLength(all, 0);
      end;
    end;
    
    function CountStringMultiEx(s: TStringArray; str: string; regex: Boolean): Integer;
    var
      tmp, all: TIntegerArray;
      h, i, l, f, a: Integer;
    begin
      h := High(s);
      if ((str <> '') and (h > -1)) then
      begin
        for i := 0 to h do
        begin
          tmp := FindEx(str, s[i], [mmAll, mmIgnoreCase, mmWholeWords], 1, regex);
          f := High(tmp);
          if (h > -1) then
          begin
            l := Length(all);
            SetLength(all, (l + (f + 1)));
            for a := 0 to f do
              all[(a + l)] := Integer(tmp[a]);
            SetLength(tmp, 0);
          end;
        end;
        ClearSameIntegers(all);
        Result := Length(all);
        SetLength(all, 0);
      end;
    end;
    
    function PositionToLine(position: Integer): Integer;
    var
      h: Integer;
    begin
      Result := 1;
      h := High(linePositions);
      if (h > -1) then
      case (h > 0) of
        True:
        for Result := 1 to (h + 1) do
          if (position < linePositions[(Result - 1)]) then
            Break;
        False:
        if (position >= linePositions[0]) then
          Result := 2;
      end;
      Dec(Result);
    end;
    
    procedure AddMessage(var msgs: string; msg: string);
    begin
      case (msgs <> '') of
        True: msgs := (msgs + #13#10 + msg);
        False: msgs := msg;
      end;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindBadCode;
    var
      h, i, x: Integer;
      bc: TStringArray;
      tmp: TIntegerArray;
      s: string;
    begin
      msgBad := '';
      bc := ['mmouse (\() x , y , 1 , 1 (\))', 'mouse (\() x , y , 1 , 1 ,(.*)(\))'];
      for x := 0 to 1 do
      begin
        tmp := FindEx(filteredScriptText, ReplaceWrap(bc[x], ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
        h := High(tmp);
        if (h > -1) then
        begin
          case x of
            0: s := 'MMouse(x, y, 1, 1)';
            1: s := 'Mouse(x, y, 1, 1, *)';
          end;
          for i := 0 to h do
            NewThreat(_threats, PositionToLine(tmp[i]), s, tk_Bad);
          AddMessage(msgBad, 'Found "' + s + '" [Risk level: MEDIUM], potential ban.');
          Inc(BadCode);
          threats := (threats + 1);
          SetLength(tmp, 0);
        end;
      end;
      SetLength(bc, 0);
      tmp := FindEx(filteredScriptText, ReplaceWrap('(random (\()(.*)(\))|randomrange (\()(.*)(\)))', ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
      h := High(tmp);
      case (h = -1) of
        True:
        begin
          AddMessage(msgBad, 'Found no randomness in script [Risk level: MEDIUM], potential ban.');
          Inc(BadCode)
          Inc(threats);
        end;
        False: SetLength(tmp, 0);
      end;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindFishyCode;
    var
      ac: TStringArray;
      h, i, x: Integer;
      tmp: TIntegerArray;
    begin
      msgFishy := '';
      ac := ['Name', 'Pass', 'Pin'];
      for x := 0 to 2 do
      begin
        tmp := FindEx(filteredScriptText, ReplaceWrap(('players (\[) (.*) (\]) (\.) ' + Lowercase(ac[x])), ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
        h := High(tmp);
        if (h > 0) then
        begin
          for i := 0 to h do
            NewThreat(_threats, PositionToLine(tmp[i]), ('Players[*].' + ac[x]), tk_Fishy);
          IncEx(FishyCode, (h + 1));
          AddMessage(msgFishy, 'The variable "' + ac[x] + '" is used more then once [Risk level: MEDIUM]');
          Inc(threats);
        end;
        SetLength(tmp, 0);
      end;
      tmp := FindEx(filteredScriptText, ReplaceWrap('ToStr (\() players (\[) (.*) (\]) (\))', ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
      h := High(tmp);
      if (h > -1) then
      begin
        for i := 0 to h do
          NewThreat(_threats, PositionToLine(tmp[i]), 'ToStr(Players[*])', tk_Fishy);
        IncEx(FishyCode, (h + 1));
        AddMessage(msgFishy, 'Player data sent to ToStr() [Risk level: MEDIUM]');
        Inc(threats);
        SetLength(tmp, 0);
      end;
      SetLength(ac, 0);
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindHTTPThreats;
    var
      ht: TStringArray;
      h, i, x: Integer;
      tmp: TIntegerArray;
    begin
      msgHTTP := '';
      ht := ['AddPostVariable', 'GetPage', 'PostHTTPPage', 'PostHTTPPageEx'];
      for x := 0 to 3 do
      begin
        tmp := FindEx(filteredScriptText, (Lowercase(ht[x]) + ReplaceWrap(' (\()(.*)(\))', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
        h := High(tmp);
        if (h > -1) then
        begin
          for i := 0 to h do
            NewThreat(_threats, PositionToLine(tmp[i]), (ht[x] + '(*)'), tk_HTTP);
          IncEx(HTTPThreats, (h + 1));
          AddMessage(msgHTTP, 'Found "' + ht[x] + '" [Risk level: HIGH]');
          IncEx(threats, 4);
        end;
        SetLength(tmp, 0);
      end;
      SetLength(ht, 0);
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure FindWebThreats;
    var
      h, i: Integer;
      tmp: TIntegerArray;
    begin
      msgWeb := '';
      tmp := FindEx(filteredScriptText, ('openwebpage' + ReplaceWrap(' (\()(.*)(\))', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
      h := High(tmp);
      if (h > -1) then
      begin
        for i := 0 to h do
          NewThreat(_threats, PositionToLine(tmp[i]), 'OpenWebPage(*)', tk_Web);
        IncEx(WebThreats, (h + 1));
        AddMessage(msgWeb, 'Found "OpenWebPage" [Risk level: HIGH]');
        IncEx(threats, 4);
        SetLength(tmp, 0);
      end;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure Scan;
    begin
      FindHTTPThreats;
      FindWebThreats;
      FindFishyCode;
      FindBadCode;
      PrintReport;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure OpenThread(Sender: TObject);
    begin
      OpenWebPage('http://villavu.com/forum/showthread.php?t=103408');
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure SaveFormInfo(Sender: TObject);
    var
      tmp: TStringArray;
    begin
      DsgnForm.ModalResult := mrOk;
      tmp := ExplodeMulti([#13#10, #13, #10], ScriptEdit.Text);
      originalScriptText := TSAConcatEx(tmp, #13#10);
      SetLength(tmp, 0);
      filteredScriptText := FilterScriptData(originalScriptText);
      linePositions := PosAll(#13#10, filteredScriptText);
      TIAInsert(linePositions, 0, 1);
      pressed := True;
      DsgnForm.Close;
    end;
    
    (*
      Auther: Officer Barbrady
    *)
    procedure InitForm;
    begin
      DsgnForm := TForm.Create(nil);
      with DsgnForm do
      begin
        Caption := ('Simba Script Scanner v' + VERSION);
        Left := 377;
        Top := 380;
        Width := 750;
        Height := 460;
        Font.Name := default;
        Font.Color := clDefault;
        Font.Size := 0;
      end;
      ScriptEdit := TMemo.Create(DsgnForm);
      with ScriptEdit do
      begin
        Parent := DsgnForm;
        Left := 120;
        Top := 80;
        Width := 481;
        Height := 177;
        Font.Name := default;
        with ScriptEdit.Lines do
          Add('Paste script into this box, it will look for suspicious lines of code!');
        ScrollBars := ssBoth;
        TabOrder := 0;
      end;
      TitleLabel := TLabel.Create(DsgnForm);
      with TitleLabel do
      begin
        Parent := DsgnForm;
        Caption := ('Simba Script Scanner v' + VERSION);
        Left := 225;
        Top := 20;
        Width := 43;
        Height := 14;
        Font.Name := default;
        Font.Color := clDefault;
        Font.Size := 17;
      end;
      ScanButton := TButton.Create(DsgnForm);
      with ScanButton do
      begin
        Parent := DsgnForm;
        Caption := 'Scan';
        Left := 175;
        Top := 300;
        Width := 150;
        Height := 25;
        Font.Size := 12;
        OnClick := @SaveFormInfo;
      end;
      UpdateButton := TButton.Create(DsgnForm);
      with UpdateButton do
      begin
        Parent := DsgnForm;
        Caption := 'Update';
        Left := 400;
        Top := 300;
        Width := 150;
        Height := 25;
        Font.Size := 12;
        OnClick := @OpenThread;
      end;
    end;
    
    procedure SafeInitForm;
    var
      v: TVariantArray;
    begin
      SetLength(V, 0);
      ThreadSafeCall('InitForm', v);
    end;
    
    procedure ShowFormModal;
    begin
      DsgnForm.ShowModal;
    end;
    
    procedure SafeShowFormModal;
    var
      v: TVariantArray;
    begin
      SetLength(V, 0);
      ThreadSafeCall('ShowFormModal', v);
    end;
    
    begin
      ClearDebug;
      SafeInitForm;
      SafeShowFormModal;
      if pressed then
        Scan;
      originalScriptText := '';
      filteredScriptText := '';
      displayScriptText := '';
    end.
    @Officer Barbrady
    I wonder, if this unofficial 1.42 should be official version "1.50" (when you'll do some merging with your latest form improvements first) and then this new unofficial 1.50 could be the official version "2.00" (with those same form improvements for GUI part)
    Because, this version 1.50 doesn't have adult content detection anymore...
    Also, these both have PRO's and CON's (1.42 is probably a lot faster, whereas 1.50 is a little more advanced with its features and that way slower)
    So, I'd say they are both pretty good.. With different kind of structures, of course.

    Script is attached!

    Regards,
    -Jani
    Attached Files Attached Files
    Last edited by Janilabo; 06-10-2013 at 11:44 AM. Reason: 1.53 - Just a little bit more eye-candy + removed some unneeded lines

  7. #57
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    updated, working on making into an extension

  8. #58
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    updated, working on making into an extension
    Yay, thanks!

    Really like the extension version.

    However, there's some problems with it, that doesn't exist in script (form) version:
    -When you scan more than 1 time, the results keep growing - for some reason, extension version doesn't reset variables... I wonder why?
    -Sometimes it debugs the original script when it should debug the filtered script - this doesn't make any sense, but it could be again something to do with extension behaviour (storing settings behind the scenes or so)
    -Buggy, ignores those checkbox checked states sometimes..
    -ClearDebug not supported
    -Status() not supported

    So, at this point, script version is a lot more reliable, but hopefully extension version will catch up, because this utility is a lot more useful as an extension than script (in my opinion).

    Anyways, I attached latest extension [2.01] and latest script [1.54] to this post.

    Enjoy!
    Attached Files Attached Files
    Last edited by Janilabo; 06-11-2013 at 01:41 AM. Reason: 1.56!

  9. #59
    Join Date
    Jan 2008
    Location
    10° north of Hell
    Posts
    2,035
    Mentioned
    65 Post(s)
    Quoted
    164 Post(s)

    Default

    Extentions are ran at the start of Simba, and wont stop until you close Simba.

    Dg's Small Procedures | IRC Quotes
    Thank Wishlah for my nice new avatar!
    Quote Originally Posted by IRC
    [22:12:05] <Dgby714> Im agnostic
    [22:12:36] <Blumblebee> :O ...you can read minds

  10. #60
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by Dgby714 View Post
    Extentions are ran at the start of Simba, and wont stop until you close Simba.
    Thanks Dgby, that clears it up.

  11. #61
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Dgby714 View Post
    Extentions are ran at the start of Simba, and wont stop until you close Simba.
    So theres not much I can do to fix the problem?

  12. #62
    Join Date
    Jan 2008
    Location
    10° north of Hell
    Posts
    2,035
    Mentioned
    65 Post(s)
    Quoted
    164 Post(s)

    Default

    Quote Originally Posted by Officer Barbrady View Post
    So theres not much I can do to fix the problem?
    Initialize your variables when you start the scan.

    Dg's Small Procedures | IRC Quotes
    Thank Wishlah for my nice new avatar!
    Quote Originally Posted by IRC
    [22:12:05] <Dgby714> Im agnostic
    [22:12:36] <Blumblebee> :O ...you can read minds

  13. #63
    Join Date
    Jan 2008
    Location
    10° north of Hell
    Posts
    2,035
    Mentioned
    65 Post(s)
    Quoted
    164 Post(s)

    Default

    Also, Just a note, You do know all your OnClick methods can be 1 method right?

    Also, Your form should be created in the Init. Just hide it, and show when the button is clicked, OnShow, Clear it's data.

    You should put it on GitHub, I'll send some pull request with fixes. =P

    I feel like y'all need to understand how Extensions work internally, if you have any questions, join me on IRC in #Simba .
    Last edited by Dgby714; 06-11-2013 at 12:36 AM.

    Dg's Small Procedures | IRC Quotes
    Thank Wishlah for my nice new avatar!
    Quote Originally Posted by IRC
    [22:12:05] <Dgby714> Im agnostic
    [22:12:36] <Blumblebee> :O ...you can read minds

  14. #64
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    I'm going to be leaving tomorrow, ill be away until Sunday

Page 3 of 3 FirstFirst 123

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •