Can I remove a digital signature from a DLL? - winapi

My installer build "signs" a DLL using a Code Signing certificate during the build process.
I've noticed that if I try to build twice in succession, the second build fails because the DLL is already signed so signcode chokes. Obviously I can fix this by signing a copy of the DLL in the build, but the problem intrigued me:
Is it possible to "unsign" a DLL, and if not, why not...?

signtool remove /s C:\path\to.exe.or.dll
signtool is available in Windows SDK, and must be at least from Windows 8 SDK kit (version 6.2.9200.20789) to have the remove command supported.

You can use delcert.exe from the this XDA Forum post.
here is a small tool that strips (removes) digital sign (Authenticode)
from PE executable files like *.exe, *.dll, *.mui, etc.

It's fairly easy to remove the signature from a .dll file using the ImageRemoveCertificate API.
You don't have any language specified in your tags but this article shows how to implement it in C#. Remove digital signature from a file using C#
Other than that, if you are looking for a simple tool to do the work for you, you can use FileUnsigner.

Another possible option is to switch to the SignTool.exe. It comes with the Windows SDK and signing a binary that has already been signed does not generate an error. I use signtool.exe in my build process and haven't any difficulties with it, even when something is already signed.
Also, check out the question What's the main difference between signcode.exe and signtool.exe?

Sure it's possible, but not trivial.
Although it would be easier to save a copy of the presigned DLL.
This digital signature is little more than an extra section appended to the end of a PE file. You could write a program that deleted the signature, if you want.
It's not quite as simple as truncating the file; you have to remove references to the signature in the file header. It could get complicated if the DLL has multiple signatures and you just want to remove one.
The format of a PE file is publicly documented here

Check if your build tool supports "Re-signing". This should replace all existing signatures.
If not, you can use Stud_PE to remove the signature block.
Open the DLL or EXE in Stud_PE, go to the sections tab, right click the digital signature section and select "Delete section". However, this needs user interaction. Old versions of the tool could destroy the file.

Related

Replace PE in embedded icon image, without re-signing the file all over again

Is there any option to set new icon for a signed PE executable in windows without re-signing it all over again?
This means that the icon image, although fully embedded into the PE file, won't change the hash value as it's appears in the file signature part.
perhaps there's a concept where one can sign only the code and data section of the file and avoid other parts ? or maybe there's an option to exclude unwanted parts from the signature cover ?
Maybe it's possible to place the icon somehow inside the certificate section itself which is created by SignTool, so that it would be excluded from signing?
thanks
No, the signTool provided by microsoft that is used to sign binary files is not able to partially sign files. And it wouldn't make much sense to sign a binary if anyone could just change the embedded resources - the application code might rely on the data in those resources. So if the resource's integrity is not covered by the signature, the executable code would also be untrusted, thus defeating the purpose of the signature.
A solution would be to externalize the resources, so it's not part of the signature. It just might be possible by specifying an external path to the icon in the application's manifest file - but I'm not sure.

What is the structure of AppxSignature.p7x?

Universal Windows apps are in .appx file, which is simply a zip of a bunch of files and metadata. Most of the metadata files are extensively documented on the Microsoft website and are trivial to parse and/or regenerate. However AppxSignature.p7x remains a mystery.
From this diagram (source):
AppxSignature.p7x should have hashes of the AppxBlockMap.xml, content & directory hashes, and a signature. However I cannot find any documentation of the AppxSignature.p7x file itself. Ideally I would like to use an alternative tool to produce and verify this signature, e.g. openssl/gnutls or similar. A practical use for this is to update and repackage apps on Linux, and prepare .appxupload file for the Windows Store.
As described in the blog post you link to, the AppxBlockMap.xml file stores cryptographic block hashes for every file in the package. This file is verified and secured with a digital signature when the package is signed using authenticode.
So, on windows, you have two tools:
MakeAppx.exe that creates the package (.zip format) and the blockmap file at the same time. This is important, as what's in the block map corresponds closely to the .zip file bits, you can't just any zipping tool for this step, you must program the zip/app package creation using some ZIP API.
SignTool.exe that adds the signature to the package using "standard" authenticode.
With the Windows API you can do the same as MakeAppx using the
Packaging API and you can do the same as SignTool using The SignerSign function.
The whole MakeAppx process is not documented IMHO, but the blockmap schema is in fact described here: Package block map schema reference which is relatively easy to understand.
The Authenticode signature for PE document is documented here: Windows Authenticode Portable Executable Signature Format
But it's only for PE (.dll, .exe, etc.) files (note it's also possible to sign .CAB files), and I don't think how SignerSign builds AppxSignature.p7x is documented. However, there is an open source tool here that does it here: https://github.com/facebook/fb-util-for-appx. You will notice this file https://github.com/facebook/fb-util-for-appx/blob/master/PrivateHeaders/APPX/Sign.h that declares what should be used as input for signing. I have no idea where they got that information.
The P7X format is just 0x504B4358 ("PKCX") followed by PKCS #7 data in the DER format. DER is described by ASN.1.

