Security Patches

mohdammed-ali-fWbNy_WTMoA-unsplash Photo by Mohdammed Ali on Unsplash

A patch is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. Wikipedia - Patch

Software patches are necessary to improve software over time. Whether a new feature is being provided or the latest security hole needs to be plugged, patching software is means to update binaries across most major distributions.

Table of Contents

Platform Security Updates

Every major platform has their own mechanism for distributing feature and security updates for their operating systems. These updates provide critical security fixes (or patches) necessary to protect systems and users. This section of the article will use the term updates and patches interchangeably.

The Windows path will be taken and specific focus given to the security patches related to a subset of the previously analyzed CVEs.

Windows Update Support Lifecycle

The complexity of managing software updates across the many versions of Windows is vast. There are several versions of the operating system to consider with varying lifecycle support expectations across each product. Lifecycle support can be taken to be the period for which Microsoft will support the product with security updates ( with the exception of the Extended Security Update Program).

A quick view of recent older Windows versions lifecycle suport:

ListingStart DateMainstream End DateExtended End Date
Windows XP12/31/200104/14/200904/08/2014
Windows 710/22/200901/13/201501/14/2020

And for Windows 10, which uses an auto-update channel with 2 major releases a year, the lifecycle support generally lasts between 18 and 20 months from the release date.

A recent look being:

VersionServicing optionAvailability dateOS buildLatest revision dateEnd of service: Home, Pro, Pro Education, Pro for Workstations and IoT CoreEnd of service: Enterprise, Education and IoT Enterprise
20H2Semi-Annual Channel2020-10-2019042.8042021-02-092022-05-102023-05-09
2004Semi-Annual Channel2020-05-2719041.8042021-02-092021-12-142021-12-14
1909Semi-Annual Channel2019-11-1218363.14112021-02-162021-05-112022-05-10
1809Semi-Annual Channel2019-03-2817763.17902021-02-16End of service2021-05-11
1809Semi-Annual Channel (Targeted)2018-11-1317763.17902021-02-16End of service2021-05-11
1803Semi-Annual Channel2018-07-1017134.20262021-02-09End of service2021-05-11
1803Semi-Annual Channel (Targeted)2018-04-3017134.20262021-02-09End of service2021-05-11

Windows Update Sources

Windows has three primary sources for obtaining updates. Updates can be automated for a workstation by using the default Microsoft Update or more fine grained controlled by corporate admins using Windows Server Update Services (WSUS). This article will focus on the only practical method to download specific patches based on CVE or timeframe. The ability to search for a specific patch is available using the Microsoft Update Catolog.

Types of Windows Updates

Windows updates come in all shapes and sizes. The goal for the Windows platform, or really any platform, is to have all of its users running fully patched machines.

Installing the most recent update means that you also get all the previous updates, including important security fixes.

Typically, updates will contain all the files necessary to fully patch the system being updated. These are called cumulative updates for Windows 10 and Monthly Rollups for Windows 7. Windows also issues security only to address specific critical vulnerabilities. For Patch-Diffing, the latter type might be best, as there is less noise to sort through. In fact, if a patch for a particular patch is available on Windows 7 (no matter the update type), you might consider using that for analysis instead. As Windows 7 is no longer officially supported, the exception being Extended Security Updates, the changes to binaries within the particular update typically only include security relevant updates.

Update Availability

From the history links are details about each of the updates. Based on lifecycle support and type of update, availability typically resembles this table.

Update Availability By Source:

Windows Update and Microsoft UpdateYesNoNone. This update will be downloaded and installed automatically from Windows Update.
Microsoft Update CatalogYesYesTo get the standalone package for this update, go to the Microsoft Update Catalog website.
Windows Server Update Services (WSUS)YesYesThis update will automatically sync with WSUS if you configure Products and Classifications as follows: Product: Windows 10, version 1903 and later Classification: Security Updates

So now we know different types of patches, how do we find the one we need for our particular CVE?

Finding the Haystack (Relevant Patches)

graph LR;

A[CVE] --> B[MSRC info page];
B --> C[KB article];
C --> D[MUC site];
D --> E[MSU archive]

