Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added virustotal plugin

  • Loading branch information...
commit 015f9e92d8e77d72d4a8bd6fd8309e7d8fe9cc49 1 parent 5f10d40
unknown authored
View
4 Project1.vbw
@@ -1,11 +1,11 @@
-Form1 = 39, 69, 954, 491, , 20, -13, 1051, 595, C
+Form1 = 39, 69, 954, 491, Z, 20, -13, 1051, 595, C
Module4 = 22, 22, 857, 436,
fso = 1, 160, 916, 582,
clsCmnDlg = 132, 132, 1047, 554, C
CPDFStream = 42, 32, 957, 509,
CPdfParser = 88, 88, 1003, 510,
Form2 = 32, 17, 929, 608, , -10, 2, 905, 572, C
-CScriptFunctions = 44, 60, 959, 482, Z
+CScriptFunctions = 44, 60, 959, 482,
frmReplace = 44, 44, 959, 466, , 0, 0, 824, 414, C
modCrc = 22, 22, 937, 444, C
frmSclog = 0, 0, 915, 422, , 0, 0, 817, 547, C
View
8 install_script.iss
@@ -24,6 +24,7 @@ Name: {app}\husk
Name: {app}\plugins
Name: {app}\plugins\build_db
Name: {app}\plugins\objbrowser
+Name: {app}\plugins\VirusTotal
Name: {app}\highlighters
Name: {app}\libemu\scSigs
Name: {app}\xor_bruteforcer
@@ -178,6 +179,13 @@ Source: AS3_WebInstall\Project1.vbp; DestDir: {app}\AS3_WebInstall\
Source: AS3_WebInstall\Project1.vbw; DestDir: {app}\AS3_WebInstall\
Source: AS3_WebInstall\ucAsyncDownload.ctl; DestDir: {app}\AS3_WebInstall\
Source: VS_LIBEMU.url; DestDir: {app}\
+Source: plugins\VirusTotal\MD5Hash.cls; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\plugin.cls; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\Project1.vbp; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\Project1.vbw; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\Form1.frm; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\JSON.bas; DestDir: {app}\plugins\VirusTotal\
+Source: plugins\VirusTotal\cStringBuilder.cls; DestDir: {app}\plugins\VirusTotal\
[Icons]
Name: {group}\PdfStreamDumper.exe; Filename: {app}\PDFStreamDumper.exe
View
BIN  libemu/scdbg.exe
Binary file not shown
View
275 plugins/VirusTotal/Form1.frm
@@ -0,0 +1,275 @@
+VERSION 5.00
+Begin VB.Form Form1
+ Caption = "Virus Total Sample Lookup"
+ ClientHeight = 6345
+ ClientLeft = 60
+ ClientTop = 345
+ ClientWidth = 9210
+ LinkTopic = "Form1"
+ ScaleHeight = 6345
+ ScaleWidth = 9210
+ StartUpPosition = 2 'CenterScreen
+ Begin VB.TextBox Text1
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 4155
+ Left = 0
+ MultiLine = -1 'True
+ ScrollBars = 2 'Vertical
+ TabIndex = 5
+ Top = 2100
+ Width = 9165
+ End
+ Begin VB.TextBox txtFile
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 315
+ Left = 870
+ TabIndex = 4
+ Top = 60
+ Width = 8265
+ End
+ Begin VB.ListBox List1
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 1230
+ Left = 0
+ TabIndex = 2
+ Top = 810
+ Width = 9165
+ End
+ Begin VB.TextBox txtHash
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 285
+ Left = 840
+ TabIndex = 1
+ Top = 480
+ Width = 4635
+ End
+ Begin VB.Label Label2
+ Caption = "File: "
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 315
+ Left = 60
+ TabIndex = 3
+ Top = 60
+ Width = 735
+ End
+ Begin VB.Label Label1
+ Caption = "MD5"
+ BeginProperty Font
+ Name = "Courier"
+ Size = 9.75
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ Height = 225
+ Left = 120
+ TabIndex = 0
+ Top = 510
+ Width = 615
+ End
+ Begin VB.Menu mnuPopup
+ Caption = "mnuPopup"
+ Visible = 0 'False
+ Begin VB.Menu mnuCopyLine
+ Caption = "Copy Line"
+ End
+ Begin VB.Menu mnuCopyTable
+ Caption = "Copy Table"
+ End
+ End
+End
+Attribute VB_Name = "Form1"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = False
+Attribute VB_PredeclaredId = True
+Attribute VB_Exposed = False
+Public frmMain As Object
+
+Dim http As XMLHTTP
+Dim md5 As New MD5Hash
+
+Const URL_API_BASIS = "https://www.virustotal.com/vtapi/v2/"
+Const URL_SCAN_FILE = "file/scan"
+Const URL_FILE_REPORT = "file/report"
+Const URL_SCAN_URL = "url/scan"
+Const URL_URL_REPORT = "url/report"
+Const API_KEY = "a949ea9c64e7145a065b0e562673a66216a132712e958168c8c00ee5f451485b"
+
+Public Sub Form_Load()
+
+ On Error Resume Next
+
+ Dim pdf As String
+ Dim hash As String
+ Dim my_json As String
+ Dim sStatus As String
+ Dim status As Long
+ Dim d As Dictionary
+
+ Me.Show
+
+ Set http = New XMLHTTP
+
+ If http Is Nothing Then
+ List1.AddItem "Could not create XMLHTTP Object"
+ Exit Sub
+ End If
+
+ pdf = frmMain.txtPDFPath.Text
+ txtFile = pdf
+
+ If Not FileExists(pdf) Then
+ List1.AddItem "Load a file in PDF StreamDumper first"
+ Exit Sub
+ End If
+
+ hash = md5.HashFile(pdf)
+ txtHash = hash
+
+ List1.AddItem "Connecting to VirusTotal to query report for " & hash
+
+ Me.Refresh
+ DoEvents
+
+ If Not Get_VT_Report(hash, my_json, sStatus, status) Then
+ List1.AddItem "Could not get VirusTotal page, returned status code: " & status & " " & sStatus
+ Exit Sub
+ End If
+
+ List1.AddItem "Report found for md5: " & hash
+
+ Set d = JSON.parse(my_json)
+ If d Is Nothing Then
+ List1.AddItem "An error occurred parsing the JSON returned from VT"
+ Exit Sub
+ End If
+
+ If JSON.GetParserErrors <> "" Then
+ List1.AddItem "Json Parse Error: " & JSON.GetParserErrors
+ Exit Sub
+ End If
+
+ report = ParseVTJSON(d)
+
+ Text1 = report
+
+End Sub
+
+Private Function FileExists(p) As Boolean
+ If Len(p) = 0 Then Exit Function
+ If Dir(p, vbNormal Or vbHidden Or vbReadOnly Or vbSystem) <> "" Then FileExists = True
+End Function
+
+Function ParseVTJSON(d As Dictionary) As String
+ Dim r As String
+ Dim scans As Dictionary
+ Dim scanner As Dictionary
+ Dim entry, s
+
+ If d.Item("response_code") <> 1 Then
+ r = "Not found in Virustotal"
+ GoTo retnow
+ End If
+
+
+ If d.Item("positives") = 0 Then
+ r = "This sample had no detections."
+ GoTo retnow
+ End If
+
+ r = pad("scan_date: ") & d.Item("scan_date") & vbCrLf
+ r = r & pad("positives: ") & d.Item("positives") & "/" & d.Item("total") & vbCrLf
+ r = r & pad("MD5: ") & d.Item("md5") & vbCrLf
+ r = r & String(45, "-") & vbCrLf
+
+ Set scans = d.Item("scans")
+ For Each s In scans.keys
+ Set scanner = scans.Item(s)
+ If scanner.Item("detected") = True Then
+ r = r & pad(s & ": ") & scanner.Item("result") & vbCrLf
+ End If
+ Next
+
+
+retnow:
+ ParseVTJSON = r
+
+End Function
+
+Function pad(ByVal x, Optional sz As Long = 25)
+ While Len(x) < sz
+ x = x & " "
+ Wend
+ pad = x
+End Function
+
+
+Function Get_VT_Report(hash, out_response As String, out_status As String, out_statusCode As Long) As Boolean
+
+ Err.Clear
+ On Error GoTo hell
+
+ Dim x As Variant
+ out_status = Empty
+ out_response = Empty
+
+1 http.Open "POST", URL_API_BASIS & URL_FILE_REPORT, False
+2 http.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
+3 http.send "key=" & API_KEY & "&resource=" & hash
+
+ DoEvents
+
+5 out_status = http.statusText
+6 out_statusCode = http.status
+7 out_response = http.responseText
+ If out_status = "OK" Then Get_VT_Report = True
+
+hell:
+ DoEvents
+ If Err.Number <> 0 Then
+ List1.AddItem "Error in Get_VT Report Line: " & Erl & " desc: " & Err.Description
+ End If
+
+End Function
View
661 plugins/VirusTotal/JSON.bas
@@ -0,0 +1,661 @@
+Attribute VB_Name = "JSON"
+' VBJSON is a VB6 adaptation of the VBA JSON project at http://code.google.com/p/vba-json/
+' Some bugs fixed, speed improvements added for VB6 by Michael Glaser (vbjson@ediy.co.nz)
+' BSD Licensed
+
+Option Explicit
+
+Const INVALID_JSON As Long = 1
+Const INVALID_OBJECT As Long = 2
+Const INVALID_ARRAY As Long = 3
+Const INVALID_BOOLEAN As Long = 4
+Const INVALID_NULL As Long = 5
+Const INVALID_KEY As Long = 6
+Const INVALID_RPC_CALL As Long = 7
+
+Private psErrors As String
+
+Public Function GetParserErrors() As String
+ GetParserErrors = psErrors
+End Function
+
+Public Function ClearParserErrors() As String
+ psErrors = ""
+End Function
+
+
+'
+' parse string and create JSON object
+'
+Public Function parse(ByRef str As String) As Object
+
+ Dim index As Long
+ index = 1
+ psErrors = ""
+ On Error Resume Next
+ Call skipChar(str, index)
+ Select Case Mid(str, index, 1)
+ Case "{"
+ Set parse = parseObject(str, index)
+ Case "["
+ Set parse = parseArray(str, index)
+ Case Else
+ psErrors = "Invalid JSON"
+ End Select
+
+
+End Function
+
+ '
+ ' parse collection of key/value
+ '
+Private Function parseObject(ByRef str As String, ByRef index As Long) As Dictionary
+
+ Set parseObject = New Dictionary
+ Dim sKey As String
+
+ ' "{"
+ Call skipChar(str, index)
+ If Mid(str, index, 1) <> "{" Then
+ psErrors = psErrors & "Invalid Object at position " & index & " : " & Mid(str, index) & vbCrLf
+ Exit Function
+ End If
+
+ index = index + 1
+
+ Do
+ Call skipChar(str, index)
+ If "}" = Mid(str, index, 1) Then
+ index = index + 1
+ Exit Do
+ ElseIf "," = Mid(str, index, 1) Then
+ index = index + 1
+ Call skipChar(str, index)
+ End If
+
+
+ ' add key/value pair
+ sKey = parseKey(str, index)
+ On Error Resume Next
+
+ parseObject.Add sKey, parseValue(str, index)
+ If Err.Number <> 0 Then
+ psErrors = psErrors & Err.Description & ": " & sKey & vbCrLf
+ Exit Do
+ End If
+ Loop
+eh:
+
+End Function
+
+'
+' parse list
+'
+Private Function parseArray(ByRef str As String, ByRef index As Long) As Collection
+
+ Set parseArray = New Collection
+
+ ' "["
+ Call skipChar(str, index)
+ If Mid(str, index, 1) <> "[" Then
+ psErrors = psErrors & "Invalid Array at position " & index & " : " + Mid(str, index, 20) & vbCrLf
+ Exit Function
+ End If
+
+ index = index + 1
+
+ Do
+
+ Call skipChar(str, index)
+ If "]" = Mid(str, index, 1) Then
+ index = index + 1
+ Exit Do
+ ElseIf "," = Mid(str, index, 1) Then
+ index = index + 1
+ Call skipChar(str, index)
+ End If
+
+ ' add value
+ On Error Resume Next
+ parseArray.Add parseValue(str, index)
+ If Err.Number <> 0 Then
+ psErrors = psErrors & Err.Description & ": " & Mid(str, index, 20) & vbCrLf
+ Exit Do
+ End If
+ Loop
+
+End Function
+
+'
+' parse string / number / object / array / true / false / null
+'
+Private Function parseValue(ByRef str As String, ByRef index As Long)
+
+ Call skipChar(str, index)
+
+ Select Case Mid(str, index, 1)
+ Case "{"
+ Set parseValue = parseObject(str, index)
+ Case "["
+ Set parseValue = parseArray(str, index)
+ Case """", "'"
+ parseValue = parseString(str, index)
+ Case "t", "f"
+ parseValue = parseBoolean(str, index)
+ Case "n"
+ parseValue = parseNull(str, index)
+ Case Else
+ parseValue = parseNumber(str, index)
+ End Select
+
+End Function
+
+'
+' parse string
+'
+Private Function parseString(ByRef str As String, ByRef index As Long) As String
+
+ Dim quote As String
+ Dim Char As String
+ Dim Code As String
+
+ Dim SB As New cStringBuilder
+
+ Call skipChar(str, index)
+ quote = Mid(str, index, 1)
+ index = index + 1
+
+ Do While index > 0 And index <= Len(str)
+ Char = Mid(str, index, 1)
+ Select Case (Char)
+ Case "\"
+ index = index + 1
+ Char = Mid(str, index, 1)
+ Select Case (Char)
+ Case """", "\", "/", "'"
+ SB.Append Char
+ index = index + 1
+ Case "b"
+ SB.Append vbBack
+ index = index + 1
+ Case "f"
+ SB.Append vbFormFeed
+ index = index + 1
+ Case "n"
+ SB.Append vbLf
+ index = index + 1
+ Case "r"
+ SB.Append vbCr
+ index = index + 1
+ Case "t"
+ SB.Append vbTab
+ index = index + 1
+ Case "u"
+ index = index + 1
+ Code = Mid(str, index, 4)
+ SB.Append ChrW(Val("&h" + Code))
+ index = index + 4
+ End Select
+ Case quote
+ index = index + 1
+
+ parseString = SB.toString
+ Set SB = Nothing
+
+ Exit Function
+
+ Case Else
+ SB.Append Char
+ index = index + 1
+ End Select
+ Loop
+
+ parseString = SB.toString
+ Set SB = Nothing
+
+End Function
+
+'
+' parse number
+'
+Private Function parseNumber(ByRef str As String, ByRef index As Long)
+
+ Dim Value As String
+ Dim Char As String
+
+ Call skipChar(str, index)
+ Do While index > 0 And index <= Len(str)
+ Char = Mid(str, index, 1)
+ If InStr("+-0123456789.eE", Char) Then
+ Value = Value & Char
+ index = index + 1
+ Else
+ If InStr(Value, ".") Or InStr(Value, "e") Or InStr(Value, "E") Then
+ parseNumber = CDbl(Value)
+ Else
+ parseNumber = CLng(Value)
+ End If
+ Exit Function
+ End If
+ Loop
+End Function
+
+'
+' parse true / false
+'
+Private Function parseBoolean(ByRef str As String, ByRef index As Long) As Boolean
+
+ Call skipChar(str, index)
+ If Mid(str, index, 4) = "true" Then
+ parseBoolean = True
+ index = index + 4
+ ElseIf Mid(str, index, 5) = "false" Then
+ parseBoolean = False
+ index = index + 5
+ Else
+ psErrors = psErrors & "Invalid Boolean at position " & index & " : " & Mid(str, index) & vbCrLf
+ End If
+
+End Function
+
+'
+' parse null
+'
+Private Function parseNull(ByRef str As String, ByRef index As Long)
+
+ Call skipChar(str, index)
+ If Mid(str, index, 4) = "null" Then
+ parseNull = Null
+ index = index + 4
+ Else
+ psErrors = psErrors & "Invalid null value at position " & index & " : " & Mid(str, index) & vbCrLf
+ End If
+
+End Function
+
+Private Function parseKey(ByRef str As String, ByRef index As Long) As String
+
+ Dim dquote As Boolean
+ Dim squote As Boolean
+ Dim Char As String
+
+ Call skipChar(str, index)
+ Do While index > 0 And index <= Len(str)
+ Char = Mid(str, index, 1)
+ Select Case (Char)
+ Case """"
+ dquote = Not dquote
+ index = index + 1
+ If Not dquote Then
+ Call skipChar(str, index)
+ If Mid(str, index, 1) <> ":" Then
+ psErrors = psErrors & "Invalid Key at position " & index & " : " & parseKey & vbCrLf
+ Exit Do
+ End If
+ End If
+ Case "'"
+ squote = Not squote
+ index = index + 1
+ If Not squote Then
+ Call skipChar(str, index)
+ If Mid(str, index, 1) <> ":" Then
+ psErrors = psErrors & "Invalid Key at position " & index & " : " & parseKey & vbCrLf
+ Exit Do
+ End If
+ End If
+ Case ":"
+ index = index + 1
+ If Not dquote And Not squote Then
+ Exit Do
+ Else
+ parseKey = parseKey & Char
+ End If
+ Case Else
+ If InStr(vbCrLf & vbCr & vbLf & vbTab & " ", Char) Then
+ Else
+ parseKey = parseKey & Char
+ End If
+ index = index + 1
+ End Select
+ Loop
+
+End Function
+
+'
+' skip special character
+'
+Private Sub skipChar(ByRef str As String, ByRef index As Long)
+ Dim bComment As Boolean
+ Dim bStartComment As Boolean
+ Dim bLongComment As Boolean
+ Do While index > 0 And index <= Len(str)
+ Select Case Mid(str, index, 1)
+ Case vbCr, vbLf
+ If Not bLongComment Then
+ bStartComment = False
+ bComment = False
+ End If
+
+ Case vbTab, " ", "(", ")"
+
+ Case "/"
+ If Not bLongComment Then
+ If bStartComment Then
+ bStartComment = False
+ bComment = True
+ Else
+ bStartComment = True
+ bComment = False
+ bLongComment = False
+ End If
+ Else
+ If bStartComment Then
+ bLongComment = False
+ bStartComment = False
+ bComment = False
+ End If
+ End If
+
+ Case "*"
+ If bStartComment Then
+ bStartComment = False
+ bComment = True
+ bLongComment = True
+ Else
+ bStartComment = True
+ End If
+
+ Case Else
+ If Not bComment Then
+ Exit Do
+ End If
+ End Select
+
+ index = index + 1
+ Loop
+
+End Sub
+
+Public Function toString(ByRef obj As Variant) As String
+ Dim SB As New cStringBuilder
+ Select Case VarType(obj)
+ Case vbNull
+ SB.Append "null"
+ Case vbDate
+ SB.Append """" & CStr(obj) & """"
+ Case vbString
+ SB.Append """" & Encode(obj) & """"
+ Case vbObject
+
+ Dim bFI As Boolean
+ Dim i As Long
+
+ bFI = True
+ If TypeName(obj) = "Dictionary" Then
+
+ SB.Append "{"
+ Dim keys
+ keys = obj.keys
+ For i = 0 To obj.Count - 1
+ If bFI Then bFI = False Else SB.Append ","
+ Dim key
+ key = keys(i)
+ SB.Append """" & key & """:" & toString(obj.Item(key))
+ Next i
+ SB.Append "}"
+
+ ElseIf TypeName(obj) = "Collection" Then
+
+ SB.Append "["
+ Dim Value
+ For Each Value In obj
+ If bFI Then bFI = False Else SB.Append ","
+ SB.Append toString(Value)
+ Next Value
+ SB.Append "]"
+
+ End If
+ Case vbBoolean
+ If obj Then SB.Append "true" Else SB.Append "false"
+ Case vbVariant, vbArray, vbArray + vbVariant
+ Dim sEB
+ SB.Append multiArray(obj, 1, "", sEB)
+ Case Else
+ SB.Append Replace(obj, ",", ".")
+ End Select
+
+ toString = SB.toString
+ Set SB = Nothing
+
+End Function
+
+Private Function Encode(str) As String
+
+ Dim SB As New cStringBuilder
+ Dim i As Long
+ Dim j As Long
+ Dim aL1 As Variant
+ Dim aL2 As Variant
+ Dim c As String
+ Dim p As Boolean
+
+ aL1 = Array(&H22, &H5C, &H2F, &H8, &HC, &HA, &HD, &H9)
+ aL2 = Array(&H22, &H5C, &H2F, &H62, &H66, &H6E, &H72, &H74)
+ For i = 1 To Len(str)
+ p = True
+ c = Mid(str, i, 1)
+ For j = 0 To 7
+ If c = Chr(aL1(j)) Then
+ SB.Append "\" & Chr(aL2(j))
+ p = False
+ Exit For
+ End If
+ Next
+
+ If p Then
+ Dim a
+ a = AscW(c)
+ If a > 31 And a < 127 Then
+ SB.Append c
+ ElseIf a > -1 Or a < 65535 Then
+ SB.Append "\u" & String(4 - Len(Hex(a)), "0") & Hex(a)
+ End If
+ End If
+ Next
+
+ Encode = SB.toString
+ Set SB = Nothing
+
+End Function
+
+Private Function multiArray(aBD, iBC, sPS, ByRef sPT) ' Array BoDy, Integer BaseCount, String PoSition
+
+ Dim iDU As Long
+ Dim iDL As Long
+ Dim i As Long
+
+ On Error Resume Next
+ iDL = LBound(aBD, iBC)
+ iDU = UBound(aBD, iBC)
+
+ Dim SB As New cStringBuilder
+
+ Dim sPB1, sPB2 ' String PointBuffer1, String PointBuffer2
+ If Err.Number = 9 Then
+ sPB1 = sPT & sPS
+ For i = 1 To Len(sPB1)
+ If i <> 1 Then sPB2 = sPB2 & ","
+ sPB2 = sPB2 & Mid(sPB1, i, 1)
+ Next
+ ' multiArray = multiArray & toString(Eval("aBD(" & sPB2 & ")"))
+ SB.Append toString(aBD(sPB2))
+ Else
+ sPT = sPT & sPS
+ SB.Append "["
+ For i = iDL To iDU
+ SB.Append multiArray(aBD, iBC + 1, i, sPT)
+ If i < iDU Then SB.Append ","
+ Next
+ SB.Append "]"
+ sPT = Left(sPT, iBC - 2)
+ End If
+ Err.Clear
+ multiArray = SB.toString
+
+ Set SB = Nothing
+End Function
+
+' Miscellaneous JSON functions
+
+Public Function StringToJSON(st As String) As String
+
+ Const FIELD_SEP = "~"
+ Const RECORD_SEP = "|"
+
+ Dim sFlds As String
+ Dim sRecs As New cStringBuilder
+ Dim lRecCnt As Long
+ Dim lFld As Long
+ Dim fld As Variant
+ Dim rows As Variant
+
+ lRecCnt = 0
+ If st = "" Then
+ StringToJSON = "null"
+ Else
+ rows = Split(st, RECORD_SEP)
+ For lRecCnt = LBound(rows) To UBound(rows)
+ sFlds = ""
+ fld = Split(rows(lRecCnt), FIELD_SEP)
+ For lFld = LBound(fld) To UBound(fld) Step 2
+ sFlds = (sFlds & IIf(sFlds <> "", ",", "") & """" & fld(lFld) & """:""" & toUnicode(fld(lFld + 1) & "") & """")
+ Next 'fld
+ sRecs.Append IIf((Trim(sRecs.toString) <> ""), "," & vbCrLf, "") & "{" & sFlds & "}"
+ Next 'rec
+ StringToJSON = ("( {""Records"": [" & vbCrLf & sRecs.toString & vbCrLf & "], " & """RecordCount"":""" & lRecCnt & """ } )")
+ End If
+End Function
+
+
+'Public Function RStoJSON(rs As ADODB.Recordset) As String
+' On Error GoTo errHandler
+' Dim sFlds As String
+' Dim sRecs As New cStringBuilder
+' Dim lRecCnt As Long
+' Dim fld As ADODB.Field
+'
+' lRecCnt = 0
+' If rs.State = adStateClosed Then
+' RStoJSON = "null"
+' Else
+' If rs.EOF Or rs.BOF Then
+' RStoJSON = "null"
+' Else
+' Do While Not rs.EOF And Not rs.BOF
+' lRecCnt = lRecCnt + 1
+' sFlds = ""
+' For Each fld In rs.Fields
+' sFlds = (sFlds & IIf(sFlds <> "", ",", "") & """" & fld.Name & """:""" & toUnicode(fld.Value & "") & """")
+' Next 'fld
+' sRecs.Append IIf((Trim(sRecs.toString) <> ""), "," & vbCrLf, "") & "{" & sFlds & "}"
+' rs.MoveNext
+' Loop
+' RStoJSON = ("( {""Records"": [" & vbCrLf & sRecs.toString & vbCrLf & "], " & """RecordCount"":""" & lRecCnt & """ } )")
+' End If
+' End If
+'
+' Exit Function
+'errHandler:
+'
+'End Function
+
+'Public Function JsonRpcCall(url As String, methName As String, args(), Optional user As String, Optional pwd As String) As Object
+' Dim r As Object
+' Dim cli As Object
+' Dim pText As String
+' Static reqId As Integer
+'
+' reqId = reqId + 1
+'
+' Set r = CreateObject("Scripting.Dictionary")
+' r("jsonrpc") = "2.0"
+' r("method") = methName
+' r("params") = args
+' r("id") = reqId
+'
+' pText = toString(r)
+'
+' Set cli = CreateObject("MSXML2.XMLHTTP.6.0")
+' ' Set cli = New MSXML2.XMLHTTP60
+' If Len(user) > 0 Then ' If Not IsMissing(user) Then
+' cli.Open "POST", url, False, user, pwd
+' Else
+' cli.Open "POST", url, False
+' End If
+' cli.setRequestHeader "Content-Type", "application/json"
+' cli.Send pText
+'
+' If cli.Status <> 200 Then
+' Err.Raise vbObjectError + INVALID_RPC_CALL + cli.Status, , cli.statusText
+' End If
+'
+' Set r = parse(cli.responseText)
+' Set cli = Nothing
+'
+' If r("id") <> reqId Then Err.Raise vbObjectError + INVALID_RPC_CALL, , "Bad Response id"
+'
+' If r.Exists("error") Or Not r.Exists("result") Then
+' Err.Raise vbObjectError + INVALID_RPC_CALL, , "Json-Rpc Response error: " & r("error")("message")
+' End If
+'
+' If Not r.Exists("result") Then Err.Raise vbObjectError + INVALID_RPC_CALL, , "Bad Response, missing result"
+'
+' Set JsonRpcCall = r("result")
+'End Function
+
+
+
+
+Public Function toUnicode(str As String) As String
+
+ Dim x As Long
+ Dim uStr As New cStringBuilder
+ Dim uChrCode As Integer
+
+ For x = 1 To Len(str)
+ uChrCode = Asc(Mid(str, x, 1))
+ Select Case uChrCode
+ Case 8: ' backspace
+ uStr.Append "\b"
+ Case 9: ' tab
+ uStr.Append "\t"
+ Case 10: ' line feed
+ uStr.Append "\n"
+ Case 12: ' formfeed
+ uStr.Append "\f"
+ Case 13: ' carriage return
+ uStr.Append "\r"
+ Case 34: ' quote
+ uStr.Append "\"""
+ Case 39: ' apostrophe
+ uStr.Append "\'"
+ Case 92: ' backslash
+ uStr.Append "\\"
+ Case 123, 125: ' "{" and "}"
+ uStr.Append ("\u" & Right("0000" & Hex(uChrCode), 4))
+ Case Is < 32, Is > 127: ' non-ascii characters
+ uStr.Append ("\u" & Right("0000" & Hex(uChrCode), 4))
+ Case Else
+ uStr.Append Chr$(uChrCode)
+ End Select
+ Next
+ toUnicode = uStr.toString
+ Exit Function
+
+End Function
+
+Private Sub Class_Initialize()
+ psErrors = ""
+End Sub
+
+
View
202 plugins/VirusTotal/MD5Hash.cls
@@ -0,0 +1,202 @@
+VERSION 1.0 CLASS
+BEGIN
+ MultiUse = -1 'True
+ Persistable = 0 'NotPersistable
+ DataBindingBehavior = 0 'vbNone
+ DataSourceBehavior = 0 'vbNone
+ MTSTransactionMode = 0 'NotAnMTSObject
+END
+Attribute VB_Name = "MD5Hash"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = True
+Attribute VB_PredeclaredId = False
+Attribute VB_Exposed = False
+Option Explicit
+'
+'dilettante 5-21-2008
+'http://www.vbforums.com/showthread.php?t=525133
+'
+'
+'MD5Hash
+'
+'Perform CryptoAPI MD5 hash of contents of a named file or a Byte array,
+'returning hash as String of 32 hex digits.
+
+'----- Private Consts -----
+
+Private Const ALG_TYPE_ANY As Long = 0
+Private Const ALG_CLASS_HASH As Long = 32768
+Private Const ALG_SID_MD5 As Long = 3
+Private Const CALG_MD5 As Long = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5
+
+Private Const PROV_RSA_FULL As Long = 1
+Private Const CRYPT_VERIFYCONTEXT As Long = &HF0000000
+Private Const MS_DEFAULT_PROVIDER As String = _
+ "Microsoft Base Cryptographic Provider v1.0"
+
+Private Const HP_HASHVAL As Long = 2
+Private Const HP_HASHSIZE As Long = 4
+
+'----- Private Defines -----
+
+Private Declare Function CryptAcquireContext Lib "advapi32" Alias "CryptAcquireContextA" ( _
+ ByRef phProv As Long, _
+ ByVal pszContainer As String, _
+ ByVal pszProvider As String, _
+ ByVal dwProvType As Long, _
+ ByVal dwFlags As Long) As Long 'TRUE (<> 0) = success. See Err.LastDLLError if FALSE.
+
+Private Declare Function CryptCreateHash Lib "advapi32" ( _
+ ByVal hProv As Long, _
+ ByVal algid As Long, _
+ ByVal hKey As Long, _
+ ByVal dwFlags As Long, _
+ ByRef phHash As Long) As Long 'TRUE (<> 0) = success. See Err.LastDLLError if FALSE.
+
+Private Declare Function CryptDestroyHash Lib "advapi32" ( _
+ ByVal hHash As Long) As Long 'TRUE (<> 0) = success. See Err.LastDLLError if FALSE.
+
+Private Declare Function CryptGetHashParam Lib "advapi32" ( _
+ ByVal hHash As Long, _
+ ByVal dwParam As Long, _
+ ByRef pbData As Any, _
+ ByRef pdwDataLen As Long, _
+ ByVal dwFlags As Long) As Long
+
+Private Declare Function CryptHashData Lib "advapi32" ( _
+ ByVal hHash As Long, _
+ ByRef pbData As Any, _
+ ByVal dwDataLen As Long, _
+ ByVal dwFlags As Long) As Long
+
+Private Declare Function CryptReleaseContext Lib "advapi32" ( _
+ ByVal hProv As Long, _
+ ByVal dwFlags As Long) As Long 'TRUE (<> 0) = success. See Err.LastDLLError if FALSE.
+
+'----- Private Data -----
+
+Private m_hHash As Long 'Hash object handle.
+Private m_hProvider As Long 'Cryptographic Service Provider handle.
+
+'----- Private Methods -----
+
+Private Sub HashBlock(ByRef Block() As Byte)
+Attribute HashBlock.VB_Description = "Hash a block of data"
+ If CryptHashData(m_hHash, _
+ Block(LBound(Block)), _
+ UBound(Block) - LBound(Block) + 1, _
+ 0&) = 0 Then
+ Err.Raise vbObjectError Or &HC312&, _
+ "MD5Hash", _
+ "Failed to hash data block, system error " _
+ & CStr(Err.LastDllError)
+ End If
+End Sub
+
+Private Function HashValue() As String
+Attribute HashValue.VB_Description = "Retrieve hash value and terminate hashing sequence"
+ Dim lngDataLen As Long
+ Dim lngHashSize As Long
+ Dim bytHashValue() As Byte
+
+ lngDataLen = 4 '4 bytes for Long length.
+ If CryptGetHashParam(m_hHash, HP_HASHSIZE, lngHashSize, lngDataLen, 0&) = 0 Then
+ Err.Raise vbObjectError Or &HC322&, _
+ "MD5Hash", _
+ "Failed to obtain hash value length, system error " _
+ & CStr(Err.LastDllError)
+ Else
+ lngDataLen = lngHashSize
+ ReDim bytHashValue(lngDataLen - 1)
+
+ If CryptGetHashParam(m_hHash, HP_HASHVAL, bytHashValue(0), lngDataLen, 0&) = 0 Then
+ Err.Raise vbObjectError Or &HC324&, _
+ "MD5Hash", _
+ "Failed to obtain hash value, system error " _
+ & CStr(Err.LastDllError)
+ Else
+ Dim intByte As Integer
+
+ For intByte = 0 To lngDataLen - 1
+ HashValue = HashValue & Right$("0" & Hex$(bytHashValue(intByte)), 2)
+ Next
+
+ CryptDestroyHash m_hHash
+ End If
+ End If
+End Function
+
+Private Sub NewHash()
+Attribute NewHash.VB_Description = "Initialize a new hashing sequence"
+ If CryptCreateHash(m_hProvider, CALG_MD5, 0&, 0&, m_hHash) = 0 Then
+ Err.Raise vbObjectError Or &HC332&, _
+ "MD5Hash", _
+ "Failed to create CryptoAPI Hash object, system error " _
+ & CStr(Err.LastDllError)
+ End If
+End Sub
+
+'----- Public Methods -----
+
+Public Function HashFile(ByVal FileName As String) As String
+ Const CHUNK As Long = 16384
+ Dim intFile As Integer
+ Dim lngWholeChunks As Long
+ Dim intRemainder As Integer
+ Dim lngChunk As Long
+ Dim bytBlock() As Byte
+
+ On Error Resume Next 'Does file exist?
+ GetAttr FileName
+ If Err.Number = 0 Then
+ On Error GoTo 0
+ intFile = FreeFile(0)
+ Open FileName For Binary Access Read As #intFile
+ lngWholeChunks = LOF(intFile) \ CHUNK
+ intRemainder = LOF(intFile) - (CHUNK * lngWholeChunks)
+ NewHash
+ ReDim bytBlock(CHUNK - 1)
+ For lngChunk = 1 To lngWholeChunks
+ Get #intFile, , bytBlock
+ HashBlock bytBlock
+ Next
+ If intRemainder > 0 Then
+ ReDim bytBlock(intRemainder - 1)
+ Get #intFile, , bytBlock
+ HashBlock bytBlock
+ End If
+ Close #intFile
+ HashFile = HashValue()
+ Else
+ Err.Raise vbObjectError Or &HC342&, _
+ "MD5Hash.HashFile", _
+ "File doesn't exist"
+ End If
+End Function
+
+Public Function HashBytes(ByRef Block() As Byte) As String
+ NewHash
+ HashBlock Block
+ HashBytes = HashValue()
+End Function
+
+'----- Class Event Handlers -----
+
+Private Sub Class_Initialize()
+ If CryptAcquireContext(m_hProvider, _
+ vbNullString, _
+ MS_DEFAULT_PROVIDER, _
+ PROV_RSA_FULL, _
+ CRYPT_VERIFYCONTEXT) = 0 Then
+ Err.Raise vbObjectError Or &HC352&, _
+ "MD5Hash.Class_Initialize", _
+ "Failed to obtain access to CryptoAPI, system error " _
+ & CStr(Err.LastDllError)
+ End If
+End Sub
+
+Private Sub Class_Terminate()
+ On Error Resume Next 'All exceptions must be processed here.
+ CryptDestroyHash m_hHash
+ CryptReleaseContext m_hProvider, 0&
+End Sub
View
45 plugins/VirusTotal/Project1.vbp
@@ -0,0 +1,45 @@
+Type=OleDll
+Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINDOWS\system32\stdole2.tlb#OLE Automation
+Reference=*\G{F5078F18-C551-11D3-89B9-0000F81FE221}#3.0#0#C:\WINDOWS\system32\msxml3.dll#Microsoft XML, v3.0
+Reference=*\G{420B2830-E718-11CF-893D-00A0C9054228}#1.0#0#C:\WINDOWS\system32\scrrun.dll#Microsoft Scripting Runtime
+Class=plugin; plugin.cls
+Form=Form1.frm
+Class=MD5Hash; MD5Hash.cls
+Module=JSON; JSON.bas
+Class=cStringBuilder; cStringBuilder.cls
+Startup="(None)"
+HelpFile=""
+Title="vbplugin"
+ExeName32="virustotal.dll"
+Path32=".."
+Command32=""
+Name="VirusTotal"
+HelpContextID="0"
+CompatibleMode="1"
+CompatibleEXE32="..\virustotal.dll"
+MajorVer=1
+MinorVer=0
+RevisionVer=0
+AutoIncrementVer=0
+ServerSupportFiles=0
+VersionCompanyName="freddies super chew taffy co."
+CompilationType=-1
+OptimizationType=0
+FavorPentiumPro(tm)=0
+CodeViewDebugInfo=0
+NoAliasing=0
+BoundsCheck=0
+OverflowCheck=0
+FlPointCheck=0
+FDIVCheck=0
+UnroundedFP=0
+StartMode=1
+Unattended=0
+Retained=0
+ThreadPerObject=0
+MaxNumberOfThreads=1
+ThreadingModel=1
+DebugStartupOption=0
+
+[MS Transaction Server]
+AutoRefresh=1
View
5 plugins/VirusTotal/Project1.vbw
@@ -0,0 +1,5 @@
+plugin = 45, 9, 813, 548, C
+Form1 = 26, 10, 986, 603, Z, 16, 11, 873, 536, C
+MD5Hash = 132, 132, 723, 533, C
+JSON = 110, 110, 794, 525,
+cStringBuilder = 0, 0, 0, 0, C
View
244 plugins/VirusTotal/cStringBuilder.cls
@@ -0,0 +1,244 @@
+VERSION 1.0 CLASS
+BEGIN
+ MultiUse = -1 'True
+ Persistable = 0 'NotPersistable
+ DataBindingBehavior = 0 'vbNone
+ DataSourceBehavior = 0 'vbNone
+ MTSTransactionMode = 0 'NotAnMTSObject
+END
+Attribute VB_Name = "cStringBuilder"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = True
+Attribute VB_PredeclaredId = False
+Attribute VB_Exposed = False
+Option Explicit
+
+' ======================================================================================
+' Name: vbAccelerator cStringBuilder
+' Author: Steve McMahon (steve@vbaccelerator.com)
+' Date: 1 January 2002
+'
+' Copyright © 2002 Steve McMahon for vbAccelerator
+' --------------------------------------------------------------------------------------
+' Visit vbAccelerator - advanced free source code for VB programmers
+' http://vbaccelerator.com
+' --------------------------------------------------------------------------------------
+'
+' VB can be slow to append strings together because of the continual
+' reallocation of string size. This class pre-allocates a string in
+' blocks and hence removes the performance restriction.
+'
+' Quicker insert and remove is also possible since string space does
+' not have to be reallocated.
+'
+' Example:
+' Adding "http://vbaccelerator.com/" 10,000 times to a string:
+' Standard VB: 34s
+' This Class: 0.35s
+'
+' ======================================================================================
+
+Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
+ (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
+
+
+Private m_sString As String
+Private m_iChunkSize As Long
+Private m_iPos As Long
+Private m_iLen As Long
+
+Public Property Get Length() As Long
+ Length = m_iPos \ 2
+End Property
+
+Public Property Get Capacity() As Long
+ Capacity = m_iLen \ 2
+End Property
+
+Public Property Get ChunkSize() As Long
+ ' Return the unicode character chunk size:
+ ChunkSize = m_iChunkSize \ 2
+End Property
+
+Public Property Let ChunkSize(ByVal iChunkSize As Long)
+ ' Set the chunksize. We multiply by 2 because internally
+ ' we are considering bytes:
+ m_iChunkSize = iChunkSize * 2
+End Property
+
+Public Property Get toString() As String
+ ' The internal string:
+ If m_iPos > 0 Then
+ toString = Left$(m_sString, m_iPos \ 2)
+ End If
+End Property
+
+Public Property Let TheString(ByRef sThis As String)
+ Dim lLen As Long
+
+ ' Setting the string:
+ lLen = LenB(sThis)
+ If lLen = 0 Then
+ 'Clear
+ m_sString = ""
+ m_iPos = 0
+ m_iLen = 0
+ Else
+ If m_iLen < lLen Then
+ ' Need to expand string to accommodate:
+ Do
+ m_sString = m_sString & Space$(m_iChunkSize \ 2)
+ m_iLen = m_iLen + m_iChunkSize
+ Loop While m_iLen < lLen
+ End If
+ CopyMemory ByVal StrPtr(m_sString), ByVal StrPtr(sThis), lLen
+ m_iPos = lLen
+ End If
+
+End Property
+
+Public Sub Clear()
+ m_sString = ""
+ m_iPos = 0
+ m_iLen = 0
+End Sub
+
+Public Sub AppendNL(ByRef sThis As String)
+ Append sThis
+ Append vbCrLf
+End Sub
+
+Public Sub Append(ByRef sThis As String)
+ Dim lLen As Long
+ Dim lLenPlusPos As Long
+
+ ' Append an item to the string:
+ lLen = LenB(sThis)
+ lLenPlusPos = lLen + m_iPos
+ If lLenPlusPos > m_iLen Then
+ Dim lTemp As Long
+
+ lTemp = m_iLen
+ Do While lTemp < lLenPlusPos
+ lTemp = lTemp + m_iChunkSize
+ Loop
+
+ m_sString = m_sString & Space$((lTemp - m_iLen) \ 2)
+ m_iLen = lTemp
+ End If
+
+ CopyMemory ByVal UnsignedAdd(StrPtr(m_sString), m_iPos), ByVal StrPtr(sThis), lLen
+ m_iPos = m_iPos + lLen
+End Sub
+
+Public Sub AppendByVal(ByVal sThis As String)
+ Append sThis
+End Sub
+
+Public Sub Insert(ByVal iIndex As Long, ByRef sThis As String)
+ Dim lLen As Long
+ Dim lPos As Long
+ Dim lSize As Long
+
+ ' is iIndex within bounds?
+ If (iIndex * 2 > m_iPos) Then
+ Err.Raise 9
+ Else
+
+ lLen = LenB(sThis)
+ If (m_iPos + lLen) > m_iLen Then
+ m_sString = m_sString & Space$(m_iChunkSize \ 2)
+ m_iLen = m_iLen + m_iChunkSize
+ End If
+
+ ' Move existing characters from current position
+ lPos = UnsignedAdd(StrPtr(m_sString), iIndex * 2)
+ lSize = m_iPos - iIndex * 2
+
+ ' moving from iIndex to iIndex + lLen
+ CopyMemory ByVal UnsignedAdd(lPos, lLen), ByVal lPos, lSize
+
+ ' Insert new characters:
+ CopyMemory ByVal lPos, ByVal StrPtr(sThis), lLen
+
+ m_iPos = m_iPos + lLen
+ End If
+End Sub
+
+Public Sub InsertByVal(ByVal iIndex As Long, ByVal sThis As String)
+ Insert iIndex, sThis
+End Sub
+
+Public Sub Remove(ByVal iIndex As Long, ByVal lLen As Long)
+ Dim lSrc As Long
+ Dim lDst As Long
+ Dim lSize As Long
+
+ ' is iIndex within bounds?
+ If (iIndex * 2 > m_iPos) Then
+ Err.Raise 9
+ Else
+ ' is there sufficient length?
+ If ((iIndex + lLen) * 2 > m_iPos) Then
+ Err.Raise 9
+ Else
+ ' Need to copy characters from iIndex*2 to m_iPos back by lLen chars:
+ lSrc = UnsignedAdd(StrPtr(m_sString), (iIndex + lLen) * 2)
+ lDst = UnsignedAdd(StrPtr(m_sString), iIndex * 2)
+ lSize = (m_iPos - (iIndex + lLen) * 2)
+ CopyMemory ByVal lDst, ByVal lSrc, lSize
+ m_iPos = m_iPos - lLen * 2
+ End If
+ End If
+End Sub
+
+Public Function Find(ByVal sToFind As String, _
+ Optional ByVal lStartIndex As Long = 1, _
+ Optional ByVal compare As VbCompareMethod = vbTextCompare _
+ ) As Long
+
+ Dim lInstr As Long
+ If (lStartIndex > 0) Then
+ lInstr = InStr(lStartIndex, m_sString, sToFind, compare)
+ Else
+ lInstr = InStr(m_sString, sToFind, compare)
+ End If
+ If (lInstr < m_iPos \ 2) Then
+ Find = lInstr
+ End If
+End Function
+
+Public Sub HeapMinimize()
+ Dim iLen As Long
+
+ ' Reduce the string size so only the minimal chunks
+ ' are allocated:
+ If (m_iLen - m_iPos) > m_iChunkSize Then
+ iLen = m_iLen
+ Do While (iLen - m_iPos) > m_iChunkSize
+ iLen = iLen - m_iChunkSize
+ Loop
+ m_sString = Left$(m_sString, iLen \ 2)
+ m_iLen = iLen
+ End If
+
+End Sub
+Private Function UnsignedAdd(Start As Long, Incr As Long) As Long
+' This function is useful when doing pointer arithmetic,
+' but note it only works for positive values of Incr
+
+ If Start And &H80000000 Then 'Start < 0
+ UnsignedAdd = Start + Incr
+ ElseIf (Start Or &H80000000) < -Incr Then
+ UnsignedAdd = Start + Incr
+ Else
+ UnsignedAdd = (Start + &H80000000) + (Incr + &H80000000)
+ End If
+
+End Function
+Private Sub Class_Initialize()
+ ' The default allocation: 8192 characters.
+ m_iChunkSize = 16384
+End Sub
+
+
View
35 plugins/VirusTotal/plugin.cls
@@ -0,0 +1,35 @@
+VERSION 1.0 CLASS
+BEGIN
+ MultiUse = -1 'True
+ Persistable = 0 'NotPersistable
+ DataBindingBehavior = 0 'vbNone
+ DataSourceBehavior = 0 'vbNone
+ MTSTransactionMode = 0 'NotAnMTSObject
+END
+Attribute VB_Name = "plugin"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = True
+Attribute VB_PredeclaredId = False
+Attribute VB_Exposed = True
+
+
+'Function RegisterPlugin(intMenu As Integer, <-- which menu to add to
+' strMenuName As String, <-- menu text
+' intStartupArgument As Integer) <--argument to pass back on select
+
+
+Public frmMain As Object
+
+Sub SetHost(newref As Object)
+ Set frmMain = newref
+ frmMain.RegisterPlugin 0, "Virus Total", 0
+End Sub
+
+Sub StartUp(intArg As Integer)
+ On Error Resume Next
+ Set Form1.frmMain = frmMain
+ Form1.Show '1
+End Sub
+
+
+
View
BIN  plugins/virustotal.dll
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.