Created
April 3, 2021 23:29
-
-
Save joedf/e9fdbea3f364202aa9347a51cb03d5bc to your computer and use it in GitHub Desktop.
Possibly a Hero.ahk by tidbit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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