An individual update (especially depending on whether or not it is security only or cumulative) will provide a large set of patched binaries. What is required though it to find the set of binaries (or haystack) relevant your particular CVE. For a particular CVE, the path to find the haystack is as follows.

From the references section the CVE details on MITRE’s page, follow the link link to Microsoft’s Security Response Center (MSRC). From the MSRC, a link to the appropriate Knowledge Base (KB) article can be found. The KB article will list a specific ID ( ie. KB4556799) than can finally be searched for in Microsoft Update Catalog (MUC). MUC will then provide a download link to a Microsoft Standalone Update (MSU) containing several update files for the corresponding update.

CVE-2020-1048 relevant patch

Here is a run through with links included for CVE-2020-1048.

  • CVE - Browse to the corresponding CVE listing.
    • Find link to corresponding MSRC
  • MSRC article
    • From here the KB number for the corresponding OS can be found:
      • Windows 7 for x64-based Systems Service Pack 1
        • Monthly Rollup - 4556836 -
        • Security Only - 4556843 -
      • Windows 10 Version 1903 for x64-based Systems
        • 4556799 -
    • Also of note is the date to help determine what is included in this patch relative to the current file system.
      • May 12, 2020
  • KB - article describing details of CVE and other patch requirements
    • Windows 7 for x64-based Systems Service Pack 1 - Monthly Rollup - 4556836 - - Security Only - 4556843 -
    • Windows 10 Version 1903 for x64-based Systems
      • 4556799 -
  • MSU - actual download from catalog

In the end, you want to collect and extract the relevant MSU file.

  • Windows 10 - windows10.0-kb4556799-x64_9de920d8738612baa81a751b003ff98f0ce7156b.msu
  • Windows 7
    • Security Only - windows6.1-kb4556843-x64_b98b5ff5cd7e9989df36db39bdb735e2e354b436.msu
    • Monthly Rollup - windows6.1-kb4556836-x64_81f1637b7d3bf105dcf88f3256be0119a3bb6cc4.msu

Extracting the patch

Now that we have the relevant patch archive (MSU), we need to take a look inside.


Expand the MSU file:

mkdir tmp
expand -F:* .\windows6.1-kb4556843-x64_b98b5ff5cd7e9989df36db39bdb735e2e354b436.msu .\tmp\
Microsoft (R) File Expansion Utility
Copyright (c) Microsoft Corporation. All rights reserved.

Adding .\tmp\ to Extraction Queue
Adding .\tmp\ to Extraction Queue
Adding .\tmp\Windows6.1-KB4556843-x64-pkgProperties.txt to Extraction Queue
Adding .\tmp\Windows6.1-KB4556843-x64.xml to Extraction Queue

Expanding Files ....

Expanding Files Complete ...
4 files total.

The MSU file contains 4 files with containing all the patched files. Another expand command is required:

expand -F:* .\tmp\ .\2020-05\
Adding .\2020-05\amd64_ntprint.inf_31bf3856ad364e35_6.1.7601.24553_none_9983b903ea91b16c\amd64\p6disp.gpd to Extraction Queue

Expanding Files ....
Progress: 86 out of 2921 files

The extracted patch files for the “security-only” update contains 2921 files. These updates can be quite large (the monthly rollup patch for May exceeds 23K files).

Patch extraction automation

In order to sort through the madness, there are several open source scripts that will help you make sense of all the files found within the MSU file. Following along from a recent blog post about extracting patches in 2020, this Patch Extract script will run through and recursively extract the binaries into a architecture relevant directory structure:

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2/22/2021   8:07 PM                JUNK
d-----         2/22/2021   8:06 PM                MSIL
d-----         2/22/2021   8:07 PM                PATCH
d-----         2/22/2021   8:06 PM                WOW64
d-----         2/22/2021   8:06 PM                x64
d-----         2/22/2021   8:06 PM                x86

From there it is much simpler to search for your relevant files and they are already sorted.

Finding the needle (Relevant Files)

Out of all the files, how do you know which files are relevant for your software component? Good question. If you are familiar with and understand the system, you likely know which binary to look at. If you are just starting off, well it’s part of the process. You’re going to have to dig in.

