Jump to content
Tuts 4 You

.net Memory Security By Coderipper


CodeExplorer

Recommended Posts

.NET memory security

Loking under some encryption/decryption tutorial I've noticed that they use MemoryStream.ToArray(); MemoryStream.ToArray() is bad since will create a new byte array under memory – insted just use an UnmanagedMemoryStream and UnmanagedMemoryStream.GetBuffer()!

But the contents of the UnmanagedMemoryStream buffer (you get him using GetBuffer()) will be still there even if I close the memory stream, set him to 0 and call System.GC.Collect()

What is going on ?

1. The memory is released : According to Microsof the object is destroyed when all its references are explicitly set to null or it goes out of scope.

2. The contents is still there and probabily won't be overwrited by Framework whit other value!

1.) 1st lame solution is to set each byte from buffer whit 0:

for (int i=0;i< outStream.GetBuffer().Length;i++)

outStream.GetBuffer()=0;

2. Another solution could be to create of a secured MemoryStream which will always have the byte array encryted but this prove to be ineficient since at a point you may still need the whole byte buffer decrypted or the encryption/decryption algorithm doesn't suport partial encryption/decryption.

The best solution is the double encryption : once encrypt the whole data and after that encrypt each subset of data.

3.) Use Marshal.AllocHGlobal for alocating needed memory and use a pointer for accessing memory;

// Allocate a block of unmanaged memory

IntPtr memptr = Marshal.AllocHGlobal(4);

byte* pointer = (byte*)memptr.ToPointer();

pointer[0]=21; // set first byte whit 21

byte firstbyte = pointer[0]; // get first byte

Marshal.FreeHGlobal(memptr); // free the memory

4. ) Build your own byte[] array:

byte[] test = new byte[]{1,2,3,4};

uint* pointer = null;

int arraytable = 0;

// we create a new byte array whit 4 bytes

int newsize = 4;

IntPtr memptr = Marshal.AllocHGlobal(8+newsize);

// 8 bytes needed for struct

fixed ( byte* p = test)

{

// real address from where byte[] starts

int* bytearraystart = (int*)(p-8);

arraytable = bytearraystart[0]; // get the

Marshal.WriteInt32(memptr,0,arraytable);

}

Marshal.WriteInt32(memptr,4,newsize);

Assembly loadedasm = Assembly.Load(test);

Unfortunality .NET don't suport IntPtr to byte[] casting; we are only saved by reflection: replace the variable test whit memptr (of type IntPtr);

Link to comment
  • 10 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...