www.pudn.com > 29a_fu.zip > 29A-7.006


 
                            How to break the rules 
                           with the class libraries 
                               roy g biv / 29A 
 
 
 
About the author: 
 
Former  DOS/Win16  virus writer, author of several virus  families,  including 
Ginger  (see Coderz #1 zine for terrible buggy example, contact me for  better 
sources  ;),  and Virus Bulletin 9/95 for a description of what   they  called 
Rainbow.   Co-author  of  world's first virus using circular  partition  trick 
(Orsam, coded with Prototype in 1993).  Designer of world's first XMS swapping 
virus  (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is 
swapped  out).   Author of world's first virus using Thread Local Storage  for 
replication  (Shrug, see Virus Bulletin 6/02 for a description, but they  call 
it Chiton), world's first virus using Visual Basic 5/6 language extensions for 
replication  (OU812), world's first Native executable virus (Chthon),  world's 
first  virus  using process co-operation to prevent termination  (Gemini,  see 
Virus  Bulletin 9/02 for a description), world's first virus using polymorphic 
SMTP  headers  (Junkmail,  see Virus Bulletin 11/02 for  a  description),  and 
world's  first  viruses that can convert any data files to infectable  objects 
(Pretext).   Author  of  various retrovirus articles (eg see Vlad #7  for  the 
strings  that make your code invisible to TBScan).  Went to sleep for a number 
of years.  This is my first virus for .NET.  It is the world's first 32/64-bit 
parasitic EPO .NET virus. :) 
 
 
Object-oriented language programming 
 
At  the first look, object-oriented languages in the .NET framework (C#,  C++, 
JScript,  and Visual Basic) seem to be very strict.  There are no pointers  in 
JScript and Visual Basic, and they are limited in C# and C++.  Type conversion 
is also restricted. 
 
 
BitConverter class 
 
Imagine  that we have an array of bytes (because only a byte array is  allowed 
for the buffer when accessing files in the .NET framework).  We have read some 
bytes  from the file and now we want to check for the 'MZ' signature (assuming 
little-endian machine).  In C, we could use: 
 
    if (*((WORD *) &array[0]) == 0x5a4d) 
 
Can  we do that in JScript or Visual Basic?  No.  Can we do that in C++?  Yes, 
but  only for unmanaged arrays, which cannot be used with the class libraries. 
Can  we  do it in C#?  No (really yes, but it requires "Unsafe coding",  which 
causes other problems).  We can form the word from the array like this: 
 
    if (((array[1] << 8) + array[0]) == 0x5a4d)        //C#, C++, JScript 
    if (((array(1) * &h100) + array(0)) = &h5a4d) then 'Visual Basic 
 
but  that  requires lots of bytes of code each time to do that.   Fortunately, 
the class libraries contain a class that exposes methods for exactly this kind 
of  data access.  The class is called BitConverter, and the method we can  use 
here  is called ToInt16().  It takes two parameters: the array and the offset. 
So now our code can be replaced by: 
 
    if (BitConverter.ToInt16(array, 0) == 0x5a4d)     //C#, JScript 
    if (BitConverter::ToInt16(array, 0) == 0x5a4d)    //C++ 
    if (BitConverter.ToInt16(array, 0) = &h5a4d) then 'Visual Basic 
 
Nice.   The class exposes other methods, too, such as ToInt32() and ToInt64(), 
and also versions for unsigned numbers (ToUInt16(), etc). 
 
 
Marshal class 
 
Now we want to write large values into a byte array.  In C, we could use 
 
    *((DWORD *) &array[0]) = dword; 
 
In C#, C++, and JScript, we can store a dword in the array like this: 
 
    array[0] = (Byte) (dword); 
    array[1] = (Byte) (dword >> 8); 
    array[2] = (Byte) (dword >> 0x10); 
    array[3] = (Byte) (dword >> 0x18); 
 
In Visual Basic, we can store a dword in the array like this: 
 
    array(0) = dword mod &h100 
    array(1) = (dword \ &h100) mod &h100 
    array(2) = (dword \ &h10000) mod &h100 
    array(3) = (dword \ &h1000000) mod &h100 
 
but  that  requires  too many instructions and too many bytes  of  code.   The 
better  way  is to use the Marshal class.  It allows us to copy  data  between 
managed  data  types  (.NET base types) and unmanaged data types  (eg  process 
memory).   It can also copy from one managed type to another managed type, but 
this  use  is  not  documented.  The method that we can  use  here  is  called 
WriteInt32().   It takes three parameters: the array, the offset in the array, 
and the value.  So now our code can be replaced by: 
 
    Marshal.WriteInt32(array, 0, dword);  //C#, JScript 
    Marshal::WriteInt32(array, 0, dword); //C++ 
    Marshal.WriteInt32(array, 0, dword)   'Visual Basic 
 