Try to answer some questions to lead in the right direction. Are you looking at a system binary? Where are they stored? Is it a service you are looking at? Where do services live? Using the Windows Print Spooler as an example, we know that it is a service and windows binary, so odds are that the code lives in C:\windows\System32. Assuming no knowledge of the system, it might be easiest to use a tool like Process Explorer or Process Hacker to understand which modules are loaded at runtime, which would point out which binaries contain the code we are seeking.

Finding the files you care about

Essentially, you want to build up an awareness of the code that makes up your software component. There are several ways to go about this.

Read the docs

Not all software comes with an instruction manual. Official documentation will not always be available. Luckily, for the Windows Print Spooler, there is quite a bit of information from Microsoft’s Developer Network (MSDN)

Simple Process Explorer/Hacker Technique

Not knowing anything about the Windows Print Spooler, you could use Process Explorer or Process Hacker to find more. As simple as typing “spool” or “print” in the search would find the Windows Print Spooler Process.


Grep Loaded Modules

Within Windows there is typically a single process (.exe) that acts as the container, loading several dynamic link libraries (.dlls) (modules) to add functionality. In trying to figure out which dlls the spooler is running, simply take a look at the loaded modules tab form within Process Hacker.

From the full list of modules, a subset could be filtered out using keywords like print or spool

PS C:\Users\dev> cat 'Process Hacker Spooler Modules List Windows'|findstr /i print
NameBase AddressSizeDescriptionFile NameVersionLoad Time
win32spl.dll.mui0x18e00004 kBClient Side Rendering Print ProviderC:\Windows\System32\en-US\win32spl.dll.mui10.0.19041.1 
inetpp.dll.mui0x18f00004 kBInternet Print Provider DLLC:\Windows\System32\en-US\inetpp.dll.mui10.0.19041.1 
FXSMON.dll0x7ff9bbea000068 kBMicrosoft Fax Print MonitorC:\Windows\System32\FXSMON.dll10.0.19041.8043:40:17 PM 2/26/2021
AppMon.dll0x7ff9bbec0000136 kBApp PrinterC:\Windows\System32\AppMon.dll10.0.19041.13:40:17 PM 2/26/2021
PrintIsolationProxy.dll0x7ff9bbef000076 kBPrint Sandbox COM Proxy StubC:\Windows\System32\PrintIsolationProxy.dll10.0.19041.13:40:17 PM 2/26/2021
usbmon.dll0x7ff9bbb10000944 kBStandard Dynamic Printing Port Monitor DLLC:\Windows\System32\usbmon.dll10.0.19041.7463:40:17 PM 2/26/2021
winprint.dll0x7ff9b89b000064 kBWindows Print Processor DLLC:\Windows\System32\spool\prtprocs\x64\winprint.dll10.0.19041.8043:40:19 PM 2/26/2021
win32spl.dll0x7ff9b88d0000884 kBClient Side Rendering Print ProviderC:\Windows\System32\win32spl.dll10.0.19041.7463:40:19 PM 2/26/2021
inetpp.dll0x7ff9b8890000204 kBInternet Print Provider DLLC:\Windows\System32\inetpp.dll10.0.19041.13:40:19 PM 2/26/2021
PS C:\Users\dev2> cat '.\Process Hacker Spooler Modules List Windows'|findstr /i spool
NameBase AddressSizeDescriptionFile NameVersionLoad Time
spoolsv.exe.mui0x9100004 kBSpooler SubSystem AppC:\Windows\System32\en-US\spoolsv.exe.mui10.0.19041.1 
localspl.dll.mui0x10f000080 kBLocal Spooler DLLC:\Windows\System32\en-US\localspl.dll.mui10.0.19041.1 
spoolsv.exe0x7ff740030000808 kBSpooler SubSystem AppC:\Windows\System32\spoolsv.exe10.0.19041.7463:40:14 PM 2/26/2021
spoolss.dll0x7ff9bbf40000116 kBSpooler SubSystem DLLC:\Windows\System32\spoolss.dll10.0.19041.13:40:17 PM 2/26/2021
localspl.dll0x7ff9bbf600001.24 MBLocal Spooler DLLC:\Windows\System32\localspl.dll10.0.19041.8043:40:17 PM 2/26/2021
winspool.drv0x7ff9bc0a0000568 kBWindows Spooler DriverC:\Windows\System32\winspool.drv10.0.19041.7463:40:17 PM 2/26/2021
winprint.dll0x7ff9b89b000064 kBWindows Print Processor DLLC:\Windows\System32\spool\prtprocs\x64\winprint.dll10.0.19041.8043:40:19 PM 2/26/2021