How to view and/or edit the manifest of a Setup.exe file

This question might seem to be duplicated with this and this that are similar. But it is not! First- I am getting this error from the setup file and not from the program that I am distributing Second -the version is different, the directories in Installshield 2009 an 10.5 differ. .
I'm trying to fix an error caused by Windows compatibility mode in my setup, which is built with Installshield 10.5. So far my research led me to a conclusion that i need to add [this][3] to my manifest file. I saw that Microsoft's tool mt.exe could extract a manifest file from a dll, however I did not see anywhere that it can extract it from an executable file.
So my questions are the following:
Is there any way to view the manifest file of a Setup.exe built with Installshield?
Is there any way to configure this manifest file for the certain project in Installshield?
[3]Can one edit an InstallShield setup.exe's manifest file?
As far as I know, mt.exe will work fine on EXE files; both EXE and DLL files are Portable Executable (PE) files, and PE files use the exact same structure for resources such as the manifest. Visual Studio, CFF explorer, and countless other tools (including raw resource APIs) will also work to view and possibly update manifests in general.
However for a built InstallShield setup.exe, there is a twist. InstallShield uses areas in the file to store information that are not described in the PE format. Tools that update the resources on an EXE can inadvertently destroy this data as they do not expect it to be there, nor do they know how to detect or adjust it.
InstallShield 12 or so and later allow you to specify a manifest, and it selects the manifest from files it ships that you can update before it adds them to the setup.exe. In addition, there is a tool called ISReMan that is aware of the extra information and can update the manifest correctly when that data is present.
By the way, it's generally helpful to mention the actual problem you're trying to solve, in case the method you've chosen (in this case updating the manifest) is not the correct solution. Note as well that InstallShield 10.5 is over 10 years old, and knows nothing about UAC, PCA, and other Vista and later technologies; adjusting the manifest may not help fix, say, an elevation-related problem.
Note as well that I am paid to work on InstallShield, so I may be biased when I recommend things like upgrading. :)

How can I profile Signed Assemblies with VS 2010 or VS 2013

I have a website that uses AjaxControlToolkit.dll and Log4Net.dll.
When I try to run the performance profiling tool in VS 2010 on it it gives me the following warning:
AjaxControlToolkit.dll is signed and instrumenting it will invalidate its signature. If you proceed without a post-instrument event to re-sign the binary it may not load correctly.
Now, if I choose the option to continue without re-signing, the profiling starts but the assembly doesn't load and gives an ASP.NET exception.
If you're doing this on a development machine, you can disable strong name verification altogether with sn -Vr *. If you do this, you don't have to resign anything. This approach can be a security risk, but if you are comfortable with it, it's easier than resigning.
Specifically, from MSDN, it says:
Registers assembly for verification skipping. Optionally, you can specify a comma-separated list of user names. If you specify infile, verification remains enabled, but the public key in infile is used in verification operations. Assembly can be specified in the form *, strongname to register all assemblies with the specified strong name. Strongname should be specified as the string of hexadecimal digits representing the tokenized form of the public key. See the -t and -T options to display the public key token.
And the security risk:
Caution: Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification.
ghusse linked to a blog post giving the answer. The answer is described there. As he points out, you have to use a post-instrument event on each signed assembly.
It's easiest to call sn.exe directly:
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sn.exe" -R [pathOfDll] [pathOfSNK]
Note that [pathOfDll] is located in the directory obj\Debug associated to the project.
The answer is described here. You have to use a post-instrument event on each signed assembly.
I could not manage to make it work "as is" with my installation of VS 2010. I had to call this command line as a post-build event on each dll :
"C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" & sn -Ra [pathOfDll] [pathOfSNK]
Note that [pathOfDll] is located in the directory obj\Debug associated to the project.
The easiest way to get instrumentation work on signed binaries, which have not been re-signed, is to disable signature checks altogether. This is a machine wide setting that you can activate by registering an exception for the * pattern:
sn.exe -Vr *
This command must be executed from an elevated command prompt. You will find sn.exe in the SDK (in my case, I found it in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin).
When you are finished with testing, you should unregister the exception:
sn.exe -Vu *
or else your machine could be vulnerable to malicious code, since assemblies will be trusted even if they have been tampered with.
See also Access denied running sn.exe on Windows 7.
The profiler probably changes the assembly and because it was previously signed.
Apparently you need to add a post-instrument action that re-signs the assembly.
This could be a problem because you do not have the sn file that was used to sign the 3rd party assemblies.
Might have taken the lazy learning-new-things-free way out here, but I ended up solving this by writing a powershell script to unsign all the projects in my solution -- worked just fine. As part of the script, I save the original csproj files so I can revert them after. (you could also just undo changes in source control).
http://pastebin.com/UbABvz7d
should be able to revert by calling it passing the -revert switch.

Embedding an application manifest into a VB6 exe

