Sunday, June 2, 2013

Working with Unmanaged Callback Functions in PowerShell

tl;dr version

With a little bit of work, you can bind a scriptblock to an unmanaged callback function in PowerShell. The key to accomplishing this is by casting a scriptblock as a non-generic delegate that has the function signature of the desired callback function. Fortunately, creating non-generic delegates is made easy with my Get-DelegateType function.



I’ve previously spoken in depth about the various ways to interact with the Win32/Native API in PowerShell. The ability to do this unlocks all kinds of potential for PowerShell. There was one subset of functions however, that to this day I was unable to interact with – those that have parameters with unmanaged callback functions. C# developers may cry foul of my assertion and state that you can easily do this in C# code and then just call the Add-Type cmdlet. Those developers would be right. I however, wanted to accomplish this in pure PowerShell without compiling a single line of code.

For those who may not be familiar with callback functions, they are basically a block of executable code that gets passed in as a parameter to a function, typically as a function pointer. When the function executes the callback function, it generally passes several arguments. It is up to the implementation of the callback function as to what gets done with those arguments.

For example, the EnumChildWindows user32 function accepts a WNDENUMPROC (EnumChildProc) parameter – a callback function that gets passed to it a window handle and an optional user-defined parameter. Here are the function definitions for both EnumChildWindows and EnumChildProc:


Now, function pointers are simple in C. That concept doesn’t easily translate to the world of PowerShell, however. The closest analog to a function pointer in .NET is a delegate which we can work with in PowerShell. In fact, it is not well known but you can actually cast a scriptblock as a delegate! The PowerShell engine implements a lot of plumbing under the hood in order to make this happen. Here’s a silly example of a scriptblock being cast and invoked as a generic Func delegate:
Now back to callback functions. After a little bit of experimentation, I discovered that you cannot bind a scriptblock to a generic delegate like we did in the last example when dealing with P/Invoke methods. You can, however bind them to non-generic types. In fact, that’s exactly what Get-DelegateType was designed to do! As an example, this is the code I used to replicate the EnumChildProc callback function:
The only thing left to do is to define the method signature for the EnumChildWindows function. The following table lists the equivalent types that we’ll use in PowerShell.


Now that we have everything we need to get started, I wrote a function that enumerates all child windows and returns their handle and title – Get-ChildWindows
 
 
You may have noticed my use of ugly global variables in the $Action scriptblock. They were necessary because the scriptblock executes in a bizarre state where it does not have the full functionality of a PowerShell session. Those familiar with registering .NET events with the Register-ObjectEvent cmdlet will know what this it like. Basically, a good portion of PowerShell’s functionality breaks when running in this environment – the pipeline doesn’t work and objects cannot be output. The only real form of user output available to you is via the Write-Host cmdlet. A way around this is to save all output to a global variable. Then, once the scriptblock is done executing you can interact with your output like normal. Hopefully, this issue will be fixed in a future version of PowerShell.

That’s it. Hopefully, this will be helpful to those working with the Win32 API in PowerShell and to people like me who refuse to compile C# in their scripts. ;D

Friday, April 5, 2013

Shellcode Execution in .NET using MSIL-based JIT Overwrite


Download: Invoke-ShellcodeMSIL

While investigating MSIL opcodes a while back, I uncovered a useful opcode - Cpblk. Cpblk is the MSIL equivalent of a memcpy. After writing a .NET method that utilized Cpblk, I immediately thought of a practical use - overwrite a JITed .NET method with shellcode. That way, I could execute shellcode directly without needing to call any Win32 functions. I wrote Invoke-ShellcodeMSIL as an implementation of my idea.

For those who are unfamiliar with MSIL. MSIL is Microsoft's implementation of the Common Interface Language or in other words, .NET bytecode. Using reflection or an IL assembler (like ilasm), you can craft .NET methods using raw MSIL opcodes. There is a great introduction to MSIL opcode assembly in "Metaprogramming in .NET."

For Invoke-ShellcodeMSIL, I wrote a dummy method that simply XORs an input number 101 times. I chose to use an XOR function because I was confident that it would not be optimized during the JIT process. As a consequence, this dummy method will contain sufficient space for a shellcode buffer.

I then wrote the 'memcpy' method using the following opcodes:

Ldarg_0 - Arg0 is the destination buffer (i.e. the address of the dummy JITed method)
Ldarg_1 - Arg1 is the source buffer (i.e. where my shellcode is allocated in RW memory)
Ldarg_2 - Arg2 is the length of the source buffer
Volatile
Cpblk
Ret

After defining the XOR method using reflection, I executed it twenty times in order to force the method to be JITed. Finally, I called my overwrite method and overwrote the JITed XOR method with my shellcode. Here are the screenshots of the disassembly before (left) and after (right) the overwrite:


When you provide your shellcode to Invoke-ShellcodeMSIL, make sure your shellcode ends in a RET and that the stack is in proper alignment (duh :P) or PowerShell will crash. A shellcode stub us generated at runtime depending upon the bitness PowerShell. All it does is save the non-volatile registers, jump to your shellcode, and return zero to the caller. The rest is up to you. :D

Enjoy!