While this list may not be comprehensive, it provides a record of what code is currently loaded within the spooler process.

Search Process Memory

To dig a little deeper, you could search the memory (both the on-disk image memory and the process address space) for strings related to the spooler. image_private_mem_ph

Within the strings you can easily search using regular expressions: proces_hacker_mem_filter

Useful string filters for the spooler:

  • spool
  • print
  • spl
  • dll
$ cat image_private_spooler2.txt  | egrep "spool|print|spl|.dll" | cut -f3 -d " " | grep dll | egrep -v "printscan|ext|\\\\" | sort | uniq -c
      1 api-ms-onecoreuap-print-render-l1-1-0.dll
      1 FaxPrinterInstaller.dll
      1 LoadLibrary(ntprint.dll)
      7 localspl.dll
      1 LocalSpl.dll
      1 localspl.dll.mui
      1 nspoolss.dll
      3 ntprint.dll
      2 Print.ResourcesLib.dll
      1 Print.Workflow.Source.dll
      8 PrintConfig.dll
      1 PrintFilterPipelinePrxy.dll
      1 PrintIsolationProxy.dll
      3 PrintSandboxProxy.dll
      2 printui.dll
      1 rundll32.exe
      3 spoolss.dll
      5 tsprint.dll
      1 wifidisplay.dll
      7 win32spl.dll
      4 winprint.dll
      1 wsplib.dll
      1 xpsprint.dll

Relevant files for the Windows Print Spooler

We now have a list of potentially relevant Windows Printer Spooler binaries:

  • winprint.dll - Windows Print Processor DLL
  • winspool.drv - Windows Print Spooler Driver
  • localspl.dll - Local Spool DLL
  • spoolss.dll - Spooler Subsystem DLL
  • spoolsv.exe - Spooler Subsystem App
  • FXSMON.dll - Microsoft Fax Print Monitor
  • AppMon.dll - App Printer
  • PrintIsolationProxy.dll - Print Sandbox COM Proxy Stub
  • usbmon.dll - Standard Dynamic Printing Port Monitor DLL
  • winprint.dll - Windows Print Processor DLL
  • win32spl.dll - Client Side Rendering Print Provider
  • inetpp.dll - Internet Print Provider DLL

*Removed MUI files as they are language resources and not relevant code changes.

Next, we need to figure out which files are actually relevant.

Finding the binaries to compare

So at this point we have done our best to download the patch corresponding the the CVE being analyzed. We also have a good idea of the location of relevant code paths for the software component we are analyzing. Which helps us find out which needles (files) in the haystack (relevant patch) we need to pay attention to.

The last piece of our puzzle is to determine which versions of the binaries to to use for comparison in Patch-Diffing. In order to understand which code modifications were made relevant to a patch, the typical way to do that is to obtain the version relevant to your patch (see above). Then take the version of the binary just prior to the CVE patch of interest.


  • CVE of interest
    • Patch related to CVE
    • List of relevant code for software of interest


  • Version of binary or binaries released before the relevant CVE patch or the N-1 update.

Finding the N-1 Update

For a any Windows binary, the patch cycle could look like this:


    title Sample Binary Windows 10 1909 Patch Lifecycle 
    dateFormat  YYYY-MM-DD
    section Patch Lifecycle
    OEM Release  - 10.0.18362.1  :a1, 2019-10-12, 30d
    Security KB4524570 - 10.0.18362.476  :a2, after a1, 30d
    Cumulative KB4530684 - 10.0.18362.535 :a3, after a2, 30d
    Cumulative KB4528760 - 10.0.18362.592 :a4, after a3, 30d
    Fully Patched  - 10.0.18362.697 :a5, after a4, 30d

