Reverse Engineering Windows Printer Drivers (Part 1)

Note: This is Part 1 in a series of posts discussing security analysis of printer drivers extracted and installed from public resources. This part explains how we located publicly available drivers distributed by WeWork and conducted initial analysis. Part 2 come shortly after and will cover our exploration with in-depth technical details about how Windows kernel drivers work and the techniques we used to discover bugs in these drivers.

Almost every large organization uses printers, and while the printer market is fairly distributed, it is still heavily dominated by only a few players. Printers need kernel mode drivers to work so that they can communicate through USB and other means, though this is not always the case as modern operating systems are pivoting to user-mode drivers to ensure safety. A vulnerability in a kernel mode printer driver could result in Local Privilege Escalation (LPE) if exploited successfully.

In this two-part series, we’ll discuss the steps we took to analyze these drivers. We’ll also discuss some helpful background information for beginning analysis of Windows kernel-mode drivers.

Step 1. Find Driver Documentation or Public Resources

Since most of the public uses a search engine to find drivers, we will emulate the way a WeWork user would find print drivers so that we can also discuss the implications of using unofficial sources to find installers. The first step we took was to search for documentation and driver downloads in the same way as a user. The drivers found will be used in our analysis. 

What printers does WeWork use?

A quick online search provides these links: 

According to the setup documents, WeWork uses HP, Kyocera and Konica printers. Though this instructional manual seems to be from a non-official source, an attempt to run these installers will be unsuccessful as they expect to be connected to a printer. A search through WeWork’s publicly available documentation shows that for Russian and Chinese WeWork spaces, only the WeWork_HP_installer.exe is documented. It seems that either the other printers are much rarer, or WeWork does not publish documentation publicly.

Step 2. Unpacking Resources

Unpacking Windows Resources

With a bit of web crawling for “WeWork_Installer_HP.exe”, the HP installer executable can be found at

Since this executable contains no digital signature, its origin from WeWork cannot be verified. VirusTotal shows that it is not flagged by any antivirus engines, but they advise to continue on a virtual machine (VM).

The installer does not display a prompt to select where files are stored similar to most common software installers, but we used ProcMon to identify where files are placed on the local machine. Typically, you would first check C:\Program Files or C:\Program Files (x86) for changes. In this analysis, a folder named WeWork_printer_drivers was found in C:\Program Files (x86), which contained two executable files: HP_UPD.exe and win_39754.exe. The files have the following icons displayed in Windows Explorer:

These executables are self-extracting 7-Zip executables and can be opened with the 7-Zip application.

Opening win_39754.exe shows some references to a printer client software known as Papercut, but this does not contain any driver.

Opening HP_UPD.exe (which presumably stands for HP Universal Printer Driver), points to a file directory that contains .inf files for these printers and their properties. See the following documentation for more information on .inf files:

Exploring the files further, there are directories with the name drivers, with each directory containing a subdirectory named either WINXP, WIN2000, AMD64. These directories contain drivers. Out of the directory names, AMD64 is the one most modern architecture for modern day windows operating systems.

Extracting the drivers in this folder, there are 5 drivers:

  • HPZid412.sys
  • HPZisc12.sys
  • HPZipr12.sys
  • HPZius12.sys
  • HPZs2k12.sys

These files all have additional information about them in their properties. Their properties can be viewed by right-clicking on them and selecting Properties->Details, where their descriptions and their original file names are shown.

They seem to be used for implementing the DOT4 (IEEE 1284.4) multiplexing data channel protocol over USB. In fact, the original filenames are references to Microsoft default DOT4 protocol drivers, and the strings of the original Dot4 Microsoft drivers are extremely similar to the HP drivers, almost exact. For more confirmation, BinDiff could be used to check the similarity of the two binaries. 

Unpacking MacOS resources

After an attempt to find the package described in the public facing documents, we settled with the file in the MacOSPrinterSetup instructions, which provides a DMG file.

Opening the DMG file in 7-Zip presents the following directory structure:

Immediately, the most interesting place to find drivers would be the .pkg file that contains the packages which contain binaries. Opening in 7-Zip provides folders:

From the above list of files, the most relevant to kernel drivers would be a KEXT (Kernel Extension), and it seems there is only one relevant package with kext in its name: Opening it in 7-Zip results in the files below:

The directory contains these files, the most important of which is the Payload file which contains the actual binaries. We can open this file in 7-Zip and it contains numerous empty path folders which just hold other folders. KEXTs are folders that contain plists (files that describe the KEXT) and the MACH-O binaries. The path to the KEXT in the Payload file is shown below:


This is the path inside the payload to the KEXT contents folder. It provides the directory structure below:

CodeSignature is a directory of signatures for verifying the file. The Info.plist file describes the properties of the KEXT and Version.plist contains version numbers, but where is the binary?

As it turns out, this KEXT is a Codeless Kernel Extension, which can be verified by looking in the Info.plist file containing properties in an XML format. Specifically, KEXTs with binaries contain the CFBundleExecutable property. Inspecting the Info.plist of this KEXT, we find no CFBundleExecutable property.

The purpose of this KEXT is to point the operating system to the subsystems which this hardware device (the printer) uses, and direct it to the NON-KERNEL driver responsible for handling the hardware (IOKit). The XML keys responsible for telling us which pkg is responsible for handling this printer is the USB Printing Class

        <key>USB Printing Class</key>

In the string above, we see a path to a user mode plugin. A word in this path provides a clue into which package contains this plugin. HPDeviceModel, the process used to inspect this plugin, can also be used for the IOKit user mode driver (com.hp.DeviceModel4.pkg / HPIOPrinterClassDriver.plugin). 

Note: Unpacking these macOS driver packages confirms that these drivers are user-mode drivers and not kernel-mode drivers. We did not pursue further analysis on the macOS drivers as the value from attacking them is far less than kernel-mode drivers.

Step 3. Confirmation 

Note: For this step, we will use Windows as it is the only one with Kernel Drivers.

With our research, we now know that the HP drivers are the Dot4 default drivers. This theory can be tested by connecting a printer that supports Dot4 to your computer via USB,and then using a tool like WinObjEx64, which can inspect loaded drivers. 

Browsing the loaded drivers shows:

From the image above, you can confirm that three drivers are loaded: dot4, Dot4Print and dot4usb. The loaded drivers indicate that the operating system is ready to interact with the printer. Despite the fact that there were 5 drivers, it seems (from analysis) that only three drivers are loaded on modern systems. The three files unpacked are: 

  • dot4.sys -> HPZid412.sys
  • dot4prt.sys -> HPZipr12.sys
  • dot4usb.sys -> HPZius12.sys

The binaries for these default dot4 drivers can be found at C:\Windows\System32\Drivers once they have been loaded for the first time.

Devices listed on the system are show in the image below:

While drivers show that the operating system is ready to interact with the printer, it is ultimately up to a user-mode application to initiate a printing sequence. The application can initiate a printing sequence if the drivers present an interactable device to the user-mode application. In the image above, a dot4 device that allows for interaction between user-mode and the driver exists on the system.

Step 4. Architecture and Research

The Windows operating system is massive. It hosts a variety of subsystems, so we focused our research on Windows during analysis. For this research, the goal was to study the different types of drivers and how they affect security. 

Types of Windows Drivers

It’s important to understand that there are several types of Windows drivers and frameworks: 

WDM – The first type of drivers that were created were WDM (Windows Driver Models). This driver is a raw driver and manages resources and devices. When it came to device drivers this seemed to be almost an impossible task due to the endless amount of state that had to be managed, this issue is discussed in depth in old Microsoft archives that can be found here.

KMDF – The Kernel Mode Driver Framework (KMDF) was invented to relieve some of the difficulties developing device drivers, giving developers APIs that would handle edge cases. It implements state machines for PnP, I/O, and others.

UMDF – The User Mode Driver Framework (UMDF) is the user-mode equivalent of KMDF.

WDF – The Windows Driver Framework (WDF) is a term that encompasses KMDF and UMDF.


For this first post in our WeWork printer analysis series, we found resources online and unpacked them. The analysis covered in this post is the initial step in identifying WeWork printer drivers so that we can research further into their security. In the next post, we will look into reverse engineering and attempting to discover exploitable bugs in these drivers. 

Leave a Reply