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