c# - 如何从 Powershell 调用 GetInstance

标签 c# powershell

我正在对笔记本电脑的控制插件进行逆向工程,并试图找出如何调用模拟“应用程序”正在执行的操作的方法。它是用 C# 编写的,所以我想我可以使用 PowerShell 来调用它的方法。 我使用 DotPeek 发现所有内容都被处理到一个 DLL 中,该 DLL 实现了我想要访问的方法。

该类看起来像:

namespace Vendor.package1.package2.SomePlugin
{
  internal class SomeClass : IInterfaceThatIWant, ...
  {

    ~SomeClass()
    {
    }
  

    public RequestObject SetSomething()
    {
      ... method that I want to use
    }

    public ResponseObject GetSomething()
    {
      ...
    }
  
    private SomeClass()
    {
      ...
    }

    public static SomeClass GetInstance()
    {
      ...
    }
  }

在 PowerShell 中,我尝试过:

Add-Type -Path "c:\pathtodll\x64\vendor.dll"

[System.Reflection.Assembly]::LoadFrom("c:\pathtodll\x64\vendor.dll")

...没有显示任何错误,所以我认为两者都有效。

接下来我正在尝试:

[Vendor.package1.package2.SomePlugin.SomeClass]::GetInstance()
   Unable to find type [Vendor.package1.package2.SomePlugin.SomeClass].  
New-Object Vendor.package1.package2.SomePlugin.SomeClass
   New-Object : Cannot find type [Vendor.package1.package2.SomePlugin.SomeClass]: verify that the assembly containing this type is loaded.
[Vendor.package1.package2.SomePlugin.SomeClass]::GetInstance
   Unable to find type [Vendor.package1.package2.SomePlugin.SomeClass].  

以及各种其他排列,但我无法获得类句柄。

最佳答案

要获取对非公共(public) SomeClass 类型的引用,有几个选项:

1。让 Add-Type 返回程序集中的所有类型

Add-Type 有一个 -PassThru 开关,它将返回在加载的程序集中找到的所有类型,无论访问如何:

# Import assembly out emit types
$VendorTypes = Add-Type -Path "c:\pathtodll\x64\vendor.dll" -PassThru

# Filter the types for the one we need
$SomeClassType = $VendorTypes.Where({$_.FullName -eq 'Vendor.package1.package2.SomePlugin.SomeClass'})

# Invoke public static `GetInstance()` method
$SomeInstance = $SomeClassType::GetInstance()

$SomeInstance.SetSomething()

2。通过 Assembly.GetTypes()

发现类型元数据

As you've already found out[Assembly]::LoadFrom(...) 还返回一个 Assembly 对象,通过它我们可以发现它包含的类型:

# Load assembly, hold on to Assembly reference
$VendorAssembly = [System.Reflection.Assembly]::LoadFrom("c:\pathtodll\x64\vendor.dll")

# Get all contained types
$VendorTypes = $VendorAssembly.GetTypes()

# Same steps as above ...

[...] the dll is successfully loaded, I can access the public classes

在这种情况下,您还可以通过其中一种公共(public)类型访问程序集:

$VendorAssembly = [Vendor.package1.package2.SomePublicClass].Assembly

3。从 AppDomain

发现程序集元数据

如果您没有直接调用 Add-Type[Assembly]::LoadFrom(),而是尝试发现由GAC 中的程序集还是由模块间接加载?

幸运的是,我们可以让运行时告诉我们所有已通过 [AppDomain] 类加载的程序集:

# Enumerate all loaded assemblies
$AllAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()

# Filter for the vendor assembly in question
$VendorAssembly = $AllAssemblies.Where({ $_.Location -like "C:\pathtodll\x64\vendor.dll" })

# Same steps as above

调用非公开成员

如果 GetInstance 也是非公开的,您可能必须使用反射来访问它:

# Use reflection to obtain a reference to the GetInstance method
$GetInstanceMethod = $SomeClassType.GetMethod("GetInstance", [System.Reflection.BindingFlags]'Static,NonPublic')

# Static methods need no invocation target, second argument is parameter args for the target method
$SomeInstance = $GetInstanceMethod.Invoke($null, @())

要调用实例方法,您需要传递对目标实例的引用:

# Use reflection to obtain a reference to the SetSomething method, 
# Notice `Instance` instead of `Static` in the list of binding flags
$SetSomethingMethod = $SomeClassType.GetMethod("SetSomething", [System.Reflection.BindingFlags]'Instance,NonPublic')

# Pass the SomeClass instance we created in the previous example as the invocation target:
$RequestObject = $SetSomethingMethod.Invoke($SomeInstance, @())

关于c# - 如何从 Powershell 调用 GetInstance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63532201/

相关文章:

c# - 选择 4 个具有相同 CSS 类的按钮

powershell - 更改工作流的 SerializationMethod

powershell - 使用 Powershell/curl 检查 http header 的问题

azure - 未找到 Az 包

windows - 是否有一种编程方式来确定支持哪些应用程序处理器架构?

powershell - 使用 powershell_script 自动导入 mediawiki

javascript - KnockoutJS - 嵌套 JSON 对象

c# - 如何在 C# windows universal 10 中拨号

c# - excel中如何在数字前输入零?

c# - 建立博客数据模型的最佳实践