Skip to content

Instantly share code, notes, and snippets.

@joedf
Created April 3, 2021 23:29
Show Gist options
  • Save joedf/e9fdbea3f364202aa9347a51cb03d5bc to your computer and use it in GitHub Desktop.
Save joedf/e9fdbea3f364202aa9347a51cb03d5bc to your computer and use it in GitHub Desktop.
Possibly a Hero.ahk by tidbit
/*
Name: Possibly a Hero
Version 1.20 (Tuesday, March 27, 2018)
Created: (Thu December 20, 2012)
Author: tidbit
Credit:
Hotkeys:
ctrl & w --- Quit (Main window)
Description:
Parse a script and get some basic information about it, such as if it's threatening or
if it creates files on your harddrive. And various other things. Useful if you don't want
extra files being created or you don't want a script that needs internet access.
dllcall(diiiiiiiiie)
Notes:
Made in AHK v1.1.09.00
Unicode should be supported If you save with UTF-8 encoding.
You may drag-and-drop on the main window or the file.\
... this is not a proper code parser / interpreter ...
*/
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; #SingleInstance, force
#SingleInstance, Off
; ignoreComments := 1
cmd = %1% ; Save the first command-line thing-a-ma-doo.
actions:=[] ; This contains the "This script contains" list.
summary:=[] ; This has the info for what lines contain what stuff.
use :=[] ; This is used for the non-repeating list of descriptions.
; ------------------------------
; ---------- MAIN GUI ----------
; ------------------------------
Gui, +Resize +hwndHwnd +Minsize
; Gui, color, 0xF5F5F5,
Gui, Font, s12
Gui, add, radio, xm checked vradio1 gCodeMode, File
Gui, add, radio, x+10 yp vradio2 gCodeMode, Code
Gui, add, Checkbox, x+10 yp checked vIgnoreComments gDoTheCrap, Ignore Comments?
Gui, add, button, xm w90 vChoose gchoose, New File
Gui, add, edit, x+5 yp+5 w250 cGreen vReadFilePath,
Gui, add, edit, xm w150 cBlue ReadOnly vDisplayFileName, File:
Gui, add, button, x+5 yp vopen1 gopen, Open file location
Gui, add, button, x+5 yp vopen2 gopen, Run the file
Gui, add, edit, xm y+5 w400 r8 ReadOnly vdisplay,
Gui, add, button, xp y+0 w22 h22 gHelp, ?
Gui, add, text, x+5 w250 cBlue vSummaryText, Summary:
Gui, add, ListView, xm y+2 w400 r8 vMyListView, Type|Line|Text
; ------------------------------
; ---------- CODE GUI ----------
; ------------------------------
Gui, code: +Resize +MinSize
Gui, code: font, s10, DejaVu Sans Mono
Gui, code: add, edit, xm w400 r11 -wrap +WantTab +HScroll vCodeBox, %code%
Gui, code: font, s12
Gui, code: add, button, xm w100 vCodeOK gDoTheCrap, OK
Gui, code: add, button, x+20 yp w100 Default vCodeApply gCodeApply, Apply
Gui, code: add, button, x+80 yp w100 vCodeCancel gCodeGuiClose, Cancel
if (cmd!="")
Gosub, GuiDropFiles
Gosub, CodeMode
Gui, Show,,Possibly a Hero
; Gosub, DoTheCrap
Return
esc::
guiEscape:
GuiClose:
Exitapp
Return
~^w::
If (WinActive("AHK_ID" Hwnd))
Exitapp
Return
open:
Gui, Submit, NoHide
Gui, 1: Default
if (A_GuiControl="open1" && FileExist(FilePath))
Run, %FilePath%
else if (A_GuiControl="open2" && FileExist(File))
Run, %File%
else
Msgbox, Generic vague error message.
Return
help:
MsgBox, 64, Disclaimer,
(LTrim Join`s
This system is not 100`% accurate. Due to the systems used, it only detects
simple information and potentially harmful stuff. It is best that you review
the summary or open the file in an editor and determine if the program is
harmful or not and if you want to run the file under question.
)
Return
Choose:
Gui, submit, NoHide
if (Radio1=1)
{
FileSelectFile, file, 3,, Select a file to analyze.
if (errorlevel=1)
Return
SplitPath, file, FileName, FilePath ; Used for the Run buttons
GuiControl,, ReadFilePath, %file%
GuiControl,, DisplayFileName, %FileName%
Gosub, DoTheCrap
}
else
{
if (CodeOpen!=1)
GuiControl, Code:, CodeBox, %Code%
GuiControl,, ReadFilePath, Raw Code
GuiControl,, DisplayFileName, Raw Code
Gui, code: show,, Raw Code - Possibly a Hero
CodeOpen:=1
}
Return
GuiDropFiles:
if (cmd!="")
file:=cmd
else
file:=A_GuiEvent
if (inStr(file, "`n")) ; extract only the first item and remove all unwanted spaces/newlines
file:=trim(SubStr(file, 1, inStr(file, "`n")-1), "`r`n `t")
SplitPath, file, FileName, FilePath ; Used for the Run buttons
GuiControl,, Radio1, 1
GuiControl,, ReadFilePath, %file%
GuiControl,, DisplayFileName, %FileName%
Gosub, CodeMode
Gosub, DoTheCrap
Return
CodeGuiClose:
Gui, Code: Cancel
CodeOpen:=0
Return
CodeApply:
; update the code stuff without closing the editor window
Gui, Code: submit, NoHide
CodeApply:="ApplyPressed"
Gosub, DoTheCrap
Return
GuiSize:
if (A_EventInfo=1) ; The window has been minimized. No action needed.
return
GuiControlGet, C, Pos, MyListView ; all buttons will be this height, but I also need this width.
GuiControl, Move, Display, % "w" A_GuiWidth-18
GuiControl, Move, MyListView, % "w" A_GuiWidth-18 " h" A_GuiHeight-(CY+6)
Return
CodeGuiSize:
if (A_EventInfo=1) ; The window has been minimized. No action needed.
return
GuiControlGet, C, Pos, CodeCancel ; all buttons will be this height, but I also need this width.
GuiControl, Code: Move, CodeOK, % "y" A_GuiHeight-(CH+6)
GuiControl, Code: Move, CodeApply, % "y" A_GuiHeight-(CH+6)
GuiControl, Code: Move, CodeCancel, % "x" A_GuiWidth-(CW+6) " y" A_GuiHeight-(CH+6)
GuiControl, Code: Move, CodeBox, % "w" A_GuiWidth-18 " h" A_GuiHeight-(CH+18)
Return
CodeMode:
Gui, Submit, NoHide
if (radio1=1)
{
Gui, Code: Cancel
CodeOpen:=0
GuiControl,, Choose, New File
GuiControl, enable, DisplayFileName
GuiControl, enable, ReadFilePath
GuiControl, enable, Open1
GuiControl, enable, Open2
GuiControl,, ReadFilePath, %file%
GuiControl,, DisplayFileName, %FileName%
}
else
{
; if (CodeBox="")
GuiControl, Code:, CodeBox, %code%
GuiControl,, Choose, Edit Code
GuiControl, disable, DisplayFileName
GuiControl, disable, ReadFilePath
GuiControl, disable, Open1
GuiControl, disable, Open2
GuiControl,, ReadFilePath, Raw Code
GuiControl,, DisplayFileName, Raw Code
}
Return
DoTheCrap:
Gui, Submit, NoHide
Gui, Code: Submit, NoHide
Gui, 1: Default
; only hide the code window if Apply *wasn't* clicked
if (CodeApply!="ApplyPressed")
{
Gui, Code: Cancel
CodeOpen:=0
}
else
CodeApply:=""
; what do use as the code source, a file or the Raw Code.
if (Radio1=1 && FileExist(ReadFilePath))
FileRead, code, %ReadFilePath% ; This uses the inputbox, which allows you to paste in your path without needing the dialogue.
else if (Radio2=1)
code:=CodeBox
else
Return
LV_Delete() ; Clear the ListView
out:=scanScript(code)
; Msgbox % st_printArr(out)
warnList:=""
for k, v in out.Actions
warnList.="* " v "`n"
if (warnList="")
warnList:="Hooray! This file does nothing to worry about. :)"
Sort, warnList
; GuiControl,, display, |
GuiControl,, display, % "This file:`n" trim(warnList, "`r`n")
; update the Summary ListView
for line, text in out.Summary
{
LV_Add("", text.category, text.line, trim(text.code)) ; Insert the rows and trim off all the indentation that the line might have.
}
LV_ModifyCol()
LV_ModifyCol(1, "Sort")
LV_ModifyCol(2, "AutoHdr Integer")
GuiControl,, SummaryText, % "Summary (" LV_GetCount() "):"
return
scanScript(inCode, ignoreComments:=1, ignoreContSec:=0)
{
actions:=[] ; a list of actions that inCode might contain. column 1 of scans[]
summary:=[] ; summary of everything. line number, category (column 2 of scans[]) and the line of code.
use :=[] ; Keep track of what was already added to actions[], so we don't get dupes.
; regex detection rules.
; Each item/option/rule is separated by a |.
; [short description, category, v3=regex]
scans:=[["Modifies System" , "System" , "^(?:" "Process,?\s*Priority|MaxMem|InstallMouseHook|UseHook|InstallKeybdHook" ")"]
, ["Registry" , "Registry" , "^(?:" "RegRead|RegWrite|RegDelete|HKEY_LOCAL_MACHINE|HKLM|HKEY_USERS|HKU|HKEY_CURRENT_USER|HKCU|HKEY_CLASSES_ROOT|HKCR|HKEY_CURRENT_CONFIG|HKCC REG_SZ|REG_EXPAND_SZ|REG_MULTI_SZ|REG_DWORD|REG_BINARY" ")"]
, ["!!Possible Danger!!", "!!Sketchy!!", "%[\w$#@]+%\s*\(|DllCall|\bShutdown|BlockInput|\.Call\("]
, ["Internet access" , "Internet" , "\.Navigate|Web.*Request|HTTP.*Request|UrlDownloadToFile|\w*Explorer\.App"]
, ["Creates on disk" , "Create" , "^(?:" "FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut" ")"]
, ["Writes on disk" , "Write" , "FileAppend|RegWrite|IniDelete|\.Write|\.RawWrite"]
, ["Deletes on disk" , "Delete" , "^(?:" "FileDelete" ")"]
, ["Reads on disk" , "Read" , "Fileread|RegRead|IniRead|\.Read\b|\.ReadLine\b|\.RawRead\b"]
, ["Mouse hijack" , "Mouse" , "^(?:" "MouseClick|MouseClickDrag|MouseMove|(?<![,-\s])\bclick|ControlClick" ")"]
, ["Keyboard hijack" , "Keyboard" , "^(?:" "send\b|ControlSend" ")"]
, ["Requires files" , "Require" , "^(?:" "FileRead|Include|FileOpen" ")"]
, ["Hotkey creation" , "Hotkey" , "^(?:" "(?:\:[^:]*?:)?(?:[!-\xFF]+\h+&\h+)?[!-\xFF]+\:\:|Hotkey[,\h]" ")"]]
; dontMatchTheseInsideOfStrings:="System,Create,Write,Delete,Read,Mouse,Keyboard,Require,Hotkey"
skipTheseCategoriesInsideOfStrings:="Internet"
; ----------------------------------------------------------
; ---------- This is where all the magic happens! ----------
; ----------------------------------------------------------
ignore:=0
loop, parse, inCode, `n, `r
{
; remove the indentation.
LoopField:=trim(A_LoopField)
cLine:=a_index
if (ignoreContSec=1)
ignore+=(SubStr(LoopField,1,1)="(") ? 1 : (ignore>=1 && LoopField=")") ? -1 : 0
if (ignoreComments=1)
{
if (SubStr(LoopField,1,1)=";")
Continue
ignore+=(SubStr(LoopField,1,2)="/*") ? 1 : (ignore>=1 && inStr(LoopField, "*/")) ? -1 : 0
}
if (ignore>=1)
Continue
for k, v in scans
{
; v1 = short description, v2=category, v3=regex
if (RegExMatch(LoopField, "i)" v[3], mmm))
{
ttt:=v[2]
; crude check if certain things are inside of quotes or not
if (RegExMatch(LoopField, "i)" """.*?" mmm ".*"""))
break
; if ttt not in %skipTheseCategoriesInsideOfStrings%
; if (instr(SubStr(LoopField, 1, pos) , """")>0
; && instr(SubStr(LoopField, pos+len), """")>0)
; break
if (use[k]!=1) ; Determines if we have done this section yet. if not add the message to the array.
actions.insert(v[1])
use[k]:=1
summary.push({Line:cLine, Category:v[2], Code:LoopField})
; break
}
}
}
return {Actions:actions, Summary:summary}
}
st_printArr(array, depth=5, indentLevel="")
{
for k,v in Array
{
list.= indentLevel "[" k "]"
if (IsObject(v) && depth>1)
list.="`n" st_printArr(v, depth-1, indentLevel . " ")
else
list.=" => " v
list:=rtrim(list, "`r`n `t") "`n"
}
return rtrim(list)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment