Installer Analysis Purpose This guide covers analyzing software installer contents without running the installer.
Concepts Software installers often contain archives within archives. Excavate can extract and analyze the contents for security auditing, dependency analysis, or documentation purposes.
Analyzing Windows Installers (MSI) List All Files # List all files in an MSI installer
Excavate :: Archive . new ( 'setup.msi' ). files ( recursive_packages: true ) do | path |
puts path
end Analyze by Extension stats = Excavate :: Archive . new ( 'installer.msi' ). files ( recursive_packages: true ) do | path |
File . extname ( path ). downcase
end
by_ext = stats . group_by ( & :itself ). transform_values ( & :count )
by_ext . sort_by { | _ , count | - count }. each do | ext , count |
puts " #{ ext } : #{ count } "
end Find Executable Files executables = Excavate :: Archive . new ( 'installer.msi' ). files (
recursive_packages: true ,
filter: '**/*.{exe,dll,ocx}'
) do | path |
{
name: File . basename ( path ),
size: File . size ( path )
}
end
executables . each { | e | puts " #{ e [ :name ] } : #{ e [ :size ] } bytes" } Analyzing RPM Packages List Package Contents # List all files in an RPM
Excavate :: Archive . new ( 'package.rpm' ). files ( recursive_packages: true ) do | path |
puts path
end configs = Excavate :: Archive . new ( 'package.rpm' ). extract (
recursive_packages: true ,
filter: '**/etc/**/*'
) Analyzing macOS Packages (PKG) List Package Contents # List all files in a PKG
Excavate :: Archive . new ( 'Installer.pkg' ). files ( recursive_packages: true ) do | path |
puts path
end Excavate :: Archive . new ( 'App.pkg' ). extract (
recursive_packages: true ,
filter: '**/*.app/**/*'
) Security Analysis Find Script Files # Find potential script files
scripts = Excavate :: Archive . new ( 'installer.msi' ). files (
recursive_packages: true ,
filter: '**/*.{bat,cmd,ps1,vbs,js}'
) do | path |
content = File . read ( path )
{ path: path , size: content . size , preview: content [ 0 .. 100 ] }
end
scripts . each { | s | puts " #{ s [ :path ] } : #{ s [ :preview ] } " } Find Configuration Files configs = Excavate :: Archive . new ( 'installer.msi' ). files (
recursive_packages: true ,
filter: '**/*.{conf,config,ini,xml,yaml,yml,json}'
) do | path |
{ path: path , content: File . read ( path ) }
end
configs . each do | c |
puts "=" * 40
puts c [ :path ]
puts c [ :content ]
end Dependency Analysis Find DLL Dependencies dlls = Excavate :: Archive . new ( 'installer.msi' ). files (
recursive_packages: true ,
filter: '**/*.dll'
) do | path |
File . basename ( path )
end
puts "DLLs required:"
dlls . sort . uniq . each { | dll | puts " - #{ dll } " } Documentation Generation Generate File Manifest files = Excavate :: Archive . new ( 'installer.msi' ). files ( recursive_packages: true ) do | path |
{
path: path ,
size: File . size ( path ),
type: File . directory? ( path ) ? 'directory' : 'file'
}
end
puts "Installer Contents:"
puts "-" * 60
files . each do | f |
printf "%-10s %s \n " , " #{ f [ :size ] } bytes" , f [ :path ]
end
puts "-" * 60
puts "Total: #{ files . size } items" CLI Usage # List all files recursively
excavate -r installer.msi
# Extract specific file types
excavate -r --filter "**/*.dll" installer.msi
# Extract and analyze
excavate -r package.rpm
find package -type f | sort