I have recently gone through a bunch of standalone utility apps written in VB6 to make sure that registry virtualization is turned off for Windows Vista and above. I created a standalone manifest file for each exe, set the requestedExecutionLevel appropriately (some of them need to modify HKEY_LOCAL_MACHINE registry keys, others do not), and tested them. They all appear to work correctly.
I have only one small problem remaining. Since they are standalone utilities, people are used to just copying them around the network and running them manually. If anyone forgets to copy the manifest file as well as the exe, then the exe will silently write to the virtualized registry key instead of the real one and cause hard-to-debug problems.
The obvious solution is to embed the manifest into the exe as a resource. All the articles I have read on the net tell you to embed the resource like this:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
This should work just fine, except that the VB compiler always creates the application icon with resource ID = 1. When I tried the above code, Windows refused to run the exe, complaining about a resource error (I'll update this post with the details later). I tried changing the resource ID to another number, after which Windows ran the program successfully but did not recognise the manifest contents.
Does anyone know of a way to get an embedded manifest to work in a VB6 exe, or should I just stick with an external file?
UPDATE 1
The text given above is the whole content of the .rc file. I compile it to a .res file like this:
"%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe" /r /fo "Resources.res" "Resources.rc"
And embed it in the VB6 project file like this:
Type=Exe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\..\WINDOWS\system32\stdole2.tlb#OLE Automation
Form=Main.frm
ResFile32="Resources.res"
IconForm="FMain"
Startup="FMain"
HelpFile=""
Title="Windows Vista Registry Test - VB6"
ExeName32="RegistryTestVB6.exe"
Path32=""
Command32=""
Name="RegistryTestVB6"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionComments="Windows Vista Registry Test - VB6"
VersionCompanyName=""
VersionFileDescription="Windows Vista Registry Test - VB6"
VersionLegalCopyright=""
VersionProductName="Windows Vista Registry Test - VB6"
CondComp=""
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
When I read the compiled exe into the VS2008 resource editor, it looks like this:
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
When I construct an exact equivalent VB.NET test app in VS2008, then load that into the resource editor, it looks like this instead:
RegistryTestNET.exe
Icon
32512 [Neutral]
RT_MANIFEST
1 [Neutral]
Version
1 [Neutral]
UPDATE 2
Testing - the .NET exe runs fine on both Windows XP and Windows 7. However, the VB6 exe produces the following error on XP:
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
and the following error on 7:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Looking in the event log I see the following entry:
Activation context generation failed for "RegistryTestVB6.exe". Error in manifest or policy file "RegistryTestVB6.exe" on line 10. Invalid Xml syntax.
Needless to say the XML isn't invalid, it's exactly the same file with the same encoding that I used for the .NET exe, and that one works.
RESOLUTION
The VB6 compiler does indeed require that an arbitrary text file included in a resource must be an exact multiple of 4 bytes. I simply added spaces to the XML until Notepad++ told me that the total file size including BOM was a multiple of 4.
Thanks to both Michael and Jim for pointing me in the correct direction. Just a pity I can't mark you both as the answer!
Interestingly enough, I had to do the exact same thing recently. Following the steps Christian described, I got it to work the first time through. For prosperity, here is the entire workflow I followed:
Created a RC file as described in the orginal question
Created a app.manifest, preserving whitespace characters, which are VERY IMPORTANT for this to work. As stated in previous answers, the file size must be a multiple of 4.
Ran RC.EXE as described in the original question against the rc to generate the .res file
Edited my Project.VBP file to include the following line near the top:
ResFile32="Resources.res"
Built EXE in standard vb6 environment. When deployed on a vista or win7 machine, the shield shows up and the user is prompted to run as administrator. When opening the EXE file in studio, I verified the resources.
Notepad++ tells me that the encoding on my app.manifest file is ANSI. It did not include an byte order mark at the start of the file.
If you are still having troubles, let me know and I'll share whatever I can with you. Other than that, I'm not sure what to tell you other than Works on my Machine!
VB6 has a quirk in that any resource element must be an exact multiple of 4 in length. Try padding the manifest file out with spaces to ensure this, and see if that changes the behavior.
This quirk was documented in Microsoft article Q297112 (archive).
Also, you might add the resource using the VB6 IDE instead of editing the VBP. The effect may be the same, but the resource editor is the standard means for doing this.
Using the Resource Compiler (rc.exe) is going the long way around. There is a much simpler option for embedding an application manifest within an executable, whether C++ or VB6 or just about any other language. The Manifest Tool (mt.exe) was written specifically to embed manifests within binaries and is provided free of charge with the Windows SDK. The added benefit of using mt.exe is that it automatically handles any necessary padding.
Simply run the following command line after the binary has been compiled. I have used the naming convention used internally by the Visual C++ 2005 compiler, where the manifest filename contains the full program name with ".intermediate.manifest" appended.
mt.exe -nologo -manifest "program.exe.intermediate.manifest" -outputresource:"program.exe;#1
Update: I have personally been using this in an automated build process with VB6 executables for over two years now. It has been so successful that we have eliminated OS compatibility tests - specific to manifests - from our regression testing.

Resources