Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yubico.NativeShims breaks Powershell #32

Closed
virot opened this issue Dec 12, 2022 · 16 comments
Closed

Yubico.NativeShims breaks Powershell #32

virot opened this issue Dec 12, 2022 · 16 comments
Labels
awaiting reply When we are waiting for response from user

Comments

@virot
Copy link

virot commented Dec 12, 2022

With the implementation of Yubico.NativeShims (1.3.0), it is no longer possible (I cant find a way) to use the SDK for work with Powershell (which is based on .NET).

I have no problem adding the other DLLs, but Yubico.NativeShims gives the error:
(PS 7.3):

Add-Type: Bad IL format. The format of the file 'C:\temp\yubico.nativeshims.1.5.2\runtimes\win-x64\native\Yubico.NativeShims.dll' is invalid.

(PS 5.1):

Add-Type : Could not load file or assembly 'file:///C:\temp\yubico.nativeshims.1.5.2\runtimes\win-arm64\native\Yubico.N
ativeShims.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
At line:1 char:1
+ Add-Type -Path C:\temp\yubico.nativeshims.1.5.2\runtimes\win-arm64\na ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], BadImageFormatException
    + FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand

This restricts usage of Yubico.Yubikey and Yubico.Core to version 1.2.0 or earlier.

@GregDomzalski
Copy link
Contributor

Is this a compiled / DLL based PowerShell cmdlet? Or a script-based cmdlet?

PS 5.1 (based on .NET framework) is probably the same as #11.

PS 7.3 (which I believe is based on .NET core?)... This error is given when there's a platform / architecture mismatch. Are you sure you're running in a 64-bit process with your module compiled as 64-bit (and not something like 'AnyCPU'?)

I think I've finally made some progress tracking down what I hope to be a solution for this native dependency import problem that older .NET frameworks have been having. The next release should (hopefully, finally) have a fix for this issue.

@virot
Copy link
Author

virot commented Dec 13, 2022

Script based.

#Works
PS C:\temp> add-type -path .\yubico.core.1.5.1\lib\net47\Yubico.Core.dll
I have tried all.. Even though I run x64 both OS and Powershell (.net)
PS C:\temp> add-type -path .\yubico.nativeshims.1.5.2\runtimes\win-arm64\native\Yubico.NativeShims.dll
Add-Type: Bad IL format. The format of the file 'C:\temp\yubico.nativeshims.1.5.2\runtimes\win-arm64\native\Yubico.NativeShims.dll' is invalid.
PS C:\temp> add-type -path .\yubico.nativeshims.1.5.2\runtimes\win-x64\native\Yubico.NativeShims.dll
Add-Type: Bad IL format. The format of the file 'C:\temp\yubico.nativeshims.1.5.2\runtimes\win-x64\native\Yubico.NativeShims.dll' is invalid.
PS C:\temp> add-type -path .\yubico.nativeshims.1.5.2\runtimes\win-x86\native\Yubico.NativeShims.dll
Add-Type: Bad IL format. The format of the file 'C:\temp\yubico.nativeshims.1.5.2\runtimes\win-x86\native\Yubico.NativeShims.dll' is invalid.
PS C:\temp> $PSVersionTable

Name Value


PSVersion 7.3.0
PSEdition Core
GitCommitId 7.3.0
OS Microsoft Windows 10.0.19044
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

PS C:\temp>

@GregDomzalski
Copy link
Contributor

Oh, hmm.

OK - that will take some more experimentation on my part. I don't think anyone on the team has tried using this from a script module yet.

I will let you know what I find out.

@GregDomzalski
Copy link
Contributor

Hi @virot - sorry this has taken so long.

I originally though this might be related to #11 - however I realized that NuGet is probably not involved with your PowerShell project.

Am I correct in assuming that you were downloading the NuGet packages directly and then unpacking the assemblies by hand?

If that's the case, I recommend copying out all of the assemblies into a common dependency directory. Since Yubico.NativeShims is a native DLL, you should not use "Add-Type" to import it, as there is nothing to import. Instead, the Yubico.NativeShims DLL should be placed in the same directory as the Yubico.Core assembly.

Keep in mind that the version of Yubico.NativeShims that you copy must match the processor architecture of the running PowerShell process.

@virot
Copy link
Author

virot commented Feb 3, 2023

Yes I am downloading the NuGet packages and unzipping. I just tried tried the 1.6.1 version:

  • Download zip, Unzip
  • Copy to new folder:
    • .\lib\net47\Yubico.Core.dll
    • .\lib\net47\Yubico.YubiKey.dll
    • .\runtimes\win-x64\native\Yubico.NativeShims.dll
    • .\lib\net6.0\Microsoft.Extensions.Logging.Abstractions.dll
  • Start new powershell 7, go to new folder
  • gci |%{add-type -path $_.fullname} #Will add all, Native will warn
  • [Yubico.YubiKey.YubiKeyDevice]::FindAll() # Will fail with unable to load DLL Yubico.NativeShims.dll

@virot
Copy link
Author

virot commented Feb 3, 2023

Will try the other way, by building a DLL module, but that will make it less easy to extend.

@virot
Copy link
Author

virot commented May 7, 2023

I cant understand that NativeShims.
I have created a supersimple repo with a Windows Powershell module DLL https://github.com/virot/powershell_yubikey.

If you build it will copy dlls etc.. It copies all DLLs required... Except NativeShims.
Test-SampleCmdlet : Unable to load DLL 'Yubico.NativeShims': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
At line:1 char:1

  • Test-SampleCmdlet -FavoriteNumber 3
  • Test-SampleCmdlet : Unable to load DLL 'Yubico.NativeShims': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Wondering if "Calling C# SDK from Python results in "Unable to load DLL 'Yubico.NativeShims'" error #47 is related, as that seems to be running powershell in python.

@virot
Copy link
Author

virot commented May 10, 2023

I did the follwing comments in the wrong issue:
#47

Funny thing. The only places it seems to read is:

C:\Windows\System32\WindowsPowerShell\v1.0\Yubico.NativeShims
C:\Windows\System32\Yubico.NativeShims
So I copied it to C:\Windows\System32\WindowsPowerShell\v1.0\Yubico.NativeShims without .dll, otherwise it doesn't work. And now I am getting a issue with system.memory. But this is progress. The question is why is it only loading those two locations and why no dll extension.

Switching to building for net472, fix that the Yubico.NativeShims didnt have a dll extention. But I still have the different versions of System.Memory. Looks like I need to figure out how to do bindingRedirect.
I am still getting error about 4.0.1.1 missing, that is 4.5.4 and System.Formats.Cbor required 4.5.5.

But this is really helpful. I would love not to need to put the DLL in the protected folders but that might be out of your hands.

Sorry I didnt explain enough. The reason why it took so long for me to get back, is that I learned how to do a compiled powershell module. So I just set the target and then did a dotnet build and process takes the dlls from %HOMEPATH%.nuget\packages\yubico.yubikey\1.7.0 etc..

And since my code is now a compiled DLL i think I need to understand bindingredirects as yubico.yubikey and its dependency:

Yubico.Core: System.Memory >= 4.5.4
System.Formats.Cbor: System.Memory >= 4.5.5

@GregDomzalski
Copy link
Contributor

Oh, I gotcha. Interesting - so your compiled project's target framework is .NET 4.x and you're still getting the System.Memory issues? That should have been resolved a long time ago ~SDK 1.3.0

Yeah, perhaps if you have other dependencies they could be interfering. The BindingRedirects might be your fix there.

As for the DLL path. If you are able to use .NET Core (I'm not sure if system PowerShell will let you as it's .NET 4.x based) you could possibly use this trick: https://stackoverflow.com/questions/69958594/how-to-select-the-path-for-dllimport-at-run-time-when-the-name-of-the-required-d/69958827#69958827. NativeLibrary.Load is available from .NET Core 3 onwards, I believe.

Basically the idea is - if you manage to load a library into the process, Windows shouldn't attempt to reload a module with the same name. So you might be able to "trick" .NET into using different paths.

It's a long shot, but an avenue worth exploring.

@virot
Copy link
Author

virot commented May 10, 2023

I spent a long time learning how to build a binary module, with lots of new knowledge.
Without even a thought of procmon. but after you reminding me I have a solution without binary module even.. this is where it goes wild :)

Using Powershell 7.3 I can get it to work without putting things in the system32 folder.
The Yubico.NativeShims.dll needs to reside in a folder called win-x64 (or I guess what os-arch you have)
AND the file have to have end in .dll.dll

Then it works. now I am stuck.. I can do it via script module, but a binary module offers so much in overloading etc.. :)

@virot
Copy link
Author

virot commented May 10, 2023

The dlls needed to interact with the DLLs with powershell scripts are on my Windows 10 PC:
Microsoft.Bcl.HashCode.dll
Microsoft.Extensions.Logging.Abstractions.dll
Yubico.Core.dll
Yubico.DotNetPolyfills.dll
Yubico.YubiKey.dll
win-x64\Yubico.NativeShims.dll.dll

@GregDomzalski
Copy link
Contributor

Yeah - one thing to keep in mind is that there's a difference in framework for the system PowerShell (the one that comes with Windows) and PowerShell Core (the one you install on your own).

System PowerShell is based off of .NET Framework 4.x, and so will therefor require all those versions of the SDK assemblies (YubiKey, Core, DotnetPolyfills) in order to work 100% properly.

PowerShell Core on the other hand (7.x), is based off of .NET Core (or 6) and so will better work with the netstandard2.1 assemblies from the SDK.

The implications of this is that certain support libraries like Microsoft.Bcl.HashCode and System.Memory may be present with the one version, but not the other. Or at least the version of those will need to match the overall framework environment you're running in.

I suppose it does make sense that you would need to copy some of our dependencies into your runtime directory as well, so some of what you described above is likely to be expected.

@DennisDyallo
Copy link
Collaborator

Hi @virot ! Were you able to find somehting that works for you?

@DennisDyallo DennisDyallo added the awaiting reply When we are waiting for response from user label Apr 23, 2024
@DennisDyallo
Copy link
Collaborator

Closing old issues. Feel free to reopen if this is still important to you.

@DennisDyallo DennisDyallo closed this as not planned Won't fix, can't repro, duplicate, stale May 17, 2024
@virot
Copy link
Author

virot commented May 18, 2024

Sorry for late reply, I am learning working with C# to resolve issue with, positive results.
Please keep closed.

@DennisDyallo
Copy link
Collaborator

Let us know if you find a reliable solution! Thanks @virot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting reply When we are waiting for response from user
Development

No branches or pull requests

3 participants