From that we essentially want to find the “CVE Relevant Patch” and the N-1 version of that binary. This is to meet the goal of reducing the complexity of analysis, by minimizing the changes that we need to look at.


    title Finding the N-1
    dateFormat  YYYY-MM-DD
    section Patch Lifecycle
    OEM Release  - 10.0.18362.1  :a1, 2019-10-12, 30d
    Security KB4524570 - 10.0.18362.476  :a2, after a1, 30d
	Cumulative KB4530684 - 10.0.18362.535 :a3, after a2, 30d
    Cumulative KB4528760 - 10.0.18362.592 :a4, after a3, 30d	
    Fully Patched  - 10.0.18362.697 :a5, after a4, 30d
	section CVE Relevant and N-1
	Cumulative KB4530684 - 10.0.18362.535 :active, a3, after a2, 30d
    CVE Relevant Patch - 10.0.18362.592 :crit, a4, after a3, 30d

For each relevant file we want to compare, we need to collect the patch corresponding to the CVE and the build before it. Each binary will be tagged with an OS Build version number. If the CVE Relevant Patches binary build number is 10.0.18362.535, your N-1 is the OS Build < 10.0.18362.535. Each cumulative update is inclusive and should include a copy of the binary our are seeking. The version number of the particular binary may not change across monthly cumulative patches, but will change if modifications were made to the binary.

Checking Binary OS Build Version Number

  1. Right-Click -> Properties
  2. Select Details tab
  3. See File Version

Finding the needles for CVE-2020-1048

The patch for CVE-2020-1048 was released in May 2020 as determined previously.
Download April 2020 (N-1) and May 2020 (CVE-2020-1048).

  • 2020-05 Security Monthly Quality Rollup for Windows Embedded Standard 7 for x64-based Systems (KB4556836) - windows6.1-kb4556836-x64_81f1637b7d3bf105dcf88f3256be0119a3bb6cc4.msu
  • 2020-04 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4550964) - windows6.1-kb4550964-x64_2a8ada96b48a57fd2d3a377c8635f420f237e71b.msu

Unpack the patches. Run a regular diff command to determine which files were updated.

Find only modified or new files:

diff -qr ~/Patches/win7April2020Monthly/x64 ~/Patches/win7May2020Monthly/x64 |cut -f4 -d' '

Full output: Modified-Patch-Files-for-Monthly-Rollup-May-2020-CVE-2020-1048

From the modified files, which ones match out relevant files list above?

Modified in May 2020 Monthly Rollup:

diff -qr ~/Patches/win7April2020Monthly/x64 ~/Patches/win7May2020Monthly/x64 | cut -f3-4 -d' ' | grep -v April | sed -r 's/: /\//g'  | xargs find {} | egrep 'winprint|winspool|localspl|spool|fxsmon|appmon|print|usbmon|winprint|win32spl|inetpp'

CVE-2020-1048 needles found:

  • localspl.dll - Local Spool DLL
  • winprint.dll - Windows Print Processor DLL

Windows 10 vs Windows 7 Cumulative patches

Windows 10 treats cumulative patches a bit differently than Windows 7. Instead of supplying the full binary in each cumulative patch release, a forward and reverse differential is provided. The r and f sub-directories indicate either a reverse or forward differential.

Generating a specific version

graph LR;

A[localspl.10.0.18362.693.dll] --Reverse Difff from 693--> B[localspl.10.0.18362.1.dll];
B --Forward Diff From 836--> C[localspl.10.0.18362.836.dll];

In order to obtain the binary matching a specific update patch level (when you want to create a specific version of the binary different than the one that exists already on your system), you can follow this process:

Starting with the current System32 binary (System32\localspl.dll) on your system at a specific version (say 10.0.18362.693), you can apply the reverse differential, leveraging Micrsoft’s Delta APIs , from the Windows 10 MSU Update (2020-04-Patches-1909/x64/p..ooler-core-localspl_10.0.18362.693/r/localspl.dll) to revert it back to version one (10.0.18362.1). From there, the forward differential can be applied to bring it back to the patch level specified by the MSU update (2020-05-Patches-1909/x64/p..ooler-core-localspl_10.0.18362.836/f/localspl.dll).

Further detail of the process is spelled out in this article for generating the correct binary from Extracting and Diffing Windows Patches in 2020 - wumb0in’.

Finding CVE-2020-1337 and CVE-2020-17001 Needles

A condensed version is listed here as the details are listed for the previous example. The Windows 7 \x64 monthly patches were used for analysis.


CVE-2020-1337 -> MSRC -> KB 4571719 –> MUC –> MSU file

  • 2020-08 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4571729) - windows6.1-kb4571729-x64_62b8672a50cebb4bfcd4fb16e18a39ab472a5269.msu
$ find 2020-08/x64/ | grep localspl


CVE-2020-17001 -> MSRC -> KB 4586827 –> MUC –> MSU file

  • 2020-11 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4586827) - windows6.1-kb4586827-x64\_e560961572fe8c0ba7533bd1e88e9614d86a966a.msu
$ find 2020-11/x64/ | grep localspl

Cheating - Skipping the Haystack and Finding the Needle Directly For Windows 10+ (2021 update)

In the process of writing these articles a new web site Winbindex was developed and released to the public that has been a godsend for patch diffing. If you know the binary you are looking for, and you are working with Windows 10 or higher, there is no better option to find and discover the specific version and update for your binary.

winbindex_localspl Results from localspl.dll query

Winbindex provides a database that keeps track of Windows binaries and their corresponding updates over time, even providing you the specific link needed to download the binary you need directly from Microsoft. This feature alone saves you quite a bit of time extracting gigabytes of Windows binaries to find the one binary you are looking for.

graph LR;

A[CVE] --> B[MSRC info page];
B --> C[KB article];
C --> D[Winbindex];
D --> G[Download binary from Microsoft];

More efficient process mapping CVE to a specific security update and eventual acquisition of binary to diff leveraging Winbindex

Even though it is limited to Windows 10+ binaries due to the technique used, in order to find obtain the binaries needed for Windows 10+, all I need to know are the KB numbers associated to the CVE and the binary name. The KBs can be searched for directly within the queried results.

Wrapping up


    title Relevant Win7 (6.1.7601) Monthly Patches for N-1,1048,1337,17001
    dateFormat  YYYY-MM-DD
	axisFormat %Y-%m
	section Monthly Cumulative Patches	
	KB4550964 :m1, 2020-04-14, 2020-05-11 
	KB4556836 :m2, 2020-05-12, 2020-06-08
	KB4561643 :done, m3, 2020-06-09, 2020-07-13
	KB4565524 :done, m4, 2020-07-14, 2020-08-10
	KB4571729 :m5, 2020-08-11, 2020-09-07
	KB4577051 :done, m6, 2020-09-08, 2020-10-12
	KB4580345 :done, m7, 2020-10-13, 2020-11-09
	KB4586827 :m8, 2020-11-10, 2020-12-07
	KB4592471 :done, m9, 2020-12-08, 2021-01-11
	KB4598279 :done, m10, 2021-01-12, 2021-02-08
	section Relevant CVEs
	N-1 :a1, 2020-04-14, 2020-05-11 
    CVE-2020-1048 :a2, 2020-05-12, 2020-06-08
	CVE-2020-1337 :a3, 2020-08-11, 2020-09-07
	CVE-2020-17001 :a4, 2020-11-10, 2020-12-07
    section localspl.dll versions
    24383  :l1, 2020-04-14, 2020-05-11 
    24554  :l2, 2020-05-12, 2020-06-08
	24559  :l3, 2020-08-11, 2020-09-07
	24562  :l4, 2020-11-10, 2020-12-07

Files needed for Patch Diffing

  • N-1 - localspl.dll (6.1.7601.24383)
  • CVE-2020-1048 - localspl.dll (6.1.7601.24554)
  • CVE-2020-1337 - localspl.dll (6.1.7601.24559)
  • CVE-2020-17001 - localspl.dll (6.1.7601.24562)

We will use these files for our patch diffing prep for the the Patch-Diffing-Applied section. Before we get there, let’s get some background on Patch-Diffing.

CVE North Stars Map

graph TD;

classDef current fill:#00cc66;

A1[N-1] --> |"localspl.dll (6.1.7601.24383)"| F;
A[CVE-2020-1048] --> |"localspl.dll (6.1.7601.24554)"| F;
B[CVE-2020-1337] --> |"localspl.dll (6.1.7601.24559)"| F;
C[CVE-2020-17001] --> |"localspl.dll (6.1.7601.24562)"| F;
F[Patch Diffing];

Next section: Patch-Diffing