Closed dgrif closed 5 years ago
Hi @dgrif,
that is some strange behavior. I ran the unit test and added your test cases and all of them work as expected. I know from past issues that there is a difference between .NET Framework, Core and Windows/Linux in the signature check. See https://github.com/dotnet/corefx/issues/34202
Can you provide more information about your setup?
My dev environments have been a mess, I've been working in VS Code on Win/Mac/Linux and VS on Windows. I noticed it in VS 2015 on my Win10 box.
To replicate it in a more isolated way, I snagged one of the Edge Win10 dev VMs from MS and installed VS 2015 Community. I then created a F# Library project, installed PeNet latest with NuGet and in the fsx I put this test code which evaluates false:
#r "../packages/PeNet.1.0.7/lib/net461/PeNet.dll"
open PeNet
PeNet.Utilities.SignatureInformation.IsSigned("C:\\Windows\\System32\\Kernel32.dll")
val it : bool = false
Another test I get the expected result of True
@secana
Same Edge VM setup as described above, this time I created a console application project, compiled and debugged and using the following code, this time getting results as expected.
open PeNet
let APeFile (aFile:string)=
let ape = PeNet.PeFile(aFile)
ape
[<EntryPoint>]
let main argv =
printfn "%A" argv
let ape = APeFile "C:\\Windows\\System32\\Kernel32.dll"
if ape.IsSigned then
printfn "The file was signed."
else
printfn "The file is NOT signed."
0 // return an integer exit code
I was debugging/testing my functions in scripts via fsi before putting them into my library, so the issue likely lies with that workflow.
@dgrif do you use .NET Core or the old Framework to run the fsx scripts?
Following your tweet, I've tried this on my Windows 10 Home dev box and running
open System
Environment.CommandLine;;
#r "[path to]/packages/PeNet.1.0.8/lib/net461/PeNet.dll"
open PeNet
PeNet.Utilities.SignatureInformation.IsSigned("C:\\Windows\\System32\\Kernel32.dll");;
let ape = PeFile "C:\\Windows\\System32\\Kernel32.dll"
ape.IsSigned;;
with both commands fsi
and dotnet fsi
val it : string =
""C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsi.exe""
val it : bool = false
[file dump omitted]
val it : bool = false
and
val it : string =
""C:\Program Files\dotnet\sdk\3.0.100-preview5-011568\FSharp\fsi.exe""
val it : bool = false
[file dump omitted]
val it : bool = false
i.e. both routes to the answer on either interactive platform go adrift.
With essentially the same code
open System
open PeNet
[<EntryPoint>]
let main argv =
printfn "%A" Environment.CommandLine
printfn "%A" <| PeNet.Utilities.SignatureInformation.IsSigned("C:\\Windows\\System32\\Kernel32.dll")
let ape = PeFile "C:\\Windows\\System32\\Kernel32.dll"
printfn "%A" ape.IsSigned
0 // return an integer exit code
as a .net core 2.1 executable
"C:\Users\steve\source\repos\ClassLibrary1\ConsoleApp4\bin\Debug\netcoreapp2.1\ConsoleApp4.dll"
true
true
and as a framework 4.7.2 executable
""C:\Users\steve\source\repos\ClassLibrary1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe" "
true
true
So it looks like something in the interactive environment is invalidating an assumption at some point.
> ape.PKCS7;;
val it : Security.Cryptography.X509Certificates.X509Certificate2 = null
> ape.Authenticode;;
val it : Authenticode.AuthenticodeInfo = null
Logging from here might shed some light on the mystery.
Hypothesis- the script needs another #r
or two to pull in the dependencies in other nuget packages used for authenticode processing.
Hypothesis confirmed.
PS: C:\Users\steve
07/22/2019 08:00:10>fsi
Microsoft (R) F# Interactive version 10.2.3 for F# 4.5
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> #r "C:/Users/steve/source/repos/ClassLibrary1/packages/PeNet.Asn1.1.3.3/lib/net461/PeNet.Asn1.dll";;
--> Referenced 'C:/Users/steve/source/repos/ClassLibrary1/packages/PeNet.Asn1.1.3.3/lib/net461/PeNet.Asn1.dll' (file may be locked by F# Interactive process)
> #r "C:/Users/steve/source/repos/ClassLibrary1/packages/Newtonsoft.Json.12.0.1/lib/net45/NewtonSoft.Json.dll";;
--> Referenced 'C:/Users/steve/source/repos/ClassLibrary1/packages/Newtonsoft.Json.12.0.1/lib/net45/NewtonSoft.Json.dll' (file may be locked by F# Interactive process)
> #r "C:/Users/steve/source/repos/ClassLibrary1/packages/PeNet.1.0.8/lib/net461/PeNet.dll";;
--> Referenced 'C:/Users/steve/source/repos/ClassLibrary1/packages/PeNet.1.0.8/lib/net461/PeNet.dll' (file may be locked by F# Interactive process)
> open PeNet;;
> PeNet.Utilities.SignatureInformation.IsSigned("C:\\Windows\\System32\\Kernel32.dll");;
Binding session to 'C:/Users/steve/source/repos/ClassLibrary1/packages/PeNet.Asn1.1.3.3/lib/net461/PeNet.Asn1.dll'...
val it : bool = true
So while the original report is actually one of an insufficient script, the swallowing of all potentially diagnostic error information in the Authenticode handler obscured the problem.
@SteveGilham thx alot for helping. So an F# interactive user needs to reference the assembly manually which are referenced by PeNet itself. @dgrif this should solve your problem.
F# community is great!
That's a general .net thing; because the assemblies are not co-located (being in various places under the packages
folder) as they would be with a deployed executable, their locations have to be specified manually.
Hi all, sorry for the delayed reply but this definitely sorted me out. I really appreciate the clarification, thanks!
It appears that signed file checks may have an issue, have only tested with a few known signed x64 binaries, no other info at the moment.