Much better.  Accessing process memory is easy, too.  The Process class exists 
for that purpose.  Let's get our module handle: 
 
    IntPtr ourbase = Process.GetCurrentProcess().MainModule.BaseAddress;                //C# 
    IntPtr ourbase = Process::GetCurrentProcess()->get_MainModule()->get_BaseAddress(); //C++ 
    var ourbase : IntPtr = Process.GetCurrentProcess().MainModule.BaseAddress           //JScript 
    dim ourbase as IntPtr : Process.GetCurrentProcess().MainModule.BaseAddress          'Visual Basic 
 
Great!  But what's an IntPtr? 
 
 
Marshal class again 
 
The  IntPtr  type is a special managed type whose size  is  platform-specific. 
That means that it is 32 bits large on a 32-bit platform, and 64-bits large on 
a 64-bit platform.  The Marshal methods require an IntPtr as the object to use 
for  reading  and writing unmanaged memory.  IntPtrs do not support  operators 
such  as  + and - (they are like void * in C and C++), but since  the  Marshal 
methods require an offset, this is usually okay.  For example, we can read the 
lfanew field without trouble: 
 
    Int32 lfanew = Marshal.ReadInt32(ourbase, 0x3c);       //C# 
    Int32 lfanew = Marshal::ReadInt32(ourbase, 0x3c);      //C++ 
    var lfanew : Int32 = Marshal.ReadInt32(ourbase, 0x3c)  //JScript 
    dim lfanew as Int32 : Marshal.ReadInt32(ourbase, &h3c) 'Visual Basic 
 
and then read bytes in the PE header: 
 
    Int32 tlsrva = Marshal.ReadInt32(ourbase, lfanew + 0xc0);                //C# 
    Int32 tlsrva = Marshal::ReadInt32(ourbase, lfanew + 0xc0);               //C++ 
    var tlsrva : Int32 = Marshal.ReadInt32(ourbase, lfanew + 0xc0)           //JScript 
    dim tlsrva as Int32 : tlsrva = Marshal.ReadInt32(ourbase, lfanew + &hc0) 'Visual Basic 
 
But  what  if we want to copy any number of bytes?  There is a Copy()  method, 
and  it  takes four parameters: the source array, the destination  array,  the 
offset  in  destination array, and the number of bytes to copy.  It  does  not 
support  an offset in the source array, so we need to find a way to apply  the 
+  operator  to  a IntPtr.  Fortunately, the Marshal class  exposes  a  method 
called  ReadIntPtr(), which can convert a Int32 to a IntPtr, but this usage is 
also  not  documented.  To make our pointer, we convert our old IntPtr into  a 
Int32  by  using the ToInt32() method, then add the value that we  need,  then 
pass the result to the ReadIntPtr() method, using an offset of 0: 
 
    IntPtr tlsva = Marshal.ReadIntPtr(ourbase.ToInt32() + tlsdata, 0);               //C# 
    IntPtr tlsva = Marshal::ReadIntPtr(__box(ourbase.ToInt32() + tlsdata), 0);       //C++ 
    var tlsva : IntPtr = Marshal.ReadIntPtr(ourbase.ToInt32() + tlsdata, 0)          //JScript 
    dim tlsva as IntPtr : tlsva = Marshal.ReadIntPtr(ourbase.ToInt32() + tlsdata, 0) 'Visual Basic 
 
For 64-bit platforms, there is a ToInt64() method, and the ReadIntPtr() method 
can  also  convert  an Int64 to an IntPtr.  Notice the use of __box  for  C++. 
This  is required to convert a value into a managed object, which can then  be 
passed to the class libraries. 
 
Now  we can use the Copy() method to copy bytes from the process memory to our 
array.  Let's copy 0x29a bytes ;) to offset 6: 
 
    Marshal.Copy(tlsva, array, 6, 0x29a);  //C#, JScript 
    Marshal::Copy(tlsva, array, 6, 0x29a); //C++ 
    Marshal.Copy(tlsva, array, 6, &h29a);  'Visual Basic 
 
 
TLS and MSIL 
 
I  thought  to make an interesting W32/MSIL hybrid by using TLS to  write  the 
MSIL  RVA in the PE header at runtime, but when the MSIL code is run, it fails 
the StrongName signature verification.  Then I tried storing a hard-coded fake 
RVA  in the file, and setting it correctly at runtime, but the MSIL code won't 
run in that case.  Finally, I stored the correct RVA and size in the file, but 
if  TLS  code runs on exit, then one of the MSIL dlls waits infinitely for  an 
object  that never signals and the application won't terminate.  So don't  use 
TLS in MSIL files unless you can solve one of these problems. ;) 
 
 
GetProcAddress() 
 
.NET  files import functions in a way that is simlar to Windows files.   There 
are  AssemblyRefs  which  are  the DLL names, and  MemberRefs  which  are  the 
function  names (there  are also TypeRefs, and they hold the class names,  but 
they  have  no equivalent).  Let us imagine that we want to display our  image 
base, using only standard library functions (mscorlib).  The image base is the 
BaseAddress  property of the ProcessModule class.  The ProcessModule class  is 
returned  by the MainModule property of the Process class.  The Process  class 
is  in the System.Diagnostics  namespace.  The System.Diagnostics namespace is 
exported  by system.dll.  Since system.dll is not a standard library, we  need 
to  find  how  to load system.dll and get access to its methods,  but  without 
using  any  function from system.dll to do that.  We also have to rely on  the 
GetType()  method, instead of casting the result, because casts use references 
to  the  dll  that exports the class.  The .NET  equivalent  of  LoadLibrary() 
requires  the full path of the file to load, if the file is not in the current 
directory  (this  is  similar to LoadLibrary()).  System.dll is  in  the  .NET 
system  directory (which is not the same as the Windows system directory),  so 
we  need  to find the .NET system directory.  We can get the system  directory 
from  the full path of mscorlib.dll (equivalent to getting the Windows  system 
directory  from the module filename of kernel32.dll).  I don't know about  any 
.NET equivalent of GetSystemDirectory(). 
 
Here is the code in C#: 
 
    Type t = typeof(System.Object); //get handle to mscorlib.dll 
    Assembly a = t.Assembly;        //get its assembly 
    String s = a.CodeBase;          //get full path of mscorlib.dll 
 
Here is the code in C++: 
 
    Type *t = __typeof(System::Object); //get handle to mscorlib.dll 
    Assembly *a = t->Assembly;          //get its assembly 
    String *s = a->CodeBase;            //get full path of mscorlib.dll 
 
Here is the code in JScript: 
 
    var t : Type = System.Object.GetType() //get handle to mscorlib.dll 
    var a : Assembly = t.Assembly          //get its assembly 
    var s : String = a.CodeBase            //get full path of mscorlib.dll 
 
Here is the code in Visual Basic: 
 
    dim o as new Object                  'create an instance of System.Object 
    dim t as Type : t = o.GetType()      'get handle to mscorlib.dll 
    dim a as [Assembly] : a = t.Assembly 'get its assembly 
    dim s as String : s = a.CodeBase     'get full path of mscorlib.dll 
 
Now  that  we  have  the full path of mscorlib.dll, we have  the  .NET  system 
directory.   We simply replace "mscorlib.dll" with "system.dll", then load the 
system.dll.  This is the .NET equivalent of LoadLibrary(). 
 
Here is the code in C#: 
 
    s = s.Replace("mscorlib.dll", "system.dll"); //get full path of system.dll 
    a = Assembly.LoadFrom(s);                    //load assembly from file 
 
Here is the code in C++: 
 
    s = s->Replace("mscorlib.dll", "system.dll"); //get full path of system.dll 
    a = Assembly::LoadFrom(s);                    //load assembly from file 
 
Here is the code in JScript: 
 
    s = s.Replace("mscorlib.dll", "system.dll") //get full path of system.dll 
    a = Assembly.LoadFrom(s)                    //load assembly from file 
 
Here is the code in Visual Basic: 
 
    s = s.Replace("mscorlib.dll", "system.dll") 'get full path of system.dll 
    a = [Assembly].LoadFrom(s)                  'load assembly from file 
 
An  assembly is the .NET equivalent of a module handle.  Using an assembly, we 
can  get  the  address of any method, by using the GetType()  method  and  the 
GetMethod() method.  This is the .NET equivalent of GetProcAddress(). 
 
Here is the code in C#: 
 
    t = a.GetType("System.Diagnostics.Process");     //get class (Process) 
    MethodInfo m = t.GetMethod("GetCurrentProcess"); //get method interface 
 
Here is the code in C++: 
 
    t = a->GetType("System.Diagnostics.Process");      //get class (Process) 
    MethodInfo *m = t->GetMethod("GetCurrentProcess"); //get method interface 
 
Here is the code in JScript: 
 
    t = a.GetType("System.Diagnostics.Process")           //get class (Process) 
    var m : MethodInfo = t.GetMethod("GetCurrentProcess") //get method interface 
 
Here is the code in Visual Basic: 
 
    t = a.GetType("System.Diagnostics.Process")                'get class (Process) 
    dim m as MethodInfo : m = t.GetMethod("GetCurrentProcess") 'get method interface 
 
Now we can call our method. 
 
Here is the code in C#: 
 
    Object o = m.Invoke(null, null); //call GetCurrentProcess() 
 
Here is the code in C++: 
 
    Object *o = m->Invoke(0, 0); //call GetCurrentProcess() 
 
Here is the code in JScript: 
 
    var o : Object = m.Invoke(null, null) //call GetCurrentProcess() 
 
Here is the code in Visual Basic: 
 
    o = m.Invoke(nothing, nothing) 'call GetCurrentProcess() 
 
Okay, so now we know how to call a method dynamically. 
 
Here is the rest of the code in C#: 
 
    t = o.GetType();                              //get class (Process) 
    PropertyInfo p = t.GetProperty("MainModule"); //get property interface 
    o = p.GetValue(o, null);                      //get MainModule value 
    t = o.GetType();                              //get class (ProcessModule) 
    p = t.GetProperty("BaseAddress");             //get property interface 
    o = p.GetValue(o, null);                      //get BaseAddress value 
 
Here is the rest of the code in C++: 
 
    t = o->GetType();                               //get class (Process) 
    PropertyInfo *p = t->GetProperty("MainModule"); //get property interface 
    o = p->GetValue(o, 0);                          //get MainModule value 
    t = o->GetType();                               //get class (ProcessModule) 
    p = t->GetProperty("BaseAddress");              //get property interface 
    o = p->GetValue(o, 0);                          //get BaseAddress value 
 
Here is the rest of the code in JScript: 
 
    t = o.GetType()                                    //get class (Process) 
    var p : PropertyInfo = t.GetProperty("MainModule") //get property interface 
    o = p.GetValue(o, null)                            //get MainModule value 
    t = o.GetType()                                    //get class (ProcessModule) 
    p = t.GetProperty("BaseAddress")                   //get property interface 
    o = p.GetValue(o, null)                            //get BaseAddress value 
 
Here is the rest of the code in Visual Basic: 
 
    t = o.GetType()                                         'get class (Process) 
    dim p as PropertyInfo : p = t.GetProperty("MainModule") 'get property interface 
    o = p.GetValue(o, nothing)                              'get MainModule value 
    t = o.GetType()                                         'get class (ProcessModule) 
    p = t.GetProperty("BaseAddress")                        'get property interface 
    o = p.GetValue(o, nothing)                              'get BaseAddress value 
 
So much code for such a simple thing.  Anyway... 
 
Let's print the value in C#: 
 
    Int32 i = ((IntPtr) o).ToInt32(); //convert to Int32 
    Console.WriteLine("{0:x}", i);    //display it in hex 
 
Let's print the value in C++: 
 
    Int32 i = dynamic_cast(o)->ToInt32(); //convert to Int32 
    Console.WriteLine("{0:x}", __box(i));           //display it in hex 
 
Let's print the value in JScript: 
 
    var i : Int32 = o.ToInt32()   //convert to Int32 
    Console.WriteLine("{0:x}", i) //display it in hex 
 
Let's print the value in Visual Basic: 
 
    dim i as Int32 : i = DirectCast(o, IntPtr).ToInt32() 'convert to Int32 
    Console.WriteLine("{0:x}", i)                        'display it in hex 
 
This  code  also requires the #US stream, because it contains strings.  It  is 
possible  to build strings dynamically to avoid creating the stream, but  that 
requires  still more code.  However, if you need to access external functions, 
then this is how it is done. 
 
 
Building strings dynamically 
 
In  the object-oriented world, type conversion usually happens  transparently. 
This  means that a Byte value can be converted to a Char simply by storing the 
Byte  value  in the Char variable.  We can make strings by storing Bytes in  a 
Char  array.   We  can write multiple Bytes at a time with the  Marshal  class 
methods, such as WriteInt32() and WriteInt64().  Here is an example of that: 
 
    Char[] ourstr = new Char[8]; Marshal.WriteInt64(ourstr, 0, 0x4139322f626772);       //C# 
    Char ourstr __gc[] = new Char[8]; Marshal::WriteInt64(ourstr, 0, 0x4139322f626772); //C++ 
    var ourstr : Char[] = new Char[8] : Marshal.WriteInt64(ourstr, 0, 0x4139322f626772) //JScript 
    dim ourstr(8) as Char : Marshal.WriteInt64(ourstr, 0, &h4139322f626772)             'Visual Basic 
 
Warning:  the  JScript .NET Compiler version 7.00.9502 (.NET  v1.0)  7.10.2292 
(.NET  v1.1  final  beta)  and 7.10.3052 (.NET v1.1) has  a  bug  with  64-bit 
numbers,  so the last byte is either lost or damaged (becomes 0x4139322f626774 
in the example). 
 
I  have not found any method to convert multiple Bytes to a character  string, 
without an array. 
 
 
Greets to friendly people (A-Z): 
 
Active - Benny - Obleak - Prototype - Ratter - Ronin - RT Fishel - 
The Gingerbread Man - Ultras - Vecna - VirusBuster - Whitehead 
 
 
rgb/29A mar 2003 
iam_rgb@hotmail.com