Uhh, before I was able to have 2 forms open at the same time with my extension, but after I re-sized a Tmemo it seems that it closes the first form after the second one is opened. Here is the extension:

Simba Code:
{=======================================================================================]
|                                                                                       |
|   _____ _       _          _____         _     _      _____                           |
|  |   __|_|_____| |_ ___   |   __|___ ___|_|___| |_   |   __|___ ___ ___ ___ ___ ___   |
|  |__   | |     | . | .'|  |__   |  _|  _| | . |  _|  |__   |  _| .'|   |   | -_|  _|  |
|  |_____|_|_|_|_|___|__,|  |_____|___|_| |_|  _|_|    |_____|___|__,|_|_|_|_|___|_|    |
|                                           |_|                                         |
|                                                                                       |
[=======================================================================================}


const
  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).
  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).
  STRICT_PLAYERS_INFO_DETECTION = False; // NOTE: Enabling this will pick up less falsepositives.
                                         // However, then script wont detect all the PASS/PIN/NAME's either, because it can be quite tricky sometimes (with..do issue).
                                         // Disabled by default - picks up those player info things a lot better.
  DEBUG_SCAN_STEPS = True;
  DEFAULT = 'Times New Roman';
  VERSION = 2.12; // Don't touch... Extension version.
  POINTS_LOW = 1; // DON'T TOUCH!
  POINTS_MEDIUM = 2; // DON'T TOUCH!
  POINTS_HIGH = 4; // DON'T TOUCH!
  POINTS_VERY_HIGH = 6; // DON'T TOUCH!

type
  TMatchMethod = (mmAll, mmIgnoreCase, mmOverlap, mmWholeWords, mmStrictWW, mmGreedyRegex);
  TMatchMethods = set of TMatchMethod;
  TRegexMatch = record
    position, size: Integer;
    text: string;
  end;
  TRegexMatchArray = array of TRegexMatch;
  T2DRegexMatchArray = array of TRegexMatchArray;
  TRegexModifier = (rm_G, rm_I, rm_M, rm_S, rm_X, rm_R);
  TRange = record
    minimum, maximum: Integer;
  end;
  TRangeArray = array of TRange;
  TThreat = record
    line: Integer;
    threat: string;
    kind: (tk_Socket, tk_HTTP, tk_Web, tk_File, tk_Fishy, tk_Unhuman);
  end;
  TThreatArray = array of TThreat;

var
  DsgnForm, ResultsForm: TForm;
  ScriptEdit:TMemo;
  debugboxes: array [0..4] of TMemo;
  TitleLabel: array[0..1] of TLabel;
  Buttons: array[0..1] of TButton;
  CheckBoxs: array[0..7] of TCheckBox;
  originalScriptText, filteredScriptText, displayScriptText: string;
  SocketThreats, HTTPThreats, WebThreats, FileThreats, UnhumanCode, FishyCode, points, scanTimer, currentStep, totalSteps, scanTiming: Integer;
  msgSocket, msgHTTP, msgWeb, msgFile, msgUnhuman, msgFishy, steps: string;
  pressed, SOCKET_SCAN, HTTP_SCAN, WEB_SCAN, FILE_SCAN, CODE_SCAN, DEBUG_FILTERED_SCRIPT, FILTER_COMMENTS, FILTER_STRINGS: Boolean;
  threats: TThreatArray;
  linePositions: TIntegerArray;
  Tabs: Array[0..1] of TTabSheet;
  ResultTabs: Array[0..4] of TTabSheet;
  P, P2: TPageControl;
  Simba_Menu: TMenuItem;
  MenuItems: array[0..5] of TMenuItem;
  HelpMenuItems: array[0..1] of TMenuItem;
  falsePositives: TRangeArray;

procedure Append(var str: string; data: string);
begin
  str := (str + data);
end;

function TextReport: string;
var
  h, i: Integer;
  li, th, kd, rl, tmp: string;
begin
  Result := '';
  Append(Result, '*************************************************' + #13#10);
  Append(Result, '*        _  _  _       _  _  _  _  _ __         *' + #13#10);
  Append(Result, '*       /_`/ `/_//|/  /_//_`/_// //_//          *' + #13#10);
  Append(Result, '*      ._//_,/ // |  / \/_,/  /_// \/           *' + #13#10);
  Append(Result, '*                                               *' + #13#10);
  Append(Result, '*************************************************' + #13#10);
  Append(Result, '                                                 ' + #13#10);
  if DEBUG_FILTERED_SCRIPT then
    if (displayScriptText <> '') then
    begin
      Append(Result, '<===============[Filtered Script]===============>' + #13#10);
      Append(Result, displayScriptText + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  if DEBUG_SCAN_STEPS then
    if (steps <> '') then
    begin
      debugboxes[0].Lines.Add('<====================[Scan Steps]=====================>' + #13#10);
      debugboxes[0].Lines.Add(steps + #13#10);
      debugboxes[0].Lines.Add('<=====================================================>' + #13#10);
      debugboxes[0].Lines.Add('                                                 ' + #13#10);
    end;
  if SOCKET_SCAN then
    if (msgSocket <> '') then
    begin
      Append(Result, '<=========[Messages for Socket Threats]=========>' + #13#10);
      Append(Result, msgSocket + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  if HTTP_SCAN then
    if (msgHTTP <> '') then
    begin
      Append(Result, '<==========[Messages for HTTP Threats]==========>' + #13#10);
      Append(Result, msgHTTP + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  if WEB_SCAN then
    if (msgWeb <> '') then
    begin
      Append(Result, '<===========[Messages for Web Threats]==========>' + #13#10);
      Append(Result, msgWeb + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  if FILE_SCAN then
    if (msgFile <> '') then
    begin
      Append(Result, '<===========[Messages for File Threats]=========>' + #13#10);
      Append(Result, msgFile + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  if CODE_SCAN then
  begin
    if (msgFishy <> '') then
    begin
      Append(Result, '<===========[Messages for Fishy Code]===========>' + #13#10);
      Append(Result, msgFishy + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
    if (msgUnhuman <> '') then
    begin
      Append(Result, '<==========[Messages for Unhuman Code]==========>' + #13#10);
      Append(Result, msgUnhuman + #13#10);
      Append(Result, '<===============================================>' + #13#10);
      Append(Result, '                                                 ' + #13#10);
    end;
  end;
  h := High(threats);
  if (h > -1) then
  begin
    Append(Result, '<=============[Lines with Threats]==============>' + #13#10);
    Append(Result, ' LINE |      KIND      |        THREAT           ' + #13#10);
    Append(Result, ' -----+----------------+------------------------ ' + #13#10);
    for i := 0 to h do
    begin
      case (threats[i].line > -1) of
        True: li := IntToStr(threats[i].line);
        False: li := 'NONE';
      end;
      case threats[i].kind of
        tk_Socket: kd := 'Socket Threat';
        tk_HTTP: kd := 'HTTP Threat';
        tk_Web: kd := 'Web Threat';
        tk_File: kd := 'File Threat';
        tk_Fishy: kd := 'Fishy Code';
        tk_Unhuman: kd := 'Unhuman Code';
      end;
      th := threats[i].threat;
      Append(Result, ' ' + (li + Padr(' ', (Length(' LINE |') - Length(li)) - 2)) + '| ' + (kd + Padr(' ', (Length('      KIND      |') - Length(kd)) - 2)) + '| ' + th + #13#10);
    end;
    Append(Result, '<===============================================>' + #13#10);
    Append(Result, '                                                 ' + #13#10);
  end;
  case points of
    0: rl := 'None';
    1..3: rl := 'Low';
    4..7: rl := 'Medium';
    8..12: rl := 'High';
  else
    rl := 'Very High';
  end;
  Append(Result, '<================[Scan Results]=================>' + #13#10);
  Append(Result, ' Socket threats' + StringOfChar('.', (47 - (Length('Socket threats') + Length(IntToStr(SocketThreats))))) + IntToStr(SocketThreats) + #13#10);
  Append(Result, ' HTTP threats' + StringOfChar('.', (47 - (Length('HTTP threats') + Length(IntToStr(HTTPThreats))))) + IntToStr(HTTPThreats) + #13#10);
  Append(Result, ' Web threats' + StringOfChar('.', (47 - (Length('Web threats') + Length(IntToStr(WebThreats))))) + IntToStr(WebThreats) + #13#10);
  Append(Result, ' File threats' + StringOfChar('.', (47 - (Length('File threats') + Length(IntToStr(FileThreats))))) + IntToStr(FileThreats) + #13#10);
  Append(Result, ' Fishy code' + StringOfChar('.', (47 - (Length('Fishy code') + Length(IntToStr(FishyCode))))) + IntToStr(FishyCode) + #13#10);
  Append(Result, ' Unhuman code' + StringOfChar('.', (47 - (Length('Unhuman code') + Length(IntToStr(UnhumanCode))))) + IntToStr(UnhumanCode) + #13#10);
  Append(Result, ' -----------------------------------------------' + #13#10);
  Append(Result, ' Overall threats' + StringOfChar('.', (47 - (Length('Overall threats') + Length(IntToStr(Length(threats)))))) + IntToStr(Length(threats)) + #13#10);
  Append(Result, ' Script Risk Level' + StringOfChar('.', (47 - (Length('Script Risk Level') + Length(rl)))) + rl + #13#10);
  Append(Result, '<===============================================>' + #13#10);
  Append(Result, '                                                 ' + #13#10);
  Append(Result, '<===================[FINISHED]==================>' + #13#10);
  Append(Result, ' Remember to visit the thread for latest updates.' + #13#10);
  Append(Result, '               Thank you for using!              ' + #13#10);
  tmp := '~ Total Time Taken ' + IntToStr(GetSystemTime - scanTiming) + ' ms. ~';
  Append(Result, StringOfChar(' ', Round((49 - Length(tmp)) div 2)) + tmp + #13#10);
  Append(Result, '<===============================================>');
end;

(*
  Auther: Officer Barbrady
*)

procedure PrintReport;
begin
  WriteLn(TextReport);
end;

function OpenWebsite(site: string): Boolean;
begin
  site := Trim(site);
  Result := (Pos('.', site) > 0);
  if Result then
    OpenWebPage(site);
end;

function TimeStamp: string;
var
  Hours, Minutes, Seconds, Milliseconds: Word;
  tTSA: TStringArray;
  i: Integer;
begin
  DecodeTime(Now, Hours, Minutes, Seconds, Milliseconds);
  if (Hours > 23) then
    Hours := 0;
  tTSA := [IntToStr(Hours), IntToStr(Minutes), IntToStr(Seconds), IntToStr(Milliseconds)];
  for i := 0 to 2 do
    if (StrToInt(tTSA[i]) < 10) then
      tTSA[i] := ('0' + string(tTSA[i]));
  while (Length(tTSA[3]) < 3) do
    tTSA[3] := (string(tTSA[3]) + '0');
  Result := string(tTSA[0] + ':' + tTSA[1] + ':' + tTSA[2] + ':' + tTSA[3]);
end;

procedure IncPoints(x: string);
begin
  case Lowercase(x) of
    'low': IncEx(points, POINTS_LOW);
    'medium': IncEx(points, POINTS_MEDIUM);
    'high': IncEx(points, POINTS_HIGH);
    'very high': IncEx(points, POINTS_VERY_HIGH);
  end;
end;

procedure NewThreat(var TTA: TThreatArray; line: Integer; threat: string; kind: (tk_Socket, tk_HTTP, tk_Web, tk_File, tk_Fishy, tk_Unhuman));
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;
  case kind of
    tk_Socket: Inc(SocketThreats);
    tk_HTTP: Inc(HTTPThreats);
    tk_Web: Inc(WebThreats);
    tk_File: Inc(FileThreats);
    tk_Fishy: Inc(FishyCode);
    tk_Unhuman: Inc(UnhumanCode);
  end;
end;

procedure TIADelete(var TIA: TIntegerArray; x: Integer);
var
  i, h: Integer;
begin
  h := High(TIA);
  if ((x > h) or (x < 0)) then
    Exit;
  for i := x to (h - 1) do
    TIA[i] := TIA[(i + 1)];
  SetLength(TIA, h);
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;

{==============================================================================]
  Explanation: Indents str with spaces (just like the feature in SCAR, Ctrl+Shift+[I/U]).
               shift is the amount of spaces. It can be positive value (indent), 0 (no change) or negative value (unindent).
[==============================================================================}

procedure Indentation(var str: string; shift: Integer);
var
  d, tmp, nl: TStringArray;
  p, h, i, x, o, m, l, y, z: Integer;
  s: string;
begin
  if ((str <> '') and (shift <> 0)) then
  begin
    d := [#13#10, #13, #10];
    h := High(d);
    o := 1;
    SetLength(tmp, Length(str));
    SetLength(nl, 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
        tmp[i] := Copy(str, 1, (l - 1));
        nl[i] := string(d[m]);
        Delete(str, 1, ((l + Length(d[m])) - 1));
        Inc(i);
      end else
        tmp[i] := Copy(str, 1, Length(str));
    until (l = 0);
    str := '';
    SetLength(tmp, (i + 1));
    SetLength(nl, i);
    case (shift > 0) of
      True:
      begin
        s := StringOfChar(' ', shift);
        for x := 0 to i do
        begin
          str  := (str + (s + tmp[x]));
          if (x < i) then
            str := (str + nl[x]);
        end;
      end;
      False:
      begin
        shift := iAbs(shift);
        for x := 0 to i do
        begin
          y := 0;
          l := Length(tmp[x]);
          while ((y < shift) and (y < l) and (tmp[x][(y + 1)] = ' ')) do
            Inc(y);
          if (y > 0) then
            Delete(tmp[x], 1, y);
          str := (str + tmp[x]);
          if (x < i) then
            str := (str + nl[x]);
        end;
      end;
    end;
    SetLength(tmp, 0);
    SetLength(nl, 0);
  end;
end;

function ToRange(minimum, maximum: Integer): TRange;
begin
  Result.minimum := Integer(minimum);
  Result.maximum := Integer(maximum);
end;

{==============================================================================]
  Explanation: Returns true if int is in any range from ranges of TRA.
[==============================================================================}

function TRAContains(TRA: TRangeArray; int: Integer): Boolean;
var
  h, i: Integer;
begin
  h := High(TRA);
  case (h > -1) of
    True:
    begin
      for i := 0 to h do
        if ((int >= TRA[i].minimum) and (int <= TRA[i].maximum)) then
          Break;
      Result := (i <= h);
    end;
    False: Result := False;
  end;
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);
  l := Length(Result);
  displayScriptText := string(Result);
  if (l > 0) then
  begin
    if (FILTER_STRINGS or FILTER_COMMENTS) then
    begin
      newLines := PosAllMulti([#13#10, #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);
    tmp := ExplodeMulti([#13#10, #13, #10], displayScriptText);
    displayScriptText := '';
    h := High(tmp);
    for i := 0 to h do
      tmp[i] := (' ' + StringOfChar('0', (Length(IntToStr(h + 1)) - Length(IntToStr(i + 1)))) + IntToStr(i + 1) + '. ' + tmp[i]);
    displayScriptText := TSAConcatEx(tmp, #13#10);
    SetLength(tmp, 0);
  end;
end;

{==============================================================================]
  Explanation: Function for tracing findStr's from data.
               Contains also custom fields for regexTags and regexStrs;
               each tag performs a regex action, that is set to regexStrs, during the search.
[==============================================================================}

function TraceStrsEx(findStr: string; regexTags: array of Char; regexStrs: TStringArray; data: string; modifiers: set of TRegexModifier): TRangeArray;
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(Result, 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 := Replace(findStr, regexTags[t], regexStrs[t], [rfReplaceAll]);
    re := TRegExp.Create;
    re.ModifierI := (rm_I in modifiers);
    re.ModifierG := (rm_G in modifiers);
    re.ModifierM := (rm_M in modifiers);
    re.ModifierS := (rm_S in modifiers);
    re.ModifierX := (rm_X in modifiers);
    re.ModifierR := (rm_R in modifiers);
    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);
        Result[r].minimum := re.MatchPos[0];
        Result[r].maximum := (Result[r].minimum + (re.MatchLen[0] - 1));
        Inc(r);
      end;
    until not re.ExecPos(p);
    SetLength(Result, r);
    re.Free;
  end else
    SetLength(Result, 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)) 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;
      re.ModifierM := True;
      a := (mmAll in methods);
      re.ModifierG := (mmGreedyRegex in methods);
      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 = '');
                    if not mb then
                      mb := ((sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                    ma := (sa = '');
                    if not ma then
                      ma := ((sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                  end;
                  False:
                  begin
                    mb := (sb = '');
                    if not mb then
                      mb := not InIntArray(c, Ord(sb[1]));
                    ma := (sa = '');
                    if not ma then
                      ma := 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 = '');
                  if not mb then
                    mb := ((sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                  ma := (sa = '');
                  if not ma then
                    ma := ((sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                end;
                False:
                begin
                  mb := (sb = '');
                  if not mb then
                    mb := not InIntArray(c, Ord(sb[1]));
                  ma := (sa = '');
                  if not ma then
                    ma := 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;
      re.ModifierM := True;
      a := (mmAll in methods);
      re.ModifierG := (mmGreedyRegex in methods);
      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 = '');
                    if not mb then
                      mb := ((sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                    ma := (sa = '');
                    if not ma then
                      ma := ((sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                  end;
                  False:
                  begin
                    mb := (sb = '');
                    if not mb then
                      mb := not InIntArray(c, Ord(sb[1]));
                    ma := (sa = '');
                    if not ma then
                      ma := 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 = '');
                  if not mb then
                    mb := ((sb = ' ') or (sb = #13#10) or (sb = #13) or (sb = #10));
                  ma := (sa = '');
                  if not ma then
                    ma := ((sa = ' ') or (sa = #13#10) or (sa = #13) or (sa = #10));
                end;
                False:
                begin
                  mb := (sb = '');
                  if not mb then
                    mb := not InIntArray(c, Ord(sb[1]));
                  ma := (sa = '');
                  if not ma then
                    ma := 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;
      r := Length(rmArr);
      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;

procedure FilterFalsePositives(var positions: TIntegerArray);
var
  h, i: Integer;
begin
  h := High(positions);
  if ((h > -1) and (High(falsePositives) > -1)) then
  for i := h downto 0 do
    if TRAContains(falsePositives, positions[i]) then
      TIADelete(positions, i);
end;

procedure FindSocketThreats;
var
  tr, st: TStringArray;
  h, i, x, t, m, l: Integer;
  tmp: TIntegerArray;
  es, ts, str: string;
begin
  msgHTTP := '';
  Inc(currentStep);
  ts := TimeStamp;
  t := GetSystemTime;
  tmp := FindEx(filteredScriptText, 'createsocket', [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
  FilterFalsePositives(tmp);
  str := (str + (' ????<' + ts + '> Scan for CreateSocket [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10);
  h := High(tmp);
  if (h > -1) then
  begin
    if (h > 0) then
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
    else
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
    for i := 0 to h do
    begin
      l := PositionToLine(tmp[i]);
      NewThreat(threats, l, 'CreateSocket', tk_Socket);
      str := (str + (' ????????<' + TimeStamp + '> Found CreateSocket @ line ' + IntToStr(l) + '!') + #13#10);
    end;
    AddMessage(msgSocket, (' Found "CreateSocket" [Risk level: VERY HIGH]'));
    IncPoints('VERY HIGH');
  end;
  tr := ['VERY HIGH',     'VERY HIGH',  'HIGH',       'HIGH',          'HIGH',         'HIGH',     'HIGH'];
  st := ['ConnectSocket', 'SendSocket', 'RecvSocket', 'RecvSocketStr', 'RecvSocketEx', 'BindSocket', 'SocketInfo'];
  for x := 0 to High(st) do
  begin
    es := TimeStamp;
    m := GetSystemTime;
    tmp := FindEx(filteredScriptText, ('(\W)' + Lowercase(st[x]) + ReplaceWrap(' (\()', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmOverlap], 1, True);
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + (st[x] + '(*)') + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > -1) then
    begin
      if (h > 0) then
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
      else
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, PositionToLine(tmp[i]), (st[x] + '(*)'), tk_Socket);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + (st[x] + '(*)') + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgSocket, (' Found "' + st[x] + '" [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
    end;
    SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - Socket Threats [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
  SetLength(st, 0);
  SetLength(tr, 0);
end;

(*
  Auther: Officer Barbrady
*)

procedure FindHTTPThreats;
var
  tr, ht: TStringArray;
  h, i, x, t, m, l: Integer;
  tmp: TIntegerArray;
  es, ts, str: string;
begin
  msgHTTP := '';
  Inc(currentStep);
  tr := ['VERY HIGH',       'HIGH',    'HIGH',         'HIGH',           'MEDIUM',        'MEDIUM',           'MEDIUM',      'HIGH',                 'HIGH'];
  ht := ['AddPostVariable', 'GetPage', 'PostHTTPPage', 'PostHTTPPageEx', 'GetRawHeaders', 'SetHTTPUserAgent', 'GetHTTPPage', 'InitializeHTTPClient', 'InitializeHTTPClientWrap'];
  ts := TimeStamp;
  t := GetSystemTime;
  for x := 0 to High(ht) do
  begin
    es := TimeStamp;
    m := GetSystemTime;
    tmp := FindEx(filteredScriptText, ('(\W)' + Lowercase(ht[x]) + ReplaceWrap(' (\()', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmOverlap], 1, True);
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + (ht[x] + '(*)') + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > -1) then
    begin
      if (h > 0) then
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
      else
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, l, (ht[x] + '(*)'), tk_HTTP);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + (ht[x] + '(*)') + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgHTTP, (' Found "' + ht[x] + '" [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
    end;
    SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - HTTP Threats [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
  SetLength(ht, 0);
  SetLength(tr, 0);
end;

(*
  Auther: Officer Barbrady
*)

procedure FindWebThreats;
var
  h, i, t, l: Integer;
  tmp: TIntegerArray;
  ts, str: string;
begin
  msgWeb := '';
  Inc(currentStep);
  ts := TimeStamp;
  t := GetSystemTime;
  tmp := FindEx(filteredScriptText, ('(\W)openwebpage' + ReplaceWrap(' (\()', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmOverlap], 1, True);
  FilterFalsePositives(tmp);
  str := (str + (' ????<' + ts + '> Scan for OpenWebPage(*) [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10);
  h := High(tmp);
  if (h > -1) then
  begin
    if (h > 0) then
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
    else
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
    for i := 0 to h do
    begin
      l := PositionToLine(tmp[i]);
      NewThreat(threats, PositionToLine(tmp[i]), 'OpenWebPage(*)', tk_Web);
      str := (str + (' ????????<' + TimeStamp + '> Found OpenWebPage(*) @ line ' + IntToStr(l) + '!') + #13#10);
    end;
    AddMessage(msgWeb, ' Found "OpenWebPage" [Risk level: HIGH]');
    IncPoints('HIGH');
    SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - Web Threats [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
end;

procedure FindFileThreats;
var
  tr, ft: TStringArray;
  h, i, x, t, m, l: Integer;
  tmp: TIntegerArray;
  es, ts, str: string;
begin
  msgFile := '';
  Inc(currentStep);
  tr := ['HIGH',       'HIGH',     'VERY HIGH',   'MEDIUM',         'HIGH',            'MEDIUM',          'MEDIUM',     'HIGH',            'HIGH',             'MEDIUM',   'MEDIUM',         'VERY HIGH',  'VERY HIGH',  'HIGH',     'LOW',     'VERY HIGH'];
  ft := ['CreateFile', 'OpenFile', 'RewriteFile', 'ReadFileString', 'WriteFileString', 'DirectoryExists', 'FileExists', 'CreateDirectory', 'ForceDirectories', 'GetFiles', 'GetDirectories', 'DeleteFile', 'RenameFile', 'WriteINI', 'ReadINI', 'DeleteINI'];
  ts := TimeStamp;
  t := GetSystemTime;
  for x := 0 to High(ft) do
  begin
    es := TimeStamp;
    m := GetSystemTime;
    tmp := FindEx(filteredScriptText, ('(\W)' + Lowercase(ft[x]) + ReplaceWrap(' (\()', ' ', '(\s*)', [rfReplaceAll])), [mmAll, mmIgnoreCase, mmOverlap], 1, True);
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + (ft[x] + '(*)') + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > -1) then
    begin
      if (h > 0) then
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
      else
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, l, (ft[x] + '(*)'), tk_File);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + (ft[x] + '(*)') + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgFile, (' Found "' + ft[x] + '" [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
    end;
    SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - File Threats [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
  SetLength(ft, 0);
  SetLength(tr, 0);
end;

(*
  Auther: Officer Barbrady
*)

procedure FindBadCode;
var
  h, i, x, t, m, l: Integer;
  tr, ac, bc: TStringArray;
  tmp: TIntegerArray;
  ts, es, p, s, str: string;
begin
  msgFishy := '';
  Inc(currentStep);
  tr := ['MEDIUM', 'VERY HIGH',  'HIGH'];
  ac := ['Name',   'Pass',       'Pin'];
  ts := TimeStamp;
  t := GetSystemTime;
  if STRICT_PLAYERS_INFO_DETECTION then
    p := 'Players[*].';
  for x := 0 to High(ac) do
  begin
    es := TimeStamp;
    m := GetSystemTime;
    case STRICT_PLAYERS_INFO_DETECTION of
      True: tmp := FindEx(filteredScriptText, ReplaceWrap('ToStr (\() players (\[) [a-zA-Z0-9]* (\]) (\))', ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
      False: tmp := FindEx(filteredScriptText, ac[x], [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
    end;
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + (p + ac[x]) + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > 0) then
    begin
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, l, (p + ac[x]), tk_Fishy);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + (p + ac[x]) + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgFishy, (' The variable "' + (p + ac[x]) + '" is used more then once [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
    end;
    SetLength(tmp, 0);
  end;
  es := TimeStamp;
  m := GetSystemTime;
  tmp := FindEx(filteredScriptText, ReplaceWrap('ToStr (\() players (\[) [a-zA-Z0-9]* (\]) (\))', ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
  FilterFalsePositives(tmp);
  str := (str + (' ????<' + es + '> Scan for ToStr(Players[*]) [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
  h := High(tmp);
  if (h > -1) then
  begin
    if (h > 0) then
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
    else
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREAT:') + #13#10);
    for i := 0 to h do
    begin
      l := PositionToLine(tmp[i]);
      NewThreat(threats, l, 'ToStr(Players[*])', tk_Fishy);
      str := (str + (' ????????<' + TimeStamp + '> Found ToStr(Players[*]) @ line ' + IntToStr(l) + '!') + #13#10);
    end;
    AddMessage(msgFishy, ' Player data sent to ToStr() [Risk level: VERY HIGH]');
    IncPoints('VERY HIGH');
    SetLength(tmp, 0);
  end;
  tr := ['MEDIUM',      'MEDIUM',        'MEDIUM',         'MEDIUM',          'HIGH',        'HIGH',   'MEDIUM',  'MEDIUM'];
  ac := ['TradeScreen', 'SomeoneTrades', 'GetTradersName', 'TradeScreenName', 'AcceptTrade', 'Accept', 'Waiting', 'PlayerAccepted'];
  ts := TimeStamp;
  t := GetSystemTime;
  for x := 0 to High(ac) do
  begin
    es := TimeStamp;
    m := GetSystemTime;
    tmp := FindEx(filteredScriptText, ac[x], [mmAll, mmIgnoreCase, mmWholeWords], 1, True);
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + (p + ac[x]) + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > -1) then
    begin
      str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, l, (p + ac[x]), tk_Fishy);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + ac[x] + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgFishy, (' Picked up trading activity command "' + ac[x] + '" (UNUSUAL) [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
    end;
    SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - Fishy Code [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
  SetLength(ac, 0);
  msgUnhuman := '';
  Inc(currentStep);
  t := GetSystemTime;
  tr := ['LOW',                                'LOW'];
  bc := ['(\W)mmouse (\() x , y , 1 , 1 (\))', '(\W)mouse (\() x , y , 1 , 1 ,(.*?)(\))'];
  for x := 0 to 1 do
  begin
    case x of
      0: s := 'MMouse(x, y, 1, 1)';
      1: s := 'Mouse(x, y, 1, 1, *)';
    end;
    es := TimeStamp;
    tmp := FindEx(filteredScriptText, ReplaceWrap(bc[x], ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase], 1, True);
    FilterFalsePositives(tmp);
    str := (str + (' ????<' + es + '> Scan for ' + s + ' [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
    h := High(tmp);
    if (h > -1) then
    begin
      if (h > 0) then
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10)
      else
        str := (str + (' ??????<' + TimeStamp + '> DETECTED ' + IntToStr(h + 1) + ' THREATS:') + #13#10);
      for i := 0 to h do
      begin
        l := PositionToLine(tmp[i]);
        NewThreat(threats, l, s, tk_Unhuman);
        str := (str + (' ????????<' + TimeStamp + '> Found ' + s + ' @ line ' + IntToStr(l) + '!') + #13#10);
      end;
      AddMessage(msgUnhuman, (' Found "' + s + '" (potential ban) [Risk level: ' + tr[x] + ']'));
      IncPoints(tr[x]);
      SetLength(tmp, 0);
    end;
  end;
  es := TimeStamp;
  m := GetSystemTime;
  tmp := FindEx(filteredScriptText, ReplaceWrap('((\W)random (\()|(\W)randomrange (\())', ' ', '(\s*)', [rfReplaceAll]), [mmAll, mmIgnoreCase], 1, True);
  FilterFalsePositives(tmp);
  str := (str + (' ????<' + es + '> Scan for Random[Range](*) [' + IntToStr(GetSystemTime - m) + ' ms.]') + #13#10);
  h := High(tmp);
  case (h = -1) of
    True:
    begin
      str := (str + (' ??????<' + TimeStamp + '> DETECTED 1 THREAT:') + #13#10);
      NewThreat(threats, -1, 'Random[Range](*)', tk_Unhuman);
      str := (str + (' ????????<' + TimeStamp + '> Could not find Random[Range](*) @ ANY line!') + #13#10);
      AddMessage(msgUnhuman, ' Couldn''t find any randomness in script (potential ban) [Risk level: MEDIUM]');
      IncPoints('MEDIUM');
    end;
    False: SetLength(tmp, 0);
  end;
  if (steps <> '') then
    steps := (steps + ' ?' + #13#10);
  steps := (steps + (' ??<' + ts + '> Step ' + IntToStr(currentStep) + '/' + IntToStr(totalSteps) + ' - Unhuman/Abnormal Code [' + IntToStr(GetSystemTime - t) + ' ms.]') + #13#10 + str);
  str := '';
  SetLength(bc, 0);
  SetLength(tr, 0);
end;

procedure TrackFalsePositives;
var
  h, x, i, l: Integer;
  a: array of TRangeArray;
begin
  SetLength(falsePositives, 0);
  a := [TraceStrsEx('font . name', [' '], ['(\s*)'], filteredScriptText, [rm_I]),
        TraceStrsEx(' inpin @', [' ', '@'], ['(\s*)', '(\()(\s*)players(\s*)(\[)(\s*)\w+(\s*)(\])(\s*)(\.)(\s*)pin(\s*)(\))'], filteredScriptText, [rm_I])];
  h := High(a);
  for i := 0 to h do
  begin
    l := Length(a[i]);
    for x := 0 to (l - 1) do
      TRAAppend(falsePositives, a[i][x]);
  end;
end;

(*
  Auther: Officer Barbrady
*)

procedure Scan;
var
  tmp: string;
begin
  if SOCKET_SCAN then
    Inc(totalSteps);
  if HTTP_SCAN then
    Inc(totalSteps);
  if WEB_SCAN then
    Inc(totalSteps);
  if FILE_SCAN then
    Inc(totalSteps);
  if CODE_SCAN then
    IncEx(totalSteps, 2);
  scanTimer := GetSystemTime;
  TrackFalsePositives;
  if SOCKET_SCAN then
    FindSocketThreats;
  if HTTP_SCAN then
    FindHTTPThreats;
  if WEB_SCAN then
    FindWebThreats;
  if FILE_SCAN then
    FindFileThreats;
  if CODE_SCAN then
    FindBadCode;
  steps := (' ??????????????????????????????????????????????? ' + #13#10 + steps + ' ??????????????????????????????????????????????? ' + #13#10);
  tmp := '--- Scanning ' + IntToStr(Length(linePositions)) + ' lines took ' + IntToStr(GetSystemTime - scanTimer) + ' ms. ---';
  steps := (steps + StringOfChar(' ', Round((49 - Length(tmp)) div 2)) + tmp);
  PrintReport;
end;

procedure OpenMyProfile(Sender: TObject);
var
  p: string;
begin
  case Sender of
    HelpMenuItems[0]: p := 'http://villavu.com/forum/private.php?do=newpm&u=63718'; // Officer Barbrady
    HelpMenuItems[1]: p := 'http://villavu.com/forum/private.php?do=newpm&u=31'; // Janilabo
  end;
  if (p <> '') then
    OpenWebsite(p);
end;

procedure About(Sender: TObject);
begin
  WriteLn('=====================About=====================');
  WriteLn('This exension is for scanning scripts to see if they contain any type of malicious material.');
  WriteLn('===============================================');
  WriteLn('                                               ');
end;

procedure Development(Sender: TObject);
begin
  WriteLn('==================Development==================');
  WriteLn(' Officer Barbrady [Main Developer]');
  WriteLn('  - Graphical User Interface');
  WriteLn('  - Extension Implentation');
  WriteLn(' Janilabo [Developer]');
  WriteLn('  - String Functions');
  WriteLn('  - Core Features');
  WriteLn(' Rich [Contributor]');
  WriteLn('  - Automatical checks for Scan Settings');
  WriteLn(' Brandon [Contributor]');
  WriteLn('  - Improvement suggestions (Socket detection!)');
  WriteLn('===============================================');
  WriteLn('                                               ');
end;

procedure OpenThread(Sender: TObject);
begin
  OpenWebsite('http://villavu.com/forum/showthread.php?t=103408');
end;

(*
  Auther: Officer Barbrady
*)

procedure Update(Sender: TObject);
var
 latestVersion: Extended;
 str: string;
begin
  WriteLn('Getting update information, please wait.');
  WriteLn('This step may take a couple seconds!');
  str := GetPage('http://villavu.com/forum/showthread.php?t=103408');
  latestVersion := StrToFloatDef(Between('autoupdate', 'abcdef', str), -1);
  case (latestVersion > -1) of
    True:
    begin
      WriteLn('Current Version: ' + FloatToStr(VERSION) + ' | Latest Version: ' + FloatToStr(latestVersion));
      case (VERSION = latestVersion) of
        False:
        case (VERSION < latestVersion) of
          True:
          begin
            WriteLn('You dont have the latest version, you can download the latest version from the thread.');
            OpenWebsite('http://villavu.com/forum/showthread.php?t=103408');
          end;
          False: WriteLn('Looks like your version is newer than the latest version - YAY!');
        end;
        True: WriteLn('Your version is up to date!');
      end;
    end;
    False: WriteLn('Failed to check the latest version... Connection problems?');
  end;
end;

(*
  Auther: Officer Barbrady
*)

procedure SaveFormInfo;
var
  tmp: TStringArray;
begin
  scanTiming := GetSystemTime;
  steps := '';
  SocketThreats := 0;
  HTTPThreats := 0;
  WebThreats := 0;
  FileThreats := 0;
  UnhumanCode := 0;
  FishyCode := 0;
  points := 0;
  currentStep := 0;
  totalSteps := 0;
  SetLength(threats, 0);
  SetLength(falsePositives, 0);
  SetLength(linePositions, 0);
  msgSocket := '';
  msgHTTP := '';
  msgWeb := '';
  msgFile := '';
  msgUnhuman := '';
  msgFishy := '';
  originalScriptText := '';
  filteredScriptText := '';
  displayScriptText := '';
  DsgnForm.ModalResult := mrOk;
  tmp := ExplodeMulti([#13#10, #13, #10], ScriptEdit.Text);
  originalScriptText := TSAConcatEx(tmp, #13#10);
  SetLength(tmp, 0);
  filteredScriptText := FilterScriptData(originalScriptText);
  Indentation(filteredScriptText, 1);
  linePositions := PosAll(#13#10, filteredScriptText);
  TIAInsert(linePositions, 0, 1);
  HTTP_SCAN := CheckBoxs[0].Checked;
  WEB_SCAN := CheckBoxs[1].Checked;
  CODE_SCAN := CheckBoxs[2].Checked;
  DEBUG_FILTERED_SCRIPT := CheckBoxs[3].Checked;
  FILTER_COMMENTS := CheckBoxs[4].Checked;
  FILTER_STRINGS := CheckBoxs[5].Checked;
  SOCKET_SCAN := CheckBoxs[6].Checked;
  FILE_SCAN := CheckBoxs[7].Checked;
  pressed := True;
  Scan;
 // DsgnForm.Close;
end;

procedure UpdateCB(Sender: TObject);
begin
  case Sender of
    CheckBoxs[0]: HTTP_SCAN := CheckBoxs[0].Checked;
    CheckBoxs[1]: WEB_SCAN := CheckBoxs[1].Checked;
    CheckBoxs[2]: CODE_SCAN := CheckBoxs[2].Checked;
    CheckBoxs[3]: DEBUG_FILTERED_SCRIPT := CheckBoxs[3].Checked;
    CheckBoxs[4]: FILTER_COMMENTS := CheckBoxs[4].Checked;
    CheckBoxs[5]: FILTER_STRINGS := CheckBoxs[5].Checked;
    CheckBoxs[6]: SOCKET_SCAN := CheckBoxs[6].Checked;
    CheckBoxs[7]: FILE_SCAN := CheckBoxs[7].Checked;
  end;
end;
Procedure ShowResults(Sender: TObject);
begin
  Resultsform.SHOW;
  Resultsform.SetFocus;
  SaveFormInfo;
end;

Procedure InitResultsForm;
var
  i, h: Integer;
  Strings: TStringArray;
  Points: TPointArray;
  Parents: TIntegerArray;
begin
  ResultsForm:=TForm.Create(nil);

  ResultsForm.Caption:='Scan Results';
  ResultsForm.Left:=200;
  ResultsForm.Top:=200;
  ResultsForm.Width:=580;
  ResultsForm.Height:=350;
  ResultsForm.Font.Name:=default;
  ResultsForm.Font.Color:=clDefault;
  ResultsForm.Font.Size:=0;

  P2 := TPageControl.Create(ResultsForm);
  P2.Parent := ResultsForm;
  P2.SetBounds(0, 0, 750, 460);

  Strings := ['Scan Steps','Lines with threats','Messages','Scan Results','Filtered script']
  for i:=0 to high(Resulttabs) do
  begin
    Resulttabs[i] := TTabSheet.Create(P2);
    Resulttabs[i].Caption := Strings[i];
    Resulttabs[i].Visible := True;
    Resulttabs[i].PageControl := P2;
  end;
  for i := 0 to high(debugboxes) do
  begin
    debugboxes[i] := TMemo.Create(ResultsForm);
    debugboxes[i].Parent := P2.Pages[i];
    debugboxes[i].Left := 10;
    debugboxes[i].Top := 20;
    debugboxes[i].Width := 530;
    debugboxes[i].Height := 270;
    debugboxes[i].Font.Name := 'Courier New';
    debugboxes[i].Font.Size := 10;
    debugboxes[i].WordWrap := False;
    debugboxes[i].ScrollBars := ssboth;
  end;
end;
(*
  Auther: Officer Barbrady
  Description: Starts the form.
*)

procedure InitForm;
var
  i, h: Integer;
  Strings: TStringArray;
  Points: TPointArray;
  Parents: TIntegerArray;
begin
  DsgnForm := TForm.Create(nil);
  with DsgnForm do
  begin
    Caption := 'Simba Script Scanner v' + ToStr(VERSION) + ' by Officer Barbrady and Janilabo';
    Left := 900;
    Top := 395;
    Width := 750;
    Height := 460;
    Font.Name := DEFAULT;
  end;
  P := TPageControl.Create(DsgnForm);
  P.Parent := DsgnForm;
  P.SetBounds(0, 0, 750, 460);
  Strings := ['Script Input','Scan Settings']
  for i:=0 to high(tabs) do
  begin
    Tabs[i] := TTabSheet.Create(P);
    Tabs[i].Caption := Strings[i];
    Tabs[i].Visible := True;
    Tabs[i].PageControl := P;
  end;
  ScriptEdit := TMemo.Create(DsgnForm);
  with ScriptEdit do
  begin
    Parent := P.Pages[0];
    Left := 20;
    Top := 20;
    Width := 700;
    Height := 330;
    Font.Name := 'Courier New';
    Font.Size := 10;
    WordWrap := True;
    Lines.Add('Paste script into this box, it will scan for suspicious/malicious lines of code');
    ScrollBars := ssBoth;
  end;
  Strings := ['Scan', 'Update'];
  Points := [Point(175, 380), Point(400, 380)];
  h := High(Buttons);
  for i := 0 to h do
  begin
    Buttons[i] := TButton.Create(DsgnForm);
    Buttons[i].Parent := P.Pages[0];
    Buttons[i].Caption := Strings[i];
    Buttons[i].Left := Points[i].X;
    Buttons[i].Top := Points[i].Y;
    Buttons[i].Width := 150;
    Buttons[i].Height := 25;
    Buttons[i].Font.Size := 12;
    case i of
      0: Buttons[i].OnClick := @ShowResults;
      1: Buttons[1].OnClick :=  [MENTION=129311]Update[/MENTION];
    end;
  end;
  Strings := ['Scan for HTTP Threats', 'Scan for Web Threats', 'Scan for Bad Code','Debug Filtered Script', 'Filter Comments', 'Filter Strings', 'Scan for Socket Threats', 'Scan for File Threats'];
  Points := [Point(200, 100), Point(400, 100), Point(400, 160), Point(200, 160), Point(200, 220), Point(400, 220), Point(200, 280), Point(400, 280)];
  h := High(CheckBoxs);
  for i := 0 to h do
  begin
    CheckBoxs[i] := TCheckBox.Create(DsgnForm);
    CheckBoxs[i].Parent := P.Pages[1];
    CheckBoxs[i].Left := Points[i].X;
    CheckBoxs[i].Top  := Points[i].Y;
    CheckBoxs[i].Width := 97;
    CheckBoxs[i].Caption := Strings[i];
    CheckBoxs[i].Checked := True;
    CheckBoxs[i].OnClick :=  [MENTION=129311]Update[/MENTION]CB;
  end;
  HTTP_SCAN := CheckBoxs[0].Checked;
  WEB_SCAN := CheckBoxs[1].Checked;
  CODE_SCAN := CheckBoxs[2].Checked;
  DEBUG_FILTERED_SCRIPT := CheckBoxs[3].Checked;
  FILTER_COMMENTS := CheckBoxs[4].Checked;
  FILTER_STRINGS := CheckBoxs[5].Checked;
  SOCKET_SCAN := CheckBoxs[6].Checked;
  FILE_SCAN := CheckBoxs[7].Checked;
end;

(*
  Auther: Officer Barbrady
*)

procedure Start(Sender: TObject);
begin
  try
    InitForm;
    InitResultsForm;
    DsgnForm.ShowModal;
    if pressed then Scan;
  finally
    steps := '';
    totalSteps := 0;
    currentStep := 0;
    SetLength(threats, 0);
    SetLength(falsePositives, 0);
    originalScriptText := '';
    filteredScriptText := '';
    displayScriptText := '';
    SetLength(linePositions, 0);
    SocketThreats := 0;
    HTTPThreats := 0;
    WebThreats := 0;
    FileThreats := 0;
    UnhumanCode := 0;
    FishyCode := 0;
    points := 0;
    msgSocket := '';
    msgHTTP := '';
    msgWeb := '';
    msgFile := '';
    msgFishy := '';
    msgUnhuman := '';
  except
    WriteLn('Error Showing Form');
  end;
end;

procedure Init;
var
  h, i: Integer;
  Strings: TStringArray;
begin;
  Simba_Menu := TMenuItem.Create(Simba_MainMenu);
  Simba_Menu.Caption := 'SSS';
  Simba_MainMenu.Items.Add(Simba_Menu);
  Strings := ['Scan', 'Update', 'About', 'Help', 'Script Thread', 'Development'];
  h := High(MenuItems);
  for i := 0 to h do
  begin
    MenuItems[i] := TMenuItem.Create(Simba_Menu);
    MenuItems[i].Caption := Strings[i]
    case i of
      0: MenuItems[i].OnClick :=  [MENTION=30864]start[/MENTION];
      1: MenuItems[i].OnClick :=  [MENTION=129311]Update[/MENTION];
      2: MenuItems[i].OnClick := @About;
      4: MenuItems[i].OnClick := @OpenThread;
      5: MenuItems[i].OnClick := @Development;
    end;
    Simba_Menu.Add(MenuItems[i]);
  end;
  Strings := ['Officer Barbrady', 'Janilabo'];
  h := High(Strings);
  for i := 0 to h do
  begin
    HelpMenuItems[i] := TMenuItem.CREATE(MenuItems[3]);
    HelpMenuItems[i].Caption := Strings[i];
    HelpMenuItems[i].OnClick := @OpenMyProfile;
    MenuItems[3].Add(HelpMenuItems[i]);
  end;
end;

procedure Free;
begin
  try
    DsgnForm.free;
    WriteLn('Simba Script Scanner Terminated!');
  except
    WriteLn('Error Freeing Form.');
  end;
end;

begin
  Init;
  Free;
end.

I'm not sure what I did..

Obv it's going to be hard to read through all that code, so could anybody give me some reasons as to why maybe the first one closed?