Last active
June 6, 2017 14:28
-
-
Save xoofx/628ad6b802026c780e9d2a1b1867b964 to your computer and use it in GitHub Desktop.
Mess the stack by using plain safe code (cheating through ExplicitLayout/FieldOffset)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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