using System.Runtime.InteropServices;
public static void Main()
SecureString secure = new SecureString();
Extensions.AppendString(secure, "Hello world");
IntPtr pSecuredString = GetInternalBuffer(secure);
Console.WriteLine("Address of Secured SecureString: 0x{0:X16}", pSecuredString.ToInt64());
string strSecuredString = Marshal.PtrToStringUni(pSecuredString);
Console.WriteLine("Value of Secured SecureString : {0}", strSecuredString);
IntPtr pSecureString = Marshal.SecureStringToGlobalAllocUnicode(secure);
Console.WriteLine("Address of SecureString: 0x{0:X16}", pSecureString.ToInt64());
string strSecureString = Marshal.PtrToStringUni(pSecureString);
Console.WriteLine("Value of SecureString : {0}", strSecureString);
Marshal.ZeroFreeGlobalAllocUnicode(pSecuredString);
Marshal.ZeroFreeGlobalAllocUnicode(pSecureString);
static readonly Type SecureStringType = typeof(SecureString);
public static IntPtr GetInternalBuffer(SecureString s) {
FieldInfo field = SecureStringType.GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance);
SafeHandle handle = (SafeHandle) field.GetValue(s);
IntPtr internalBuffer = handle.DangerousGetHandle();
public static class Extensions {
public static void Append(this SecureString s, string str) {
foreach ( char ch in str )
public static void AppendString(SecureString s, string str) {