Windows is the most popular consumer operating system for laptops and desktops. It is created by Microsoft, and has been developed since DOS (August 12, 1981). The OS itself is proprietary, meaning the source code is not available to the end-user. Likewise Windows departs massively from Unix & Linux based systems, both in design and philosophies.
Windows-Specific Features
Many of the underlying mechanisms for managing the operating system are specific to windows. In linux basically everything is a file in some way or form. Windows however often has specific tools that you can have limited interaction with, which serve the same purposes that the file-based mechanisms serve.
How are programs loaded when you specify them in the terminal? A custom mechanism that’s windows specific. How do processes communicate with one another? In an underlying mechanism you have limited exposure to. For all these mechanisms they are specifically built to handle the task they’re built for.
The registry
The easiest way to imagine the registry is one of two models:
- The registry is a set of folders and files that hold configuration for the system
- The registry is a database that allows for communication across the operating system, and should be viewed as an “up to date” representation of the device
Both mental models work in most cases, but the second is more accurate. In later content I will refer to these as model 1 and model 2 respectively. The registry in plain terms contains a bunch of data that the system uses to operate. Things like what the current volume should be, the current display brightness, the user’s name, preferences etc. are all part of the registry. It is essentially a system that helps manage the creation, updating, and removal of important pieces of data. You can actually look at the registry using regedit.exe
. The layout looks like this:
Warning
regedit.exe
and modifying the registry in general can completely break your windows installation. Please be careful when doing anything with the registry
The registry has a somewhat complex terminology used to describe it. The layout is essentially:
Hive
├── keys
│ └── values
│ ├── type
│ └── data
└── keys
└── Subkeys
└── values
├── type
└── data
Hives
A hive can be thought of as either:
- A Drive, which then has other folders and files inside
- A database table, with various columns and rows inside
Essentially it is the top-level, where the actual data is stored under. Windows has a limited number of these hives currently, and each serves a specific purpose. Each hive will be prefixed with HKEY_
, and the current one’s are:
HKEY_CURRENT_USER
(HKCU
): Stores values that are specific to the currently logged in user. For exampleHKEY_CURRENT_USER\Software
is often used to define values that applications rely onHKEY_LOCAL_MACHINE
(HKLM
): Stores values specific to the local computer. For exampleHKEY_LOCAL_MACHINE\HARDWARE
contains information about the BIOS and devices that are connected.HKEY_USERS
(HKU
): Contains information about all users on the system. For example Minecraft uses a value in here to specify where to run java from:HKEY_CURRENT_CONFIG
(HKCC
): A shortcut toHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\
HKEY_CLASSES_ROOT
(HKCR
): Stores information about file extension associations. This essentially allows you to specify what programs to open based on a specific extension. For example you might specify in here that.html
files should open withC:\\chrome.exe
(though this actually usesProgID
,CLSID
, andIID
like COM Objects)
Keys & Subkeys
A Key can be thought of as either:
- A folder, which can then contain other folders (subkeys) and/or files (values)
- A column in a database, which then can contain rows (values), or foreign keys to other columns (subkeys)
Keys and subkeys are essentially containers for Values, many of them have their own semantic meaning based on where they are in the registry.
Values
A value can be thought of as either:
- A file
- A row in a database
Values are what actually hold the data. Much like files, and rows, values each have a type
, and then the actual data
. The current types are1:
Constant | Description |
---|---|
REG_BINARY | Binary data in any form. |
REG_DWORD | 32-bit number. |
REG_QWORD | 64-bit number. |
REG_DWORD_LITTLE_ENDIAN | 32-bit number in little-endian format. This is equivalent to REG_DWORD. In little-endian format, a multibyte value is stored in memory from the lowest byte (the “little end”) to the highest byte. For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-endian format. |
REG_QWORD_LITTLE_ENDIAN | A 64-bit number in little-endian format. This is equivalent to REG_QWORD. |
REG_DWORD_BIG_ENDIAN | 32-bit number in big-endian format. In big-endian format, a multibyte value is stored in memory from the highest byte (the “big end”) to the lowest byte. For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-endian format. |
REG_EXPAND_SZ | Null-terminated string that contains unexpanded references to environment variables (for example, “%PATH%”). It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions. |
REG_LINK | Unicode symbolic link. |
REG_MULTI_SZ | Array of null-terminated strings that are terminated by two null characters. |
REG_NONE | No defined value type. |
REG_RESOURCE_LIST | Device-driver resource list. |
REG_SZ | Null-terminated string. It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions. |
COM Objects
COM Objects are a Microsoft-designed standard for creating re-usable objects (components) 2 3. Specifically a COM Object is an object provided by an API which implements some of the COM Standard Interfaces 4. COM objects run inside a COM server, this must be a DLL or executable 5. Despite it’s name a COM server most often is an in-process communication server, meaning it doesn’t use network connectivity, but primarily operates locally through a direct data binding.
How Common are they?
The easiest way to find all the COM objects available on your system is to use the tool provided in the windows SDK called oleview.exe
6. Generally this is a large number of items, for example in Windows 10 x64 , 1909 there are7:
- 8300+ COM Objects
- 27000+ Interfaces
- 7500+ Are In-process Servers (DLLs)
- 810+ Are Out-of-Process Servers (EXE)
What are they really
The information from this section primarily comes from Demystifying Windows Component Object Model (COM) | 0xShukruN (221bluestreet.com)
Specifically COM objects are all classes that inherit from IUnknown in their inheritence chain8. From there they have a few pieces of important metadata:
- CLSID - Class ID, Is globally unique identifier (GUID) that Identifies a COM Class. For example, the Windows Script Host Class which has CLSID - {72C24DD5-D70A-438B-8A42-98424B88AFB8}
- ProgID - Program ID, A friendly name for a COM Class which can be used in a similar manner as CLSID, For example, the Windows Script Host Class can be called in powershell by it’s ProgID, which is Wscript.Shell (example code at the end)
- AppID - Application ID, globally unique identifier (GUID) that identifies a registry key that contains various configuration for an individual or a group of COM classes
- IID - Interface ID Is globally unique identifier (GUID) that Identifies a COM Interface, For example, IWshShell Interface which has the IID of - {F935DC21-1CF0-11d0-ADB9-00C04FD58A0B}
There is additional metadata found in the registry including where the binary/DLL for the class is located. This is important in particular for network implementations of COM objects because they need to know where to instantiate the objects from.
You can create instances of a COM object via powershell using the CLSID or ProgID (you can specify a second argument to get an object over DCOM):
# Create Instance from CLSID
[System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("56FDF344-FD6D-11d0-958A-006097C9A090"))
# Over DCOM
[System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("49B2791A-B1AE-4C90-9B8E-E860BA07F889", "10.10.0.1"))
# Create Instance from Prog ID
[System.Activator]::CreateInstance([Type]::GetTypeFromProgID("Wscript.Shell")
# Shorter version of creating an instance from Prog ID
$WScriptShell = New-Object -ComObject WScript.Shell
in .Net you can use CoCreateInstance for local COM and CoCreateInstanceEx for remote instances
SCM (the Windows Service Manager) is what handles much of the registry communication, as well as local COM servers. COM servers can operate in a few different “activation modes” (how they’re registered in the registry):
-
In-Process (InprocServer32) - The vast majority of native COM servers are activated In-Process which means that the COM server is a DLL file that will be loaded into the client process that instantiated the COM Object, In this activation method, the SCM returns the file path of the DLL that contains the object server implementation. The COM Library loads the DLL and queries it for its class factory interface pointer.
-
Out-of-Process / Local - (LocalServer32) When a COM object is configured as a Local Server it means that the server is an EXE file which will be executed as a different process than the Client that instantiated the COM Object, the SCM starts the local executable which registers a class factory on startup, and its interface pointer is available to the system and clients.
-
Out-of-Process / Remote - The remote aspect here refers to DCOM which is distributed COM, for now, think of it as COM over the network (DCE-RPC). It is the act of activating or accessing a COM object on a remote machine, The local SCM acquires a class factory interface pointer from the SCM that is running on a remote computer.
Examples
A ton of examples can be found in the gist scripts.
Wscript
Wscript is a COM object that allows you to run code. It will allow you to do things like start processes9, create shortcuts10 and many more. It was also the system that allowed you to write VBScript, which has since been deprecated11.
Creating a shortcut in powershell using wscript
:
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $TargetFile
$Shortcut.Save()
Running a file explorer using wscript
and validating it ran properly:
$WScriptShell = New-Object -ComObject WScript.Shell
$q = $WScriptShell.Run("explorer")
$q # Returns 0 if it ran correctly
OLE/Compound Documents
Compound documents is a Microsoft standard for enabling robust cross-document embedding12. The easiest way to think about this is that it’s similar to the idea of an iframe. It does this through uniform data transfer, which is another interface which allows one document to essentially hook into the COM object that allows running the embedded data interactively (called In-place activation).
Example with excel
This example counts the number of used rows and columns in the document (Source, also has other languages):
def read_data_from_excel(filepath:str):
Excel = Sys.OleObject["Excel.Application"]
Excel.Workbooks.Open(filepath)
RowCount = Excel.ActiveSheet.UsedRange.Rows.Count
ColumnCount = Excel.ActiveSheet.UsedRange.Columns.Count
for i in range(1, RowCount + 1):
s = "";
for j in range(1, ColumnCount + 1):
s = s + VarToString(Excel.Cells.Item[i, j]) + '\r\n'
Log.Message("Row: " + VarToString(i), s);
Excel.Quit();
DCOM
I’ve mentioned DCOM a few times, but didn’t explain it. DCOM is the standard for communicating with COM objects across a network 13. It has been succeeded by winrm, but some standards still use DCOM.
As an extension of COM, DCOM solves a few inherent problems with the COM model to better use over a network14:
- Marshalling: Marshalling solves a need to pass data from one COM object instance to another on a different computer – in programming terms, this is called “passing arguments.” For example, if I wanted Zaphod’s last name, I would call the COM Object LastName with the argument of Zaphod. The LastName function would use a Remote Procedure Call (RPC) to ask the other COM object on the target server for the return value for LastName(Zaphod), and then it would send the answer – Beeblebrox – back to the first COM object.
- Distributed Garbage Collection: Designed to scale DCOM in order to support high volume internet traffic, Distributed Garbage Collection also addresses a way to destroy and reclaim completed or abandoned DCOM objects to avoid blowing up the memory on webservers. In turn, it communicates with the other servers in the transaction chain to let them know they can get rid of the objects related to a transaction.
- Using DCE/RPC as the underlying RPC mechanism: To achieve the previous items and to attempt to scale to support high volume web traffic, Microsoft implemented DCE/RPC as the underlying technology for DCOM – which is where the D in DCOM came from.
# the computer name or IP address you want to connect to:
$computer = '192.168.2.109'
# use a user account that has Administrator permissions on
# the target computer:
$credential = Get-Credential
# try and retrieve BIOS information:
Get-WmiObject -Class Win32_BIOS -ComputerName $computer -Credential $credential
Resources
- Registry
- COM
- 4 The Component Object Model (utah.edu)
- Hunting COM Objects | Mandiant
- COM: Component Object Model Technologies (archive.org)
- GitHub - microsoft/component-object-model-sample: Sample code for Component Object Model (COM) setup and registration.
- Component Object Model (COM) - Win32 apps | Microsoft Learn
- COM Technical Overview - Win32 apps | Microsoft Learn
- [MS-OPENSPECLP]: Open Specifications | Microsoft Learn
- Dancing with COM - Deep dive into understanding Component Object Model (youtube.com)
- Microsoft Component Object Model (COM): A Technical Overview of COM (umd.edu)
- Demystifying Windows Component Object Model (COM) | 0xShukruN (221bluestreet.com)
- Component Object Model (COM) API - Win32 apps | Microsoft Learn
- 4 The Component Object Model (utah.edu)
- GitHub - microsoft/component-object-model-sample: Sample code for Component Object Model (COM) setup and registration.
- Component Object Model (COM) - Win32 apps | Microsoft Learn
- COM Technical Overview - Win32 apps | Microsoft Learn
- [MS-OPENSPECLP]: Open Specifications | Microsoft Learn
- youtube.com/watch?v=8tjrFm2K30Q- IUnknown - Wikipedia
- Microsoft COM Specification (archive.org)
- Using and Implementing IUnknown - Win32 apps | Microsoft Learn
- IUnknown - Win32 apps | Microsoft Learn
- IUnknown::QueryInterface(REFIID,void) - Win32 apps | Microsoft Learn
- c++ - What is COM (Component Object Model) in a nutshell? - Stack Overflow
- 221bluestreet.com/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com
- GitHub - sahar55/windows-com-objects: A Database of COM objects and their configuration across multiple windows builds
- Introduction to COM - What It Is and How to Use It. - CodeProject
- c++ - What is COM (Component Object Model) in a nutshell? - Stack Overflow
- sciencedirect.com/topics/computer-science/component-object
- Microsoft Component Object Model (COM): A Technical Overview of COM (umd.edu)
- Automating Windows Applications Using COM - Practical Business Python (pbpython.com)
- Python bindings
- James Forshaw who created OLEView
- wscript
- Script Runtime | Microsoft Learn
- Scripting | Microsoft Learn
- wscript | Microsoft Learn
- wscript - VBScript - SS64.com
- wscript.Shell + Shell.Application - VBScript - SS64.com
- Shell object (Shldisp.h) - Win32 apps | Microsoft Learn
- Windows Script Host: Scripting; Management Services | Microsoft Learn
- Run Windows Script Host samples: Scripting; Management Services | Microsoft Learn
- Objects (Windows Script Host) | Microsoft Learn
- OLE
- Compound Documents - Win32 apps | Microsoft Learn
- [Microsoft Compound File Binary File Format, Version 3 (loc.gov)](https://www.loc.gov/preservation/digital/formats/fdd/fdd000380.shtml#:~:text=Microsoft%20Compound%20File%20Binary%20(CFB,storage%20objects%20and%20stream%20objects.)
- In-Process Servers - Win32 apps | Microsoft Learn
- Linked Objects and Monikers - Win32 apps | Microsoft Learn
- Containers: Compound Files | Microsoft Learn
- Format(s)
- Excel Specification
- DCOM
- pywin32/com/win32com/test/testDCOM.py at main · mhammond/pywin32 (github.com)
- Connecting OPC Servers Using Python | by Burger Wu | Medium
- What is Distributed Component Object Model (DCOM)? (techtarget.com)
- What is DCOM (Distributed Component Object Model)? (varonis.com)
- [MS-DCOM]: Distributed Component Object Model (DCOM) Remote Protocol | Microsoft Learn
Footnotes
-
Registry Data Types (Winnt.h) - Win32 apps | Microsoft Learn ↩
-
https://learn.microsoft.com/en-us/windows/win32/com/component-object-model—com—portal#:~:text=Purpose-,COM%20is%20a%20platform%2Dindependent%2C%20distributed%2C%20object%2Doriented%20system%20for%20creating%20binary%20software%20components%20that%20can%20interact.%20COM%20is%20the%20foundation%20technology%20for%20Microsoft%27s%20OLE%20(compound%20documents)%20and%20ActiveX%20(Internet%2Denabled%20components)%20technologies.,-Where%20applicable ↩
-
https://stackoverflow.com/questions/455687/what-is-com-component-object-model-in-a-nutshell ↩
-
Component Object Model (COM) - Win32 apps | Microsoft Learn ↩
-
https://www.uio.no/studier/emner/matnat/ifi/INF5040/h07/gruppemateriale/studpres/Group%204-.NET.pdf ↩
-
https://learn.microsoft.com/en-us/windows/win32/com/ole-com-object-viewer ↩
-
https://www.221bluestreet.com/offensive-security/windows-components-object-model/demystifying-windows-component-object-model-com#:~:text=Windows%2010%20x64,Process%20Servers%20(EXE) ↩
-
https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown#:~:text=All%20other%20COM%20interfaces%20are%20inherited%2C%20directly%20or%20indirectly%2C%20from%20IUnknown ↩
-
https://learn.microsoft.com/en-us/troubleshoot/windows-client/admin-development/create-desktop-shortcut-with-wsh ↩
-
https://learn.microsoft.com/en-us/windows/whats-new/deprecated-features-resources#vbscript ↩
-
https://learn.microsoft.com/en-us/windows/win32/com/compound-documents ↩
-
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiy6Jm2g8yFAxUUFlkFHSDcDW8QFnoECAkQAQ&url=https%3A%2F%2Fwinprotocoldoc.blob.core.windows.net%2Fproductionwindowsarchives%2FMS-DCOM%2F%255BMS-DCOM%255D.pdf&usg=AOvVaw2B6bWwFpAPfrXTuLgAshHl&opi=89978449 ↩
-
https://www.varonis.com/blog/dcom-distributed-component-object-model ↩