Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split a byte array at a delimiter

Tags:

c#

security

I'm having a bit of an issue and, the other questions here didn't help me much.

I am a security student and I am trying to write a crypter for a project. For those who don't know what it is you can read up on here. http://www.gamekiller.net/tutorials-guides/17187-tut-making-crypter-vb6-using-rc4.html

Anyways, a quick explanation, crypters are programs meant to bypass antiviruses by encrypting a program and then affixing a "stub" which is a program that decrypts it, on the front. I'm having a very annoying issue with splitting my file up.

The big annoyance is that I have to put the crypted executable into a byte array, since strings kill certain characters in my crypted executable, making it unexecutable. To make matters worse I still have to "split" the exe and, this is where the trouble begins.

The basic idea of the stub is to:

  • Get the current exe path
  • Read all the bytes through File.ReadAllytes
  • Split the file at the delimiter, "EVILDELIMITER"
  • Get the last field (Since thats the crypted EXE)
  • Decrypt it using RC4
  • Run using RunPE.

I have everything working except the splitting part which, is the most annoying. How do I split a byte array at the delimiter? Is there an easier way to do this?

Here's the code for the stub I have so far.

public void main()
{
    string outpath = RandomString(8) + ".exe";
    byte[] key = { 33, 44, 55, 66, 77 };
    string apppath = Assembly.GetEntryAssembly();
    byte[] exe = File.ReadAllBytes(apppath);
    string strseperate = "EVILSEPERATOREVIL";
    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    byte[] seperator = encoding.GetBytes(strseperate);
    //Split code should go here

    exe = Decrypt(key, encrypted);
    Process.Start(outpath);
}

Thanks for any help.

like image 719
redcodefinal Avatar asked Mar 18 '12 00:03

redcodefinal


2 Answers

For people who want to use the bytes in-place, instead of copying them to new arrays, you can use ArraySegment for this purpose.

Here's an implementation:

private static List<ArraySegment<byte>> Split(byte[] arr, byte[] delimiter)
{
    var result = new List<ArraySegment<byte>>();
    var segStart = 0;
    for (int i = 0, j = 0; i < arr.Length; i++)
    {
        if (arr[i] != delimiter[j])
        {
            if (j == 0) continue;
            j = 0;
        }

        if (arr[i] == delimiter[j])
        {
            j++;
        }

        if (j == delimiter.Length)
        {
            var segLen = (i + 1) - segStart - delimiter.Length;
            if (segLen > 0) result.Add(new ArraySegment<byte>(arr, segStart, segLen));
            segStart = i + 1;
            j = 0;
        }
    }

    if (segStart < arr.Length)
    {
        result.Add(new ArraySegment<byte>(arr, segStart, arr.Length - segStart));
    }

    return result;
}
like image 171
Ahmad Ibrahim Avatar answered Oct 29 '22 07:10

Ahmad Ibrahim


byte[] SeparateAndGetLast(byte[] source, byte[] separator)
{
  for (var i = 0; i < source.Length; ++i)
  {
     if(Equals(source, separator, i))
     {
       var index = i + separator.Length;
       var part = new byte[source.Length - index];
       Array.Copy(source, index, part, 0, part.Length);
       return part;
     }
  }
  throw new Exception("not found");
}

public static byte[][] Separate(byte[] source, byte[] separator)
{
    var Parts = new List<byte[]>();
    var Index = 0;
    byte[] Part;
    for (var I = 0; I < source.Length; ++I)
    {
        if (Equals(source, separator, I))
        {
            Part = new byte[I - Index];
            Array.Copy(source, Index, Part, 0, Part.Length);
            Parts.Add(Part);
            Index = I + separator.Length;
            I += separator.Length - 1;
        }
    }
    Part = new byte[source.Length - Index];
    Array.Copy(source, Index, Part, 0, Part.Length);
    Parts.Add(Part);
    return Parts.ToArray();
}

bool Equals(byte[] source, byte[] separator, int index)
{
  for (int i = 0; i < separator.Length; ++i)
    if (index + i >= source.Length || source[index + i] != separator[i])
      return false;
  return true;
}
like image 38
Serj-Tm Avatar answered Oct 29 '22 07:10

Serj-Tm