One example of using an arbitrary blob is value type initialization. Take a look at 
the following code:
//--------------------------------
.assembly extern mscorlib {}
.assembly fakestring {}
.module fakestring.exe
.class public value sequential MyVT
{
        .pack 1
        .field public int32 a
        .field public int64 b
        .field public int16 c
        .method public void Init(string Blob,int32 Offset)
        {
                ldarg.0
                ldarg.1
                call instance char[] [mscorlib]System.String::ToCharArray()
                ldc.i4.0
                ldelema [mscorlib]System.Char
                ldarg.2
                add
                sizeof MyVT
                cpblk
                ret
        }
        .method public void PrintFields()
        {
                ldarg.0
                dup
                dup

                ldstr "a = "
                call void [mscorlib]System.Console::Write(string)
                ldfld int32 MyVT::a
                call void [mscorlib]System.Console::WriteLine(int32)

                ldstr "b = "
                call void [mscorlib]System.Console::Write(string)
                ldfld int64 MyVT::b
                call void [mscorlib]System.Console::WriteLine(int64)

                ldstr "c = "
                call void [mscorlib]System.Console::Write(string)
                ldfld int16 MyVT::c
                call void [mscorlib]System.Console::WriteLine(int32)

                ldstr "--------"
                call void [mscorlib]System.Console::WriteLine(string)
                ret
        }
}

.method public static void Exec()
{
        .entrypoint
        .locals init(valuetype MyVT myvt, string Blob)
        ldloca.s myvt
        dup
        dup
        dup
        dup

        call instance void MyVT::PrintFields()

        ldstr bytearray(01 00 00 00 02 00 00 00 00 00 00 00 03 00
                        04 00 00 00 05 00 00 00 00 00 00 00 06 00)
        dup
        stloc.1

        ldc.i4.0
        call instance void MyVT::Init(string,int32)

        call instance void MyVT::PrintFields()
        
        ldloc.1
        sizeof MyVT
        call instance void MyVT::Init(string,int32)

        call instance void MyVT::PrintFields()

        ret
}
//------------------------------------

There may be other similar applications of embedded blobs. Dealing with blobs (like 
the above sample) invariably involves unverifiable operations, so you can't do 
something truly malicious. More exactly, you can, but only in Full Trust mode, and in 
this mode you can do anything anyway.

To create an arbitrary blob, you can use ILASM (ldstr bytearray(...)) or 
Reflection.Emit (create a char[] array, fill it with goo, create a System.String 
object from it and use this string in EmitOpcode(LDSTR,string)).

Thanks,
Serge

-----Original Message-----
From: Erik Mork [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, January 14, 2003 8:21 PM
To: [EMAIL PROTECTED]
Subject: [ADVANCED-DOTNET] Binary data in the #US heap.


According to Serge Lidin (in Inside Microsoft .NET Il Assembler) the #US
stream is a blob heap that contains user-defined strings.  He goes on to
say that "...the #US heap can store not only Unicode strings but any binary
object, which opens some intriguing possibilities."  What "intruiging
possibilities" might he be referring to here?  Unfortunately, I am unable
to find another reference to this in the book.

My questions:
1) Does anyone know why it would be useful to embed "custom" binary data
into the #US stream?
2) How might one go about this?  Recovering the data from the stream would
appear to be a straight forward (if unmanaged) task.  However, embedding
the data seems more difficult.  The binary data would need to be baked into
the metadata...  What might be the best way to get the data into an
assembly's metadata (Rotor? Some reflection technique that I am unaware
of?)?

My thanks to anyone who can help me with these problems.  They have been
bugging me for a while.

-Erik

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to