Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 13

Guide to signing unsigned drivers

***UPDATE***

An updated (and more readable!) PART 1 tutorial can be found


here: http://www.alkanesolutions.co.uk/2013/10/23/a-guide-to-signing-un-signed-drivers/

An additional PART 2 tutorial (debugging a driver install) can be found


here: http://www.alkanesolutions.co.uk/2016/04/29/guide-signing-un-signed-drivers-part-2/

I thought I'd write this post to give something back to the community, as it took me ages to find out
for myself and get working so hopefully it will assist others. Some of the info in this post was
extracted from some great posts from AngelD, so kudos to him for that. It's only been tested in an
XP environment, but here goes...

Tools you need: (most are from the Windows Driver Kit):

Inf2Cat.exe (To generate the unsigned catalog file from our INF)

In the same folder as Inf2Cat.exe I have the following DLLs:

Microsoft.Whos.Shared.IO.Cabinets.dll

Microsoft.Whos.Shared.IO.Catalogs.dll

Microsoft.Whos.Shared.Xml.InfReader.dll
Microsoft.Whos.Winqual.Submissions.SubmissionBuilder.dll

Microsoft.Whos.Xml.NonXmlDataReader.dll

Makecert.exe (Used to create our certificate)

Cert2spc.exe (Create Software Publisher's Certificate (SPC) from our certificate)

Signcode.Exe (Sign our catalog file with an Authenticode digital signature)

Certmgr.exe (Used to add and delete our certificate to the system root)

DifxApp.msm (Difx Merge Module to install the driver)

**********************************************

*****INTRODUCTION******************************

**********************************************

Now we have our toolset in place, let's package the unsigned Captain Planet printer driver. We're
packaging this driver for a customer called 'Planeteers Ltd'.

Let's assume we've captured the Captain Planet printer driver using a snapshot tool. We can see
from the resultant snapshot that there is a file in [WindowsFolder]\inf called 'captainplanet.inf'. There
are also files called 'captainplanet.sys' and 'captainplanet.dll' in [SystemFolder]spool\drivers\w32x86.

All of these files make up the Captain Planet printer driver so let's create a folder anywhere on your
work machine

(say, "c:\cpdriver") and copy the three files to it.

We should now have our unsigned driver in a temporary folder called "C:\cpdriver" which contains:

captainplanet.inf

captainplanet.sys

captainplanet.dll

Now let's generate a customer certificate, so we can sign this (and many more) driver(s).

**********************************************

*****SIGNING THE DRIVER*************************

**********************************************
1. Create .cat (catalog) file for driver.

We notice that the Captain Planet driver doesn't contain a cat file, so we'll need to generate one.

Open the .INF file in a text editor. Ensure that under the [version] section that you have an entry
specifying a .cat file. If it's not there, add the line

at the end of the section. For example:

[version]

Signature=xxxxxx

Provider=xxxxxx

CatalogFile.NTx86=captainplanet.cat"captainplanet.cat" is the name of the cat file that we want to

generate. Not having a line specifying this will result in an "error 22.9.4 - Missing 32-bit catalog file
entry" when we run Inf2Cat.exe. "NTx86" represents the Windows 2000 x86-based platforms.

Command line:Inf2Cat.exe /driver:"" /os:XP_X86 Example: Inf2Cat.exe /driver:"C:\cpdriver"


/os:XP_X86

Running this successfully will generate captainplanet.cat in the 'C:\cpdriver' folder.

2. Create authenticode certificate and set private key


Create another folder called 'c:\PlaneteersLtd_certificate'. It is here where we'll create our customer-
specific certificate and private key. Remember that this certificate can be reused multiple times for
the customer (Planeteers Ltd) to sign different drivers, so keep naming conventions generic to your
customer.

Command line:MakeCert.Exe -r -pe -n CN= -sv -len 2048

Example: makecert.exe -r -pe "c:\PlaneteersLtd_certificate\PlaneteersLtd.cer" -n


CN="Planeteers Ltd" -sv "c:\PlaneteersLtd_certificate\PlaneteersLtd.pvk" -len 2048

Running this will ask you to set a private key. Make a note of this key! Running this command will
generate:

c:\PlaneteersLtd_certificate\PlaneteersLtd.cer and c:\PlaneteersLtd_certificate\PlaneteersLtd.pvk

(I think certificates of this kind are actually supposed to be used for development/testing as opposed
to a live environment. It's probably advisable to purchase a certificate from
Verisign/Comodo/whoever if you have the budget.)

3. Create Software Publisher's Certificate (SPC) from our certificate

Command Line:Cert2Spc.Exe Example: cert2spc.exe


"c:\PlaneteersLtd_certificate\PlaneteersLtd.cer"
"c:\PlaneteersLtd_certificate\PlaneteersLtd.spc"

This will generate c:\PlaneteersLtd_certificate\PlaneteersLtd.spc

4. Sign the catalog file

Command line:signcode.exe -spc -v -t http://timestamp.verisign.com/scripts/timstamp.dll

(Yes....I know it says 'timstamp.dll' but that is correct) This will prompt you for the private key you set
earlier. Enter it when prompted.

Example:SignCode.Exe -spc "c:\PlaneteersLtd_certificate\PlaneteersLtd.spc" -v


"c:\PlaneteersLtd_certificate\PlaneteersLtd.pvk" -

t http://timestamp.verisign.com/scripts/timstamp.dll "C:\cpdriver\captainplanet.cat"

**********************************************

*****ADDING THE CUSTOMER CERTIFICATE**********

**********************************************

The catalog for our driver is now signed. Every time we install this driver using DifxApp, we need to
ensure the customer certificate is installed on the machine before DifxApp installs the driver. To do
this, we use CertMgr.exe in two Custom Actions (CA) - one to add the certificate on install, and one
to remove it on uninstall. We can do this in two ways:
a) Create the two CAs in every single driver package you do

