如何在PowerShell 7中定义动态模块

huangapple go评论66阅读模式
英文:

How to define a dynamic module in powershell 7

问题

我正在尝试将一个PowerShell 5脚本迁移到PowerShell 7。这个脚本的目标是在内存中加载Win32 API,使用 [AppDomain]::CurrentDomain 和程序集。

以下是代码:

function New-InMemoryModule {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [String]
        $ModuleName = [Guid]::NewGuid().ToString()
    )

    $AppDomain = [AppDomain]::CurrentDomain

    $LoadedAssemblies = $AppDomain.GetAssemblies()

    foreach ($Assembly in $LoadedAssemblies) {
        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {
            return $Assembly
        }
    }

    $AssemblyName = New-Object System.Reflection.AssemblyName($ModuleName)
    $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($AssemblyName, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName)

    return $ModuleBuilder
}

$Mod = New-InMemoryModule -ModuleName Win32
echo $Mod

当我在PowerShell 5上执行它时,第一次运行的输出是:

FullyQualifiedName : Win32
MDStreamVersion    : 131072
ModuleVersionId    : 8a94565d-3e53-4cdf-9b9d-ae6dad1df4cd
MetadataToken      : 1
ScopeName          : Win32
Name               : <Dans le module de la mémoire>
Assembly           : Win32, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
CustomAttributes   : {}
ModuleHandle       : System.ModuleHandle

然后第二次当模块实例化时:

GAC    Version        Location
---    -------        --------
False  v4.0.30319

但是当我尝试在PowerShell 7中执行它时,我收到以下错误:

Method invocation failed because
 | [System.AppDomain] does not contain a       
 | method named 'DefineDynamicAssembly';

是否有人知道语法是否变化或者我应该如何调用它?我阅读了MSDN文档,但没有找到任何信息。

我尝试了一些GPT查询,但提供的脚本根本不会加载Win32 API。

祝您有一个愉快的一天!

更新后的代码:

function New-InMemoryModule {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [String]
        $ModuleName = [Guid]::NewGuid().ToString()
    )

    $LoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()

    foreach ($Assembly in $LoadedAssemblies) {
        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {
            return $Assembly
        }
    }

    $AssemblyName = New-Object System.Reflection.AssemblyName($ModuleName)
    $AssemblyBuilder = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly($AssemblyName, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName)

    return $ModuleBuilder
}

$Mod = New-InMemoryModule -ModuleName Win32
echo $Mod

第一次执行输出:

FullyQualifiedName : RefEmit_InMemoryManifestModule
MDStreamVersion    : 131072
ModuleVersionId    : ca1f7586-b9b8-41ed-9d0a-fac37f7f080d
MetadataToken      : 1
ScopeName          : RefEmit_InMemoryManifestModule
Name               : <In Memory Module>
Assembly           : Win32, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
ModuleHandle       : System.ModuleHandle
CustomAttributes   : {}

第二次执行输出:

GAC    Version        Location
---    -------        --------
False

我更新了代码,但似乎不能正确构建模块,我尝试了各种语法并阅读了一些文档,但无法正确加载它。最终目标是在内存中加载netapi32并执行NetShareEnum。

希望对您有所帮助。

英文:

I'm currently trying to migrate a powershell 5 script to a powershell 7 one.
The goal of this script is to load the win32 api in memory using [AppDomain]::CurrentDomain and assemblies.

Here is the code :

function New-InMemoryModule {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(&#39;PSUseShouldProcessForStateChangingFunctions&#39;, &#39;&#39;)]
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [String]
        $ModuleName = [Guid]::NewGuid().ToString()
    )

    $AppDomain = [AppDomain]::CurrentDomain

    $LoadedAssemblies = $AppDomain.GetAssemblies()

    foreach ($Assembly in $LoadedAssemblies) {
        if ($Assembly.FullName -and ($Assembly.FullName.Split(&#39;,&#39;)[0] -eq $ModuleName)) {
            return $Assembly
        }
    }

    $AssemblyName = New-Object System.Reflection.AssemblyName($ModuleName)
    $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($AssemblyName, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName)

    return $ModuleBuilder
}

$Mod = New-InMemoryModule -ModuleName Win32
echo $Mod

When i execute it on powershell 5, this is the output when ran the first time :

FullyQualifiedName : Win32
MDStreamVersion    : 131072
ModuleVersionId    : 8a94565d-3e53-4cdf-9b9d-ae6da
                     d1df4cd
MetadataToken      : 1
ScopeName          : Win32
Name               : &lt;Dans le module de la        
                     m&#233;moire&gt;
Assembly           : Win32, Version=0.0.0.0,      
                     Culture=neutral,
                     PublicKeyToken=null
CustomAttributes   : {}
ModuleHandle       : System.ModuleHandle

And then the second time when the module is instanced :

GAC    Version        Location
---    -------        --------
False  v4.0.30319

But when i try to execute it in powershell 7, i get the following error :

Method invocation failed because
     | [System.AppDomain] does not contain a       
     | method named &#39;DefineDynamicAssembly&#39;

Do anyone has any idea if the syntax or if the way i'm suppose to call it changed ?
I read the MSDN Documentation but didn't find anything.

I tried some GPTs queries but the script provided wouldn't load the win32 api at all..

Have a nice day !

Updated code :

function New-InMemoryModule {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(&#39;PSUseShouldProcessForStateChangingFunctions&#39;, &#39;&#39;)]
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [String]
        $ModuleName = [Guid]::NewGuid().ToString()
    )

    $LoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()

    foreach ($Assembly in $LoadedAssemblies) {
        if ($Assembly.FullName -and ($Assembly.FullName.Split(&#39;,&#39;)[0] -eq $ModuleName)) {
            return $Assembly
        }
    }

    $AssemblyName = New-Object System.Reflection.AssemblyName($ModuleName)
    $AssemblyBuilder = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly($AssemblyName, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName)

    return $ModuleBuilder
}

$Mod = New-InMemoryModule -ModuleName Win32
echo $Mod

Output 1 execution :

FullyQualifiedName : RefEmit_InMemoryManifestMo
                     dule
MDStreamVersion    : 131072
ModuleVersionId    : ca1f7586-b9b8-41ed-9d0a-fa
                     c37f7f080d
MetadataToken      : 1
ScopeName          : RefEmit_InMemoryManifestMo
                     dule
Name               : &lt;In Memory Module&gt;        
Assembly           : Win32, Version=0.0.0.0,   
                     Culture=neutral, 
                     PublicKeyToken=null       
ModuleHandle       : System.ModuleHandle       
CustomAttributes   : {}

Output 2nd execution :

GAC    Version        Location
---    -------        --------
False

I updated my code but it doesn't seem to build the module correctly, i tried various syntax and read a bit of doc but i wasn't able to load it correctly.
The end goal is to load netapi32 in memory and execute NetShareEnum.

Regards.

答案1

得分: 3

In PowerShell 7, the [System.AppDomain] class does not have a DefineDynamicAssembly method, which explains the error. The [System.Reflection.Emit.AssemblyBuilder] class has been moved to a different namespace.

你可以直接使用[System.Reflection.Emit.AssemblyBuilder]类,它位于[System.Reflection.Emit]命名空间中。

英文:

In PowerShell 7, the [System.AppDomain] class does not have a DefineDynamicAssembly method, which explains the error. The [System.Reflection.Emit.AssemblyBuilder] class has been moved to a different namespace.

you can use the [System.Reflection.Emit.AssemblyBuilder] class from the [System.Reflection.Emit] namespace directly.

huangapple
  • 本文由 发表于 2023年6月8日 15:02:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定