MALICIOUS
854
Risk Score
Malware Insights
MITRE ATT&CK
T1059.005 Visual Basic
T1204.002 Malicious File Execution: Malicious Script
T1059 Command and Scripting Interpreter
T1105 Ingress Tool Transfer
The sample is a malicious Excel file containing heavily obfuscated VBA macros. Critical heuristics indicate the use of WScript.Shell, CreateObject, GetObject, and a VBA property-stored shellcode loader, suggesting the macro is designed to download and execute a second-stage payload. The Workbook_Open and Auto_Open macros are present, indicating an auto-execution mechanism. The presence of 'WScript.Shell usage' and 'Potential Shell call in VBA' strongly suggests command execution capabilities.
Heuristics 22
-
VBA macros detected medium 15 related findings OLE_VBA_MACROSDocument contains VBA macro code
-
Potential Shell call in VBA critical OLE_VBA_SHELLPotential Shell call in VBAMatched line in script
shell "Notepad.exe " & BBPTLogPath, 1 -
WScript.Shell usage critical OLE_VBA_WSCRIPTWScript.Shell usageMatched line in script
Set wsh = VBA.CreateObject("WScript.Shell") -
LOLBin reference in VBA critical OLE_VBA_LOLBINLOLBin reference in VBAMatched line in script
'NPExcel add-in may have been regasm'd in an older BXLA package (when it was running .net2/.net35). -
VBA property-stored shellcode loader critical OLE_VBA_PROPERTY_SHELLCODE_LOADERVBA auto-exec macro takes the address (VarPtr) of a byte buffer decoded from a document property, marks memory executable (VirtualProtect/VirtualAlloc), and transfers control through a callback API (e.g. SetTimer/EnumWindows). The payload is hidden in the document properties rather than the macro source — the SVCReady loader pattern, a native shellcode runner rather than a parser CVE.Matched line in script
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000&, AddressOf TimerProc) -
VBA ActiveX event launches decoded Excel4 macro critical OLE_VBA_ACTIVEX_XLM_STAGERVBA code attached to an auto-firing ActiveX/UserForm control event (e.g. _Layout/_Change/_Painted) decodes a string with Replace/Split/Join/StrReverse/Chr and passes the recovered formula text to ExecuteExcel4Macro. This bridges VBA event activation into XLM formula execution to call Win32 APIs / drop payloads while evading AutoOpen and Shell keyword detection — a high-confidence macro stager, not a specific Office parser CVE.Matched line in script
' Line #1843: ' FuncDefn (Sub ExecuteExcel4Macro()) ' Line #1844: -
VBA UserForm hidden-property command stager critical OLE_VBA_USERFORM_HIDDEN_COMMAND_STAGERVBA auto-exec macro creates a COM object from a decoded variable and reconstructs command text through Split/Join and hidden UserForm properties such as ControlTipText, Tag, Pages, or HelpContextId. This is a high-confidence macro downloader/loader shape seen in the reviewed OLE set, but it is not an Office CVE exploit primitive.Matched line in script
fields = Split(colHeaderNames, ",") -
Obfuscated auto-exec VBA loader critical OLE_VBA_OBFUSCATED_AUTOEXEC_LOADERAuto-exec VBA reconstructs strings with a heavy custom decoder (numeric char-array, repeated hex-string decode, or junk-token Replace removal) and feeds them to a COM-instantiation or execution sink. This obfuscated-loader shape keeps CreateObject/Shell/URL indicators out of the macro source.Matched line in script
Set FSO = CreateObject("Scripting.FileSystemObject") -
VBA macro-virus self-replication / AV tampering critical OLE_VBA_MACRO_VIRUS_REPLICATIONVBA macro programmatically rewrites VBA project code through the VBE object model (CodeModule/VBComponents InsertLines/DeleteLines/AddFromString or OrganizerCopy) to copy itself into the global template and other open documents, and/or disables Office macro-virus protection (Options.VirusProtection = False). This is the defining behavior of the W97M document macro-virus family — self-replicating code with no benign document use, independent of any AV signature.Matched line in script
.InsertLines lineNum, " " -
CreateObject call high OLE_VBA_CREATEOBJCreateObject callMatched line in script
Set FSO = CreateObject("Scripting.FileSystemObject") -
GetObject call high OLE_VBA_GETOBJGetObject callMatched line in script
Set ppApp = GetObject(, "Powerpoint.Application") -
VBA p-code auto-exec with execution tokens high OLE_VBA_PCODE_AUTOEXEC_EXECCompiled VBA/cache stream contains an auto-execution token together with shell/download/object-execution tokens. This catches p-code-only or source-extraction-failure macro documents where visible source is unavailable.
-
Workbook_Open macro low OLE_VBA_WBOPENWorkbook_Open macroMatched line in script
Public Sub Workbook_Open() -
Auto_Open macro low OLE_VBA_AUTOAuto_Open macroMatched line in script
'In Auto_Open of BlpMain.xla, the only instance of this class will be -
Auto_Close macro low OLE_VBA_AUTOCLOSEAuto_Close macroMatched line in script
'We should not do anything in Auto_Close because it is ran before the -
Environ() call (env variable access) low OLE_VBA_ENVIRONEnviron() call (env variable access)Matched line in script
codeBase = Environ("CodebaseDir") -
Reference to ShellExecute API high SC_STR_SHELLEXECReference to ShellExecute API
-
Reference to Windows Script Host high SC_STR_WSCRIPTReference to Windows Script Host
-
Reference to LoadLibrary API high SC_STR_LOADLIBRARYReference to LoadLibrary API
-
Reference to GetProcAddress API high SC_STR_GETPROCADDRESSReference to GetProcAddress API
-
Suspicious extracted artifact high EXTRACTED_FILE_STATIC_TRIAGEOne or more files extracted from inside this sample matched static suspicious-content checks such as script obfuscation, encoded payload blobs, packed data, or execution/download terms.
-
Embedded URL info EMBEDDED_URLOne or more URLs were extracted from the document. The URL itself is not a detection — see the per-URL labels for which channel (macro, JS, link annotation, document body, ...) reached each URL.URL http://127.0.0.1 In document text (OLE body)
- http://172.17.2.46/apiservices/ard/ardservice.asmxIn document text (OLE body)
- http://10.16.98.204:8291/_layouts/GAPI/filelisting.aspx?library=Templates2&folder=In document text (OLE body)
- http://sf.symcd.com0&In document text (OLE body)
- http://ocsp.verisign.com0In document text (OLE body)
- http://schemas.microsoft.com/office/2006/01/customuiIn document text (OLE body)
- http://support.microsoft.com/default.aspx?scid=kb;EN-US;q176790In document text (OLE body)
- http://support.microsoft.com/kb/186047/en-usIn document text (OLE body)
- http://support.microsoft.com/kb/213181In document text (OLE body)
- http://logo.verisign.com/vslogo.gif0In document text (OLE body)
- https://www.verisign.com/rpaIn document text (OLE body)
- https://d.symcb.com/cps0%In document text (OLE body)
- https://d.symcb.com/rpa0In document text (OLE body)
- http://sf.symcb.com/sf.crl0WIn document text (OLE body)
- http://sf.symcb.com/sf.crt0In document text (OLE body)
- https://www.verisign.com/cps0*In document text (OLE body)
- https://www.verisign.com/rpa0In document text (OLE body)
- http://logo.verisign.com/vslogo.gif04In document text (OLE body)
- http://crl.verisign.com/pca3-g5.crl04In document text (OLE body)
Extracted artifacts 1
Files carved from inside the sample during analysis.
| Filename | Kind | Source | Size |
|---|---|---|---|
macros.bas |
vba-macro | oletools.olevba.extract_macros (decoded VBA source) | 8388608 bytes |
SHA-256: 34f38f0dd7a547e45f723f4fdab5fb43384693b171f57b682d02657d3241a6f3 |
|||
|
Detection
ClamAV:
No threats found
Obfuscation or payload:
likely
Carved artifact contains 1 eval/decoder/string-building token(s).
|
|||
Preview scriptFirst 1,000 lines of the extracted script
Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Option Explicit
Dim appHandler As ApplicationEvents
Dim BBPTv2_appHandler As BBPTv2_ApplicationEvents
Dim g_prfl_handle As Long
#If VBA7 Then
Dim hAddinMutex As LongPtr
#Else
Dim hAddinMutex As Long
#End If
Private Sub Workbook_AddinInstall()
pushTrace "Workbook_AddinInstall", "ThisWorkbook.cls"
'DRQS 35536800 - introduce mutex IPC to avoid automation from ribbon
'to check if add-in is loaded or not
g_prof.handle = Prof_BeginSPS("AddinLoading_A", "AddinInstall_E") 'Profiling time since process(Excel) started till this call
If 0 <> hAddinMutex Then
CloseHandle hAddinMutex
End If
hAddinMutex = CreateMutex(0, 1, "bbshared" & CStr(GetCurrentProcessId()))
InstallCOMAddin True
popTrace "Workbook_AddinInstall"
End Sub
Private Sub Workbook_AddinUninstall()
pushTrace "Workbook_AddinUninstall", "ThisWorkbook.cls"
Dim oPopup As Object
DeleteGlobals
On Error GoTo FunctionEnd 'DRQS 9796347
' DRQS 9564315
Set oPopup = Application.CommandBars("Worksheet Menu Bar").Controls("&View")
oPopup.CommandBar.Controls("&Bloomberg Menu").Delete
FunctionEnd:
On Error GoTo FunctionEnd1
If val(Application.Version) > 11 And gRibbonAddinName <> "" Then
Workbooks(gRibbonAddinName).Close
Else
InstallCOMAddin False
End If
FunctionEnd1:
popTrace "Workbook_AddinUninstall"
End Sub
Private Sub InstallCOMAddin(Connect As Boolean)
pushTrace "InstallCOMAddin", "ThisWorkbook.cls", Connect
Dim i As Long
For i = 1 To Application.COMAddIns.count
If Application.COMAddIns(i).progId = "Bloomberg.CCYReader" Then
Application.COMAddIns(i).Connect = Connect
End If
Next
popTrace "InstallCOMAddin"
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
pushTrace "Workbook_BeforeClose", "ThisWorkbook.cls", Cancel
On Error Resume Next
If g_MainInitialized Then
Save_ToolbarPositions
' V3Status_OnClose
Refresh_OnClose
MAIN_Shutdown
HitCount
End If
ResetEvents
BLPMain_ResetEvents
' If (Not appHandler Is Nothing) Then
' Set appHandler = Nothing
' End If
' If (Not BBPTv2_appHandler Is Nothing) Then
' Set BBPTv2_appHandler = Nothing
' End If
'Show_CellFormatState
popTrace "Workbook_BeforeClose"
End Sub
Public Sub Workbook_Open()
pushTrace "Workbook_Open", "ThisWorkbook.cls"
Dim oPopup As Object
Dim originalUpdating As Boolean
If (g_prof.handle = 0) Then
g_prof.handle = Prof_BeginSPS("ExcelLoading_A", "EL_BUI_WbOpen_E") 'Profiling time since process(Excel) started till this call, ExcelLoading_A activity
Else
g_prof.Res = Prof_Mark(g_prof.handle, "EL_BUI_WbOpen_E") 'AddinLoading_A activity
End If
Application.OnTime Now, "'Prof_WBOpen_Timer_Event """ & LTrim(CStr(g_prof.handle)) & """'"
If val(Application.Version) < 10 Then
GoTo FunctionEnd
End If
'TREQ 3117337 - global add-in kill switch
If IsAddinKillSwitchEnabled Then
GoTo FunctionEnd
End If
originalUpdating = EXCEL.Application.ScreenUpdating
EXCEL.Application.ScreenUpdating = False
InitGlobals
g_prof.Res = Prof_Mark(g_prof.handle, "EL_InitGlobals_Done_E")
If IsLinkManagerV2Available Then
Set BBPTv2_appHandler = New BBPTv2_ApplicationEvents
Else
Set appHandler = New ApplicationEvents
End If
EXCEL.Application.ScreenUpdating = originalUpdating
On Error GoTo FunctionEnd
Set oPopup = Application.CommandBars("Worksheet Menu Bar").Controls("&View")
oPopup.CommandBar.Controls("&Bloomberg Menu").Delete
FunctionEnd:
ConditionallyRestoreRTDThottleInterval
g_prof.Res = Prof_Mark(g_prof.handle, "EL_BUI_WbOpen_Done_E")
popTrace "Workbook_Open"
End Sub
Attribute VB_Name = "Sheet1"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Attribute VB_Name = "Sheet2"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Attribute VB_Name = "Sheet3"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Attribute VB_Name = "ModuleImporter"
Option Explicit
Option Private Module
''
Const vbext_ct_ClassModule = 2
Const vbext_ct_Document = 100
Const vbext_ct_MSForm = 3
Const vbext_ct_StdModule = 1
Const DiffProgramLocation = "\Src\Utilities\VBAUtils\diff.exe"
Const GitProgramLocation = "\Src\Utilities\VBAUtils\git.exe"
Dim bleSkipModuleTracking As Boolean
Dim FSO As Object
Dim tmpExportFolders() As String
Sub testImportModulesFromFolder()
Dim codeBase As String
codeBase = Environ("CodebaseDir")
#If EXCEL Then
ReDim tmpExportFolders(4)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\ExcelAddins\XLAS\VBAModules\Excel\"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
tmpExportFolders(4) = codeBase & "\Src\OfficeAddins\Common\VBA\LM\"
#ElseIf POWERPOINT And LOADER Then
ReDim tmpExportFolders(3)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\PowerPoint\PowerPoint\Loader"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
#ElseIf POWERPOINT And LEGACY Then
ReDim tmpExportFolders(5)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\PowerPoint\PowerPoint\"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\PowerPoint\PowerPoint\Legacy"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(4) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
tmpExportFolders(5) = codeBase & "\Src\OfficeAddins\Common\VBA\LM\"
#ElseIf POWERPOINT Then
ReDim tmpExportFolders(4)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\PowerPoint\PowerPoint\"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
tmpExportFolders(4) = codeBase & "\Src\OfficeAddins\Common\VBA\LM\"
#ElseIf WORD And LEGACY Then
ReDim tmpExportFolders(5)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\Word\Word\"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\Word\WordLegacy\"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(4) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
tmpExportFolders(5) = codeBase & "\Src\OfficeAddins\Common\VBA\LM\"
#ElseIf WORD Then
ReDim tmpExportFolders(4)
tmpExportFolders(0) = codeBase & "\Src\OfficeAddins\Word\Word\"
tmpExportFolders(1) = codeBase & "\Src\OfficeAddins\Common\VBA\"
tmpExportFolders(2) = codeBase & "\Src\OfficeAddins\Common\VBA\APIRegistry\"
tmpExportFolders(3) = codeBase & "\Src\OfficeAddins\Common\VBA\OFCUI\"
tmpExportFolders(4) = codeBase & "\Src\OfficeAddins\Common\VBA\LM\"
#End If
Dim idx As Integer
For idx = LBound(tmpExportFolders) To UBound(tmpExportFolders)
importModulesFromFolder tmpExportFolders(idx)
Next idx
checkModuleChanges "", True, True
appendExportFoldersFunction tmpExportFolders
End Sub
Sub appendExportFoldersFunction(tmpExportFolders() As String)
Dim v
Dim VBProj As Variant
Dim VBComp As Variant
Dim CodeMod As Variant
Dim lineNum As Long
Const DQUOTE = """"
Dim idx As Integer
For Each VBComp In Application.VBE.ActiveVBProject.VBComponents
If VBComp.name = "ModuleImporterHash" Then
Set CodeMod = VBComp.CodeModule
Exit For
End If
Next VBComp
With CodeMod
lineNum = .CountOfLines + 1
.InsertLines lineNum, " "
lineNum = lineNum + 1
.InsertLines lineNum, "Public Function getExportFolders() As String()"
lineNum = lineNum + 1
.InsertLines lineNum, " Static exportFolders(0 To " & UBound(tmpExportFolders) & ") As String"
lineNum = lineNum + 1
.InsertLines lineNum, " Static assigned As Boolean"
lineNum = lineNum + 1
.InsertLines lineNum, " If Not assigned Then"
lineNum = lineNum + 1
.InsertLines lineNum, " assigned = True"
lineNum = lineNum + 1
For idx = LBound(tmpExportFolders) To UBound(tmpExportFolders)
.InsertLines lineNum, " exportFolders(" & CStr(idx) & ") = " & DQUOTE & tmpExportFolders(idx) & DQUOTE
lineNum = lineNum + 1
Next idx
.InsertLines lineNum, " End If"
lineNum = lineNum + 1
.InsertLines lineNum, " getExportFolders = exportFolders"
lineNum = lineNum + 1
.InsertLines lineNum, "End Function"
End With
End Sub
Public Function getFSO() As Object
If FSO Is Nothing Then
Set FSO = CreateObject("Scripting.FileSystemObject")
End If
Set getFSO = FSO
End Function
Public Sub importModuleFromFile(modulePath As String)
If (dir(modulePath, vbNormal) <> "") Then
Application.VBE.ActiveVBProject.VBComponents.Import modulePath
End If
End Sub
Public Sub importModulesFromFolder(SourceFolder As String)
Dim moduleFile As String
Dim mask As String
If (dir(SourceFolder, vbDirectory) <> "") Then
mask = SourceFolder & "\" & "*.cls"
moduleFile = dir(mask)
Do While moduleFile <> ""
If moduleFile = "ThisWorkbook.cls" Then
ReadModuleCodeFromFile Application.VBE.ActiveVBProject.VBComponents.Item("ThisWorkbook"), SourceFolder & "\" & moduleFile
ElseIf Mid(moduleFile, 1, 5) = "Sheet" Then
''NOTHING FOR NOW!
Else
Application.VBE.ActiveVBProject.VBComponents.Import SourceFolder & "\" & moduleFile
End If
moduleFile = dir
Loop
mask = SourceFolder & "\" & "*.bas"
moduleFile = dir(mask)
Do While moduleFile <> ""
If moduleFile = "ModuleImporter.bas" Then
''NOTHING FOR NOW!
Else
Application.VBE.ActiveVBProject.VBComponents.Import SourceFolder & "\" & moduleFile
End If
moduleFile = dir
Loop
mask = SourceFolder & "\" & "*.frm"
moduleFile = dir(mask)
Do While moduleFile <> ""
Application.VBE.ActiveVBProject.VBComponents.Import SourceFolder & "\" & moduleFile
moduleFile = dir
Loop
End If
End Sub
Sub ForceExportModules()
Dim codeBase As String
On Error GoTo handleError
bleSkipModuleTracking = True
ExportModules
handleError:
bleSkipModuleTracking = False
End Sub
Sub WriteModuleCodeToFile(VBComp As Variant, strPath As String)
Dim oFile As Object
Dim strLines As String
If VBComp.CodeModule.CountOfLines > 0 Then
Set oFile = FSO.CreateTextFile(strPath)
strLines = VBComp.CodeModule.Lines(1, VBComp.CodeModule.CountOfLines)
oFile.WriteLine strLines
oFile.Close
Set FSO = Nothing
End If
End Sub
Sub ReadModuleCodeFromFile(VBComp As Variant, strPath As String)
Dim oFile As Object
Dim strLines As String
Dim deleteLineCount As Integer
Dim i As Integer
deleteLineCount = 0
VBComp.CodeModule.AddFromFile strPath
strLines = VBComp.CodeModule.Lines(1, 1)
If (InStr(strLines, "VERSION 1.0 CLASS") > 0) Then
For i = 2 To VBComp.CodeModule.CountOfLines + 1
strLines = VBComp.CodeModule.Lines(i, 1)
If (InStr(LCase(strLines), LCase("Option Explicit")) > 0) Then
deleteLineCount = i - 1
Exit For
End If
Next i
End If
If deleteLineCount > 0 Then
VBComp.CodeModule.DeleteLines 1, deleteLineCount
End If
End Sub
Function overwriteIfChanged(newFile As String, AppSpecificTargetFile As String) As Boolean
Dim result As Integer
Dim tempOut As String
Dim f
Dim doCopy As Boolean
doCopy = False
Dim actionReport As String
Dim targetFile As String
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 0
Dim errorCode As Integer
Dim codeBase As String
codeBase = Environ("CodebaseDir")
Dim exportFolders() As String
overwriteIfChanged = False
exportFolders = Application.Run("getExportFolders")
'''''Check in which folder the file is residing currently'''
Dim idx As Integer
For idx = LBound(exportFolders) To UBound(exportFolders)
If getFSO().FileExists(codeBase & "\" & exportFolders()(idx) & AppSpecificTargetFile) Then
targetFile = codeBase & "\" & exportFolders()(idx) & "\" & AppSpecificTargetFile
Exit For
End If
Next idx
If targetFile = "" Then
targetFile = codeBase & "\" & exportFolders()(0) & "\" & AppSpecificTargetFile
End If
errorCode = wsh.Run(Chr(34) & Environ("CodebaseDir") & DiffProgramLocation & Chr(34) & " -i " & newFile & " " & targetFile, windowStyle, waitOnReturn)
If errorCode = 0 Then
doCopy = False
Else
doCopy = True
End If
If doCopy And getFSO().FileExists(newFile) Then
If getFSO().FileExists(targetFile) Then
getFSO().DeleteFile (targetFile)
End If
getFSO().CopyFile newFile, targetFile
actionReport = "CHANGED "
Else
actionReport = "KEPT "
End If
If InStr(targetFile, ".bak") > 0 Then
targetFile = newFile
End If
Debug.Print actionReport & " [" & targetFile & "]"
Set wsh = Nothing
overwriteIfChanged = doCopy
End Function
Sub ExportModules()
Dim VBComp As Variant
Dim tempFile As String
Dim lineCharCount As Integer
Dim tmpSavePath As String
tmpSavePath = Environ$("TEMP")
lineCharCount = 0
If dir(tmpSavePath, vbDirectory) <> "" Then
tempFile = tmpSavePath & "\" & "TempFile"
For Each VBComp In Application.VBE.ActiveVBProject.VBComponents
If checkModuleChanges(VBComp.name, True) Or (VBComp.Type = vbext_ct_MSForm And VBComp.HasOpenDesigner) Then
If lineCharCount > 0 Then
lineCharCount = 0
Debug.Print
End If
Select Case VBComp.Type
Case vbext_ct_StdModule
VBComp.Export tempFile
overwriteIfChanged tempFile, VBComp.name & ".bas"
Case vbext_ct_Document
#If EXCEL Then
WriteModuleCodeToFile VBComp, tempFile
overwriteIfChanged tempFile, VBComp.name & ".cls"
#End If
Case vbext_ct_ClassModule
' ThisDocument and class modules
VBComp.Export tempFile
overwriteIfChanged tempFile, VBComp.name & ".cls"
Case vbext_ct_MSForm
'''' For Forms we have to export to the correct file, otherwise the wrong info about temp
'''' file will be stuck in the file causing problems!
VBComp.Export tmpSavePath & "\" & VBComp.name & ".frm"
overwriteIfChanged tmpSavePath & "\" & VBComp.name & ".frm", VBComp.name & ".frm"
overwriteIfChanged tmpSavePath & "\" & VBComp.name & ".frx", VBComp.name & ".frx"
Kill tmpSavePath & "\" & VBComp.name & ".frm"
Kill tmpSavePath & "\" & VBComp.name & ".frx"
Case Else
VBComp.Export tempFile
overwriteIfChanged tempFile, tmpSavePath & "\" & VBComp.name
End Select
Else
Debug.Print ".";
lineCharCount = lineCharCount + 1
If (lineCharCount >= 100) Then
Debug.Print
lineCharCount = 0
End If
End If
Next
If dir(tempFile) <> "" Then
Kill tempFile
End If
End If
If (lineCharCount > 0) Then Debug.Print
Debug.Print "Export done."
End Sub
Sub deleteAllModules()
Dim VBComp As Variant
Dim cnt As Integer
For Each VBComp In Application.VBE.ActiveVBProject.VBComponents
If VBComp.name <> "ModuleImporter" And VBComp.name <> "ThisWorkbook" And VBComp.Type <> vbext_ct_Document Then
Application.VBE.ActiveVBProject.VBComponents.Remove VBComp
ElseIf VBComp.Type = vbext_ct_Document Then
cnt = VBComp.CodeModule.CountOfLines
If cnt > 0 Then
VBComp.CodeModule.DeleteLines 1, VBComp.CodeModule.CountOfLines
End If
End If
Next
End Sub
Function computeCRC16(txt As String) As String
Dim x As Long
Dim mask, i, j, nC, Crc As Integer
Dim c As String
Crc = &HFFFF
For nC = 1 To Len(txt) Step 2
j = val("&H" + LCase$(Mid(txt, nC, 2)))
Crc = Crc Xor j
For j = 1 To 8
mask = 0
If Crc / 2 <> Int(Crc / 2) Then mask = &HA001
Crc = Int(Crc / 2) And &H7FFF: Crc = Crc Xor mask
Next j
Next nC
computeCRC16 = Hex$(Crc) ''
End Function
Public Function checkModuleChanges(Optional moduleName As String = "", Optional Reset As Boolean = False, Optional Serialize As Boolean = False, Optional PassedEnvCodeBaseDir As String = "") As Boolean
Dim VBComp As Variant
Dim strContent As String
Dim strHash As String
Dim strHashNew As String
Dim allComponents As Variant
Static moduleChanges As Object
Dim lineCharCount As Integer
lineCharCount = 0
checkModuleChanges = False
''''Never save for ModuleImporterHash: False means no changes'''
If moduleName = "ModuleImporterHash" Then
Exit Function
End If
''''Always save when the SkipModuleTracking is set: True means Yes, there were changes! '''
If bleSkipModuleTracking Then
checkModuleChanges = True
Exit Function
End If
If moduleChanges Is Nothing Then
Set moduleChanges = CreateObject("Scripting.Dictionary")
On Error Resume Next
Application.Run "PopulateHashDictionary", moduleChanges
On Error GoTo 0
End If
If moduleName = "" Then
Set allComponents = Application.VBE.ActiveVBProject.VBComponents
Else
Set allComponents = New Collection
allComponents.Add Application.VBE.ActiveVBProject.VBComponents.Item(moduleName)
End If
For Each VBComp In allComponents
Dim numLines As Integer
numLines = VBComp.CodeModule.CountOfLines
If numLines = 0 Then
numLines = 1
End If
strContent = VBComp.name & vbNewLine & "--" & vbNewLine & VBComp.CodeModule.Lines(1, numLines)
strHashNew = computeCRC16(strContent) '''Application.Run("hashStr", strContent)
If (moduleChanges.Exists(VBComp.name)) Then
strHash = moduleChanges.Item(VBComp.name)
Else
strHash = vbNullString
End If
If moduleName = "" Then
If strHashNew <> strHash Then
Debug.Print "+";
Else
Debug.Print ".";
End If
lineCharCount = lineCharCount + 1
If (lineCharCount >= 100) Then
Debug.Print
lineCharCount = 0
End If
End If
If strHashNew <> strHash Then
checkModuleChanges = True
If (moduleChanges.Exists(VBComp.name)) Then
If Reset Then
moduleChanges.Item(VBComp.name) = strHashNew
End If
Else
moduleChanges.Add VBComp.name, strHashNew
End If
End If
Next VBComp
If Serialize Then
Dim v
Dim VBProj As Variant
Dim CodeMod As Variant
Dim lineNum As Long
Const DQUOTE = """"
For Each VBComp In Application.VBE.ActiveVBProject.VBComponents
If VBComp.name = "ModuleImporterHash" Then
Application.VBE.ActiveVBProject.VBComponents.Remove VBComp
Exit For
End If
Next VBComp
Set VBProj = Application.VBE.ActiveVBProject
Set VBComp = VBProj.VBComponents.Add(vbext_ct_StdModule)
VBComp.name = "ModuleImporterHash"
Set CodeMod = VBComp.CodeModule
'''''''''''''''''''''''' GET THE GIT HASH '''''''''''''''''''''''''
On Error Resume Next
Dim GitHash As String
Dim HASHfile As String
Dim f, contents, var1
Set f = getFSO().OpenTextFile(PassedEnvCodeBaseDir & "\.git\HEAD", 1)
contents = f.ReadAll
f.Close
f = Null
HASHfile = Replace$(Mid$(contents, 6), "/", "\")
HASHfile = Left$(HASHfile, Len(HASHfile) - 1)
HASHfile = PassedEnvCodeBaseDir & "\.git\" & HASHfile & ""
Set f = getFSO().OpenTextFile(HASHfile)
GitHash = Left$(f.ReadAll, 10)
f.Close
On Error GoTo 0
'''''''''''''''''''''''' GOT THE GIT HASH ''''''''''''''''''''''''''
With CodeMod
lineNum = .CountOfLines + 1
.InsertLines lineNum, "Public Const LatestGitHash = " & DQUOTE & GitHash & DQUOTE
lineNum = lineNum + 1
.InsertLines lineNum, "Public Const BuildDateTime = " & DQUOTE & Now & DQUOTE
lineNum = lineNum + 1
.InsertLines lineNum, ""
lineNum = lineNum + 1
.InsertLines lineNum, "Public Sub PopulateHashDictionary(byref d as Object)"
For Each v In moduleChanges.Keys
lineNum = lineNum + 1
.InsertLines lineNum, " d.add " & DQUOTE & v & DQUOTE & "," & DQUOTE & moduleChanges.Item(v) & DQUOTE
Next v
lineNum = lineNum + 1
.InsertLines lineNum, "End Sub"
End With
End If
If moduleName = "" Then
If lineCharCount > 0 Then Debug.Print
Debug.Print "Done (Re)hashing."
End If
End Function
Attribute VB_Name = "AboutBox"
Attribute VB_Base = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = False
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function GetSessionOptions Lib "bbrtd.dll" () As String
#Else
Private Declare Function GetSessionOptions Lib "bbrtd.dll" () As String
#End If
Implements ITool
Private m_proxy As ToolProxy
' More magic about box changes
Private Sub Class_Initialize()
pushTrace "Class_Initialize", "AboutBox.cls"
If m_proxy Is Nothing Then
Set m_proxy = New ToolProxy
m_proxy.VBAWorkbookName = "BloombergUI"
m_proxy.toolName = "AboutBox"
m_proxy.AssemblyName = "AboutBox"
m_proxy.ManagedTypeName = "Bloomberg.OfficeTools.AboutBox.AboutBox"
End If
popTrace "Class_Initialize"
End Sub
Private Sub Class_Terminate()
pushTrace "Class_Terminate", "AboutBox.cls"
Set m_proxy = Nothing
popTrace "Class_Terminate"
End Sub
Public Sub ITool_Activate(Parameters() As Variant)
pushTrace "ITool_Activate", "AboutBox.cls"
If m_proxy Is Nothing Then
popTrace "ITool_Activate"
Exit Sub
End If
ReDim Parameters(2)
Parameters(0) = ""
If isV3Enabled() Then
Parameters(1) = "v3"
Else
Parameters(1) = "v2"
End If
If Not IsDisabledSessionOptionsDisplay() Then
Parameters(2) = GetSessionOptions()
End If
m_proxy.ITool_Activate Parameters
popTrace "ITool_Activate"
End Sub
Public Function ITool_OnDeactivated() As String()
pushTrace "ITool_OnDeactivated", "AboutBox.cls"
Dim Parameters(0) As String
If m_proxy Is Nothing Then
popTrace "ITool_OnDeactivated"
Exit Function
End If
m_proxy.ITool_OnDeactivated
Parameters(0) = ""
ITool_OnDeactivated = Parameters
popTrace "ITool_OnDeactivated"
End Function
Attribute VB_Name = "AddinLoader"
Attribute VB_Base = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = False
Option Explicit
Public Function LoadLocally(addinName As String) As Boolean
pushTrace "LoadLocally", "AddinLoader.cls", addinName
LoadLocally = True
Dim addinPath As String
addinPath = ThisWorkbook.path & "\" & addinName
On Error GoTo failure
Workbooks.Open (addinPath)
popTrace "LoadLocally"
Exit Function
failure:
LoadLocally = False
popTrace "LoadLocally"
End Function
Attribute VB_Name = "ApplicationEvents"
Attribute VB_Base = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = False
Option Explicit
Dim WithEvents excelApp As Application
Attribute excelApp.VB_VarHelpID = -1
Dim SheetAutoColorShadow As String
Dim SheetAutoColor As String
Private Sub Class_Initialize()
pushTrace "Class_Initialize", "ApplicationEvents.cls"
Set excelApp = Application
popTrace "Class_Initialize"
End Sub
Private Sub Class_Terminate()
pushTrace "Class_Terminate", "ApplicationEvents.cls"
Set excelApp = Nothing
popTrace "Class_Terminate"
End Sub
Private Sub excelApp_NewWorkbook(ByVal wb As Workbook)
pushTrace "excelApp_NewWorkbook", "ApplicationEvents.cls", wb
BuildFormattingMenus_OnTime
popTrace "excelApp_NewWorkbook"
End Sub
Private Sub excelApp_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim strWksName As String
On Error Resume Next
If InStr(Sh.name, " ") > 0 Then
strWksName = Sh.Names("'" & Sh.name & "'" & "!" & AutoColor_RangeName_Wks).name
Else
strWksName = Sh.Names(Sh.name & "!" & AutoColor_RangeName_Wks).name
End If
If Err.Number = 0 Then
Wks_SetChangeForAutoColorOn Sh, Target.address
End If
'If Not Sh Is Nothing Then
'Wks_SetChangeForAutoColorOn Sh, Target.address
'End If
End Sub
Private Sub excelApp_SheetActivate(ByVal Sh As Object)
pushTrace "excelApp_SheetActivate", "ApplicationEvents.cls", Sh
Dim wksName As String
On Error Resume Next
If SheetAutoColor <> "" Then
If Not xlWksExists(Sh.Parent, SheetAutoColor) Then
Application.DisplayAlerts = False
Worksheets(SheetAutoColorShadow).Visible = True
Worksheets(SheetAutoColorShadow).Delete
Application.DisplayAlerts = True
End If
End If
popTrace "excelApp_SheetActivate"
End Sub
Private Sub excelApp_SheetDeactivate(ByVal Sh As Object)
pushTrace "excelApp_SheetDeactivate", "ApplicationEvents.cls", Sh
Dim wksName As String
Dim nameString As String
Dim nm As EXCEL.name
On Error Resume Next
nameString = "'" & Sh.name & "'" & "!" & AutoColor_RangeName_Wks
If xlNameExists(nameString) Then
Set nm = Sh.Names(nameString)
If xlWksExists(Sh.Parent, Mid(nm.RefersTo, 3, Len(nm.RefersTo) - 3)) Then
wksName = Mid(nm.RefersTo, 3, Len(nm.RefersTo) - 3)
SheetAutoColorShadow = wksName
SheetAutoColor = Sh.name
Else
SheetAutoColorShadow = ""
SheetAutoColor = ""
End If
End If
popTrace "excelApp_SheetDeactivate"
End Sub
Private Sub excelApp_WorkbookAfterSave(ByVal wb As Workbook, ByVal success As Boolean)
RestoreCreatedStateAllComponents wb
End Sub
Private Sub excelApp_WorkbookBeforeClose(ByVal wb As Workbook, Cancel As Boolean)
pushTrace "excelApp_WorkbookBeforeClose", "ApplicationEvents.cls", wb, Cancel
On Error GoTo handleError
' Dim strNm As String
' Dim strFullName As String
'
' strNm = FirstLinkedRangeName(Wb)
' If Len(strNm) > 0 Then
' strFullName = Wb.fullname
'' Cancel = True
' Fire_UpdateLinkedRanges strFullName, strNm
' End If
' Dim bleHasAutoColor As Boolean
Dim wnd As Window
If Application.Visible Then
If val(Application.Version) < 15 Then
Application.EnableEvents = False
Else ' for excel 2013
For Each wnd In Application.Windows
If UCase$(wnd.Caption) = UCase$(wb.name) Then
'wnd.Activate
wb.Activate
Else
ThisWorkbook.Activate
End If
Next wnd
End If
Else
Application.EnableEvents = False
End If
If Not (wb Is Nothing) Then
If wb.IsAddin = False And IsPowerToolsAvailable = True Then
UpdateMyLinkedRanges_OnClose wb, Cancel
End If
If wb.IsAddin = False And Cancel = False Then
ClearComponents_OnClose wb, Cancel
End If
End If
ExitHere:
Application.EnableEvents = True
popTrace "excelApp_WorkbookBeforeClose"
Exit Sub
handleError:
Gen_ErrHandle "ApplicationEvents.excelApp_WorkbookBeforeClose"
Resume ExitHere
popTrace "excelApp_WorkbookBeforeClose"
End Sub
Private Sub ClearComponents_OnClose(wb As Workbook, ByRef Cancel As Boolean)
Dim Caption As String
If Cancel = False Then
ClearAllComponents wb
End If
End Sub
Private Sub excelApp_WorkbookBeforeSave(ByVal wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
pushTrace "excelApp_WorkbookBeforeSave", "ApplicationEvents.cls", wb, SaveAsUI, Cancel
On Error GoTo handleError
If Application.Visible Then
If val(Application.Version) < 15 Then
Application.EnableEvents = False
End If
Else
Application.EnableEvents = False
End If
If xlTestGetActiveWbkWks() = True Or xlTestGetActiveWbkChartSht() = True Then
If IsPowerToolsAvailable = True Then
UpdateMyLinkedRanges_OnSave wb
' If Wb.Saved = False Then
' Cancel = StopSaveForAutoColor(Wb)
' End If
End If
End If
ClearAllComponents wb
ExitHere:
Application.EnableEvents = True
popTrace "excelApp_WorkbookBeforeSave"
Exit Sub
handleError:
Gen_ErrHandle "ApplicationEvents.excelApp_WorkbookBeforeSave"
Resume ExitHere
Resume
popTrace "excelApp_WorkbookBeforeSave"
End Sub
Private Sub UpdateMyLinkedRanges_OnClose(wb As Workbook, _
ByRef Cancel As Boolean)
pushTrace "UpdateMyLinkedRanges_OnClose", "ApplicationEvents.cls", wb, Cancel
Dim strNm As String
Dim strFullName As String
Dim strMsg As String
Dim MyResponse As VbMsgBoxResult
Dim nameCountTest As Integer
On Error Resume Next
nameCountTest = wb.Names.count
If Err.Number <> 0 Then
Log_BBPTError "Workbook Empty Warning", "UpdateMyLinkedRanges_OnClose"
…
|
|||
Open this report in the interactive analyzer, or submit your own file for analysis.