b) Create a merge module which can easily be incorporated in every driver package you do

In my opinion option b) would provide less hassle for me because after all, we want our certificate to
be easily re-usable for multiple driver packages. So for now, we'll do option b).

1. Create a new merge module and add captainplanet.cer to the SystemFolder of the MSM (or
wherever you deem appropriate)

2. Go to the Custom Action (CA) table and create 2 CAs, both are an 'Exe stored in binary
table' and 'Deferred in a System Context'.

If you use the CA wizard, you should stream 'certmgr.exe' into your binary table. Here's what
(roughly) your CustomAction table should look like after you've made them:

Name: addCertificate

Type: 3074

Source: certmgr

Target: -add "[SystemFolder]PlaneteersLtd.cer" -s -r localMachine ROOT


Name: removeCertificate

Type: 3074

Source: certmgr

Target: -del "[SystemFolder]PlaneteersLtd.cer" -s -r localMachine ROOT

And here is the Binary table:

Name: certmgr

Data:

Of course, using the wizard to do both CAs may result in two entries in your binary table containing
the same exe (certmgr.exe). Obviously this is a waste, so remove one of them and set the 'Source'
column in your CustomAction table appropriately.

3. Go to the ModuleInstallExecuteSequence table (Where is obviously empty/nothing, and not


the string literal "") and add the following:
Action: addCertificate

Sequence:

BaseAction: InstallFiles

After: 1

Condition: Not Installed

Action: removeCertificate

Sequence:

BaseAction: InstallInitialize

After: 1

Condition: REMOVE~="ALL"

Action: InstallFiles

Sequence: 4000

BaseAction:

After:

Condition:
Action: InstallInitialize

Sequence: 1500

BaseAction:

After:

Condition:

The sequencing above is important as the addCertificate CA needs to run after the certificate is put
down on the machine (after InstallFiles) and the removeCertificate CA needs to run before the
certificate is removed from the machine. It also needs to run before DifxApp installs the driver.

**********************************************

*****CREATE DRIVER PACKAGE********************

**********************************************

Great. At this point we should now have a signed driver, and a merge module which installs our
customer certificate. Now we can create the MSI package

which installs our signed driver:


1. Create a new ISM/WSI project and make a folder somewhere for your driver (one folder per
driver remember).

Let's say:

"[ProgramFilesFolder]CaptainPlanetDriver" for this example. This folder will contain all the files in
'c:\cpdriver' on our work machine:

captainplanet.inf

captainplanet.sys

captainplanet.dll

captainplanet.cat (the one we've just generated!)

Remember that all these files should be in the SAME COMPONENT as well as the same folder
(one .inf per folder), and the keypath of the component needs to be the .inf file!

Let's call the component: "CaptainPlanet_DRIVER"

2. Install the driver using DifxApp.

When we add the latest version of the DifxApp.msm merge module, it will create a table in the
project called "MsiDriverPackages". Installshield and Wise have slightly
different wizards to install a driver, so I'll just show you roughly how the MsiDriverPackages table
should be populated:

Component: CaptainPlanet_DRIVER

Flags: 7

Sequence: 1

ReferenceComponents:

Once this is done, compile your .MSI. Ensure in your .MSI that your 'addCertificate' CA runs after
'installFiles' and before 'MsiProcessDrivers' in the installExecuteSequence.

At last, we're done!

Now I'd highly recommend testing your MSI install with verbose logging enabled, as the DifX merge
module does write some half-decent logging which can assist you. For example, just recently
DifxApp verbose logging warned me that some DLLs (part of the driver) were not being copied to the
driver store. This was the reason why my driver wasn't working, and so I had to edit the .INF file
[SourceDisksFiles] section (Add the relevant files which weren't being copied to the driver store), re-
generate the cat file, re-sign it and then re-add these updated files to my MSI (Note there was
obviously no need to go fiddling with my MSM as the certificate remains the same).
It's also always best to test your driver with the appropriate hardware.

Anyway. I hope this guide can be of some help to others. If you break your machine, or yourself,
during implementing this guide then don't blame myself. It's only meant as a guide. Please feel free
to comment/correct/bug fix.

You might also like