When All Else Fails: PowerShell Reflective Assembly Loading

By Red Siege | April 9, 2026

by Ian Briley

Sometimes an older trick is the only trick that will work for you on an engagement.

Case in point, recently I was on an engagement, where if anything from my normal bag of tricks touched disk or looked dicey, AV/EDR would blow it away.

Loading raw PowerShell scripts from known attacker tooling got flagged and quarantined. Any encoded PowerShell scripts would get decoded and blown away.

Any binary, regardless of if a packer was used or not, got blocked by fairly strong application allowlisting processes.

The only thing I had access to was entering commands into the PowerShell terminal (even that had some restrictions in place). Often times the tests are time boxed to a week, and that’s not enough time to manually recreate and retype a binary’s functions into the command shell. I could not fathom trying to manually recreate tooling such as Certify in PowerShell without triggering an alert, especially in the limited amount of testing time I had.

Enter: PowerShell Reflective Assembly Loading!

What is PowerShell Reflective Assembly Loading?

In short, this is a technique you can use to load .NET assemblies into memory using PowerShell. There are a handful of caveats to this but effectively, since PowerShell is built directly on top of the newer versions of .NET, there’s a ton of overlap for C# classes. Which means for us there’s “minimal” tinkering to do this!

To make this work:

  • Ensure your project sets a namespace
  • Set the Main method and class to public
  • Compile the binary
  • Convert the binary to bytes
  • Base64 encode the bytes
  • Use PowerShell to load the base64-encoded bytes and call on the entry point of the application

The first main part of this is making sure your access modifiers are set to public. This allows the current process you’re reflectively loading the binary into to access the code. Depending on your code this could be as easy as changing out a handful of access modifiers. Below is an example of this from the Certify repo.

Class Set to Public

Nothing special needs to be done to compile the code. Just compile the C# code how you’d normally do it. Next, we will want to convert our binary into bytes and then encode those bytes into base64 for safe transport. Never transfer raw bytes over the internet, it’s a recipe for disaster!

Typically, I save the encoded binary into a file so I can easily copy the encoded code out of that file and use elsewhere.

[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\SomeDirectory\DesiredBinary.exe")) | Out-File -Encoding ASCII C:\SomeDirectory\DesiredBinary.txt

Next, we’ll load the encoded binary into a variable in PowerShell.

$EncodedAssemblyName = [System.Reflection.Assembly]::Load([Convert]::FromBase64String("EncodedValueGoesHere"))

Finally, we’ll call on the program and point to its entry point (it’s always Main because C# enforces this standard).

[EncodedAssemblyName.Program]::Main("Any supporting arguments go here".Split())

Potential Trip-Ups

In the Certify example, the program’s namespace is Certify, and the Main method is enclosed in the Program class. In this case, we can execute the code using convention below.

[EncodedAssemblyName.Program]::Main("Any supporting arguments go here".Split())

If your program’s namespace is different for some reason, or if the class isn’t Program, you’re going to need to make a few changes. Consider the following example pseudocode:

namespace MyNETAssembly
{
 public class MyClass
 {
   public static void Main()
}
}

In this case, we’d execute the assembly like this:

[MyNetAssembly.MyClass]::Main("Any supporting arguments go here".Split())

Conclusion

This is a wonderfully easy way to get a binary that would not normally be allow-listed on the machine to run with all the functionality intact. Despite this being a fairly well documented technique with several detection signatures written for tools like Splunk or Elastic, I’ve rarely seen this actually trigger any alerts on the tests I’ve done.


About Ian Briley, Security Consultant

Ian Briley has over 10 years of experience in information security consisting of The United States Armed Forces, the Healthcare industry, Security Operation Centers, and Security Consulting. Ian is an experienced presenter, trainer, developer, maker, and researcher. Ian enjoys attending local security focused groups and learning more about cloud-based environments and solutions.

Certifications:

CRTO, GWAPT, eJPT, CySA+, SSCP, SEC+