Skip to content

Instantly share code, notes, and snippets.

@xoofx
Last active June 6, 2017 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xoofx/628ad6b802026c780e9d2a1b1867b964 to your computer and use it in GitHub Desktop.
Save xoofx/628ad6b802026c780e9d2a1b1867b964 to your computer and use it in GitHub Desktop.
Mess the stack by using plain safe code (cheating through ExplicitLayout/FieldOffset)
// hack for https://twitter.com/ashmind/status/871357443036467201
// Write to the stack through FieldOffset and Virtual methods (no unsafe, not using System.Runtime.InteropServices directly into a method)
// valid only for x86-32bits (need to change int Address to long in order to have it working for x64)
// The basic idea is to use FieldOffset on a struct to reinterpret an object reference
// and using this trick to take an address on the stack that doesn't involve manipulating directly IntPtr or unsafe code...
using System.Runtime.InteropServices;
class Program
{
[StructLayout(LayoutKind.Explicit)]
struct MemoryMixer
{
[FieldOffset(0)]
public MemByPtr byptr;
[FieldOffset(0)]
public MemByRef byref;
}
private class MemByRef
{
// virtual call, same method slot than MemByPtr
public virtual void ByRef(ref uint x)
{
x = 0xCCCCCCCC;
}
}
private class MemByPtr
{
public int Address;
// virtual call, same method slot than MemByRef
public virtual void ByRef(int ptr)
{
Address = ptr;
}
}
static void Run()
{
uint stack = 0;
// Create our reinterpreter of address
// Initialize it with a MemByPtr
var mixer = new MemoryMixer { byptr = new MemByPtr() };
// Call the previous reference not as MemByPtr but as MemByRef
// Which will pass the pointer on the stack. MemByPtr will receive the pointer in its ptr argument
mixer.byref.ByRef(ref stack);
// We recover the address passed previously
var address = mixer.byptr.Address;
// We change the instance to be able to write to a memory through a ref
mixer.byref = new MemByRef();
// Start to write to the stack, starting at the variable "stack" and going further in the mem
for (int i = 0; i < 10000; i++)
{
// Here, again, we call through MemByPtr
mixer.byptr.ByRef(address);
address = address + 4;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment