0x00 Preface

---

Recently, I encountered an interesting issue: when trying to use WMI to obtain the list of installed programs on the current system, I couldn't get a complete list. So, I conducted further research, identified the cause of the error, changed my approach, and achieved the goal.

This article is an introductory piece on basic knowledge, aimed at solving fundamental problems.

0x01 Introduction

---

This article will cover the following topics:

  • Obtaining the list of installed programs on the current system via WMI
  • Reasons for incomplete WMI query results
  • Implementation ideas for obtaining a complete program list

0x02 Obtaining the List of Installed Programs on the Current System

---

1. Using PowerShell to call WMI

The code is as follows:

Get-WmiObject -class Win32_Product

Filter the output results to display only program names, the code is as follows:

Get-WmiObject -class Win32_Product | Select-Object -Property name

The obtained result is shown in the figure below

Alt text

2. Using wmic to call WMI

The code is as follows:

wmic /NAMESPACE:"\\root\CIMV2" PATH Win32_Product

Filter the output results to display only program names, the code is as follows:

wmic /NAMESPACE:"\\root\CIMV2" PATH Win32_Product get name /FORMAT:table

The obtained result is shown in the figure below

Alt text

3. Using WMI Explorer to call WMI

Download address:

https://wmie.codeplex.com/releases/view/135794

A GUI-based WMI query tool that can be used to query WMI-supported classes, making it a great tool for studying WMI.

First, click Connect to connect to the local machine.

Select ROOT\CIMV2 -> Query.

Enter the query command:

SELECT * FROM Win32_Product

The result is shown in the figure below.

Alt text

4. Query installed programs via Control Panel

Control Panel -> Programs -> Programs and Features

It is found that some programs cannot be obtained through WMI queries, such as Google Chrome. The comparison result is shown in the figure below.

Alt text

0x03 Reasons for incomplete WMI query results

---

Querying Win32_Product via WMI can only retrieve a specific list of programs.

These programs share a common characteristic: their installation packages are created by Windows Installer, and the installation process invokes the Windows Installer service for installation.

Note:

Microsoft Windows Installer: A component of the Windows operating system, serving as the standard foundation for installing and uninstalling software.

Windows Installer Service: Adds, modifies, and removes applications provided as Windows Installer packages.

In addition to Microsoft Windows Installer, tools like EasySetup, Setup2Go, Advanced Installer, Qt installer framework, and WinRAR can also be used to create installation packages.

Chrome does not invoke the Microsoft Windows Installer component during its installation process, so it cannot be found by querying Win32_Product via WMI.

0x04 Implementation Approach for Obtaining a Complete Program List

---

We know that the program list obtained via Control Panel -> Programs -> Programs and Features is relatively complete. This list corresponds to the registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\

Each subkey represents a program in the list.

Therefore, a complete program list can be obtained by enumerating registry keys.

It is worth noting that on 64-bit systems, registry redirection issues can also affect the display of the program list.

The 32-bit program list corresponds to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\

The 64-bit program list corresponds to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\

Note:

This issue was previously summarized in the article 'Notes on Redirection Issues When Running 32-bit Programs on 64-bit Systems'.

Write a PowerShell script to enumerate the registry and obtain a complete list of programs.

Key code:

1. Enumerate subkeys under the specified registry key

dir Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall -Name

As shown in the figure below

Alt text

2. Query the registry key values of the specified registry key

(Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{4F3742E0-700E-431D-BF19-5B27ED98E8F1}").DisplayName

As shown in the figure below

Alt text

3. Implement enumeration by adding a foreach loop

$RegPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$QueryPath = dir $RegPath -Name
foreach($Name in $QueryPath)
{
(Get-ItemProperty -Path $RegPath$Name).DisplayName
}

4. Add system architecture detection to automatically determine registry redirection

Complete code can be referenced at the following address:

An open-source project

0x05 Supplement

---

Typically, installed programs create shortcuts, so attempting to enumerate shortcut files can also yield a complete program list

Get all shortcuts via wmic:

wmic PATH Win32_ShortcutFile get name /FORMAT:table

0x06 Summary

---

This article explains why WMI cannot obtain a complete list of installed programs on the current system, and demonstrates writing a PowerShell script to achieve a complete program list by enumerating registry entries. As an introductory article on basic knowledge, it aims to provide inspiration for newcomers.