Search code examples
c#.netpowershellwinapipowershell-2.0

How to define a dynamic module in powershell 7


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('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

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               : <Dans le module de la        
                     mémoire>
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 'DefineDynamicAssembly'

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('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

Output 1 execution :

FullyQualifiedName : RefEmit_InMemoryManifestMo
                     dule
MDStreamVersion    : 131072
ModuleVersionId    : ca1f7586-b9b8-41ed-9d0a-fa
                     c37f7f080d
MetadataToken      : 1
ScopeName          : RefEmit_InMemoryManifestMo
                     dule
Name               : <In Memory Module>        
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.


Solution

  • 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.