From a3423012a64156709a23b523002abf83ef5a1364 Mon Sep 17 00:00:00 2001 From: vm-packages Date: Mon, 1 Apr 2024 21:28:41 +0000 Subject: [PATCH] Add bindiff.vm Closes https://github.com/mandiant/VM-Packages/issues/969. --- packages/bindiff.vm/bindiff.vm.nuspec | 13 ++++ .../bindiff.vm/tools/chocolateyinstall.ps1 | 13 ++++ .../bindiff.vm/tools/chocolateyuninstall.ps1 | 7 ++ packages/common.vm/common.vm.nuspec | 2 +- .../common.vm/tools/vm.common/vm.common.psm1 | 75 ++++++++++++++++++- 5 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 packages/bindiff.vm/bindiff.vm.nuspec create mode 100644 packages/bindiff.vm/tools/chocolateyinstall.ps1 create mode 100644 packages/bindiff.vm/tools/chocolateyuninstall.ps1 diff --git a/packages/bindiff.vm/bindiff.vm.nuspec b/packages/bindiff.vm/bindiff.vm.nuspec new file mode 100644 index 000000000..970dd75cc --- /dev/null +++ b/packages/bindiff.vm/bindiff.vm.nuspec @@ -0,0 +1,13 @@ + + + + bindiff.vm + 8.0.0.20240402 + Zynamics + A comparison tool for binary files that assists in quickly finding differences and similarities in disassembled code + + + + + + diff --git a/packages/bindiff.vm/tools/chocolateyinstall.ps1 b/packages/bindiff.vm/tools/chocolateyinstall.ps1 new file mode 100644 index 000000000..22e15923b --- /dev/null +++ b/packages/bindiff.vm/tools/chocolateyinstall.ps1 @@ -0,0 +1,13 @@ +$ErrorActionPreference = 'Stop' +Import-Module vm.common -Force -DisableNameChecking + +$toolName = 'BinDiff' +$category = 'File Information' + +$exeUrl = 'https://github.com/google/bindiff/releases/download/v8/bindiff8.msi' +$exeSha256 = '688831e490bef8a20c9917048b693bad591f346b3b96489fc79ad8d20d7cb15f' + +$toolDir = Join-Path ${Env:ProgramFiles} $toolName +$executablePath = Join-Path $toolDir "bin\bindiff_ui.cmd" + +VM-Install-With-Installer -toolName $toolName -category $category -fileType "MSI" -silentArgs '/qn /norestart' -executablePath $executablePath -url $exeUrl -sha256 $exeSha256 -consoleApp $false diff --git a/packages/bindiff.vm/tools/chocolateyuninstall.ps1 b/packages/bindiff.vm/tools/chocolateyuninstall.ps1 new file mode 100644 index 000000000..11f2df6e4 --- /dev/null +++ b/packages/bindiff.vm/tools/chocolateyuninstall.ps1 @@ -0,0 +1,7 @@ +$ErrorActionPreference = 'Continue' +Import-Module vm.common -Force -DisableNameChecking + +$toolName = 'BinDiff' +$category = 'File Information' + +VM-Uninstall-With-Uninstaller -toolName $toolName -category $category -fileType "MSI" -silentArgs '/qn /norestart' diff --git a/packages/common.vm/common.vm.nuspec b/packages/common.vm/common.vm.nuspec index 2995c8510..295caf221 100755 --- a/packages/common.vm/common.vm.nuspec +++ b/packages/common.vm/common.vm.nuspec @@ -2,7 +2,7 @@ common.vm - 0.0.0.20240321 + 0.0.0.20240402 Common libraries for VM-packages Mandiant diff --git a/packages/common.vm/tools/vm.common/vm.common.psm1 b/packages/common.vm/tools/vm.common/vm.common.psm1 index 10349bc9d..06074a2d0 100755 --- a/packages/common.vm/tools/vm.common/vm.common.psm1 +++ b/packages/common.vm/tools/vm.common/vm.common.psm1 @@ -568,7 +568,9 @@ function VM-Install-With-Installer { [Parameter(Mandatory=$false)] [bool] $consoleApp=$false, [Parameter(Mandatory=$false)] - [string] $arguments = "" + [string] $arguments = "", + [Parameter(Mandatory=$false)] + [string] $iconLocation ) try { $toolDir = Join-Path ${Env:RAW_TOOLS_DIR} $toolName @@ -621,7 +623,27 @@ function VM-Install-With-Installer { Install-ChocolateyInstallPackage @packageArgs VM-Assert-Path $executablePath - VM-Install-Shortcut -toolName $toolName -category $category -executablePath $executablePath -consoleApp $consoleApp -arguments $arguments + # if no icon path provided, set the shortcut icon to be the executable's icon. For MSI files, attempt to get executable icon from the installer first. + if (-Not $iconLocation) { + if ($fileType -eq 'MSI') { + $iconPath = VM-Get-MSIInstallerPathByProductName $toolName + if ($iconPath) { + $files = Get-ChildItem -Path $iconPath -Filter "*.ico" + if ($files.Count -gt 0) { + $iconLocation = Join-Path $iconPath $files[0] + } + } + # If no icon found from MSI installation, fallback to using executablePath for iconLocation + if (-Not $iconLocation) { + $iconLocation = $executablePath + } + } + } else { + # Not an MSI file, use executablePath for iconLocation + $iconLocation = $executablePath + } + + VM-Install-Shortcut -toolName $toolName -category $category -executablePath $executablePath -consoleApp $consoleApp -arguments $arguments -iconLocation $iconLocation Install-BinFile -Name $toolName -Path $executablePath } catch { VM-Write-Log-Exception $_ @@ -633,7 +655,9 @@ function VM-Uninstall-With-Uninstaller { Param ( [Parameter(Mandatory=$true, Position=0)] - [string] $softwareName, + [string] $toolName, + [Parameter(Mandatory=$true, Position=1)] + [string] $category, [Parameter(Mandatory=$true, Position=1)] [ValidateSet("EXE", "MSI")] [string] $fileType, @@ -652,9 +676,16 @@ function VM-Uninstall-With-Uninstaller { [Parameter(Mandatory=$false)] [array] $validExitCodes= @(0, 3010, 1605, 1614, 1641) ) + # Remove tool shortcut + VM-Remove-Tool-Shortcut $toolName $category + + # Remove tool files + $toolDir = Join-Path ${Env:RAW_TOOLS_DIR} $toolName + Remove-Item $toolDir -Recurse -Force -ea 0 | Out-Null + # Attempt to find and execute the uninstaller, may need to use wildcards # See: https://docs.chocolatey.org/en-us/create/functions/get-uninstallregistrykey - [array]$key = Get-UninstallRegistryKey -SoftwareName $softwareName + [array]$key = Get-UninstallRegistryKey -SoftwareName $toolName if ($key.Count -eq 1) { $packageArgs = @{ packageName = ${Env:ChocolateyPackageName} @@ -1457,3 +1488,39 @@ function VM-Add-To-Path { [System.Environment]::SetEnvironmentVariable("Path", $newPath, [System.EnvironmentVariableTarget]::Machine) } } + +# Useful for getting icons for tools installed from an MSI file +function VM-Get-MSIInstallerPathByProductName { + [CmdletBinding()] + Param( + [Parameter(Mandatory)] + [string]$ProductName # Name of the installed program + ) + + try { + # Get a list of all installed MSI products + $installedProducts = Get-CimInstance -Class Win32_Product | Where-Object { $_.Name -like $ProductName } + + if (-not $installedProducts) { + VM-Write-Log "WARN" "No product found with name like '$ProductName'" + return + } + + foreach ($product in $installedProducts) { + # Retrieve the GUID of the installer + $productCode = $product.IdentifyingNumber + + # Construct the likely path to the installer cache + $installerPath = Join-Path -Path 'C:\Windows\Installer' -ChildPath $productCode + + # Check if the constructed path exists + if (Test-Path -Path $installerPath) { + return $installerPath + } else { + VM-Write-Log "WARN" "Installer cache folder not found for product '$ProductName'" + } + } + } catch { + VM-Write-Log-Exception $_ "An error occurred: $_" + } +}