2012-03-18 60 views
6

Tôi đang gặp vấn đề và các câu hỏi khác ở đây không giúp ích nhiều cho tôi.Tách một mảng byte tại dấu phân cách

Tôi là một sinh viên bảo mật và tôi đang cố gắng viết một crypter cho một dự án. Đối với những người không biết những gì nó là bạn có thể đọc lên ở đây. http://www.gamekiller.net/tutorials-guides/17187-tut-making-crypter-vb6-using-rc4.html

Dù sao, giải thích nhanh, crypters là chương trình có nghĩa là bỏ qua các chương trình diệt virus bằng cách mã hóa chương trình và sau đó gắn "sơ khai" là chương trình giải mã nó ở mặt trước. Tôi đang gặp vấn đề rất khó chịu khi chia nhỏ tệp của mình.

Sự khó chịu lớn nhất là tôi phải đặt tệp thực thi được mã hóa vào một mảng byte, vì các chuỗi ký tự giết các ký tự nhất định trong tệp thực thi được mã hóa của tôi, làm cho nó không thể thực hiện được. Để làm cho vấn đề tồi tệ hơn tôi vẫn phải "tách" exe và, đây là nơi rắc rối bắt đầu.

Ý tưởng cơ bản của sơ khai là:

  • Lấy con đường exe hiện
  • Đọc tất cả các byte thông qua File.ReadAllytes
  • Chia file tại delimiter, "EVILDELIMITER"
  • Lấy trường cuối cùng (Vì đó là EXE được mã hóa)
  • Giải mã nó bằng cách sử dụng RC4
  • Chạy bằng RunPE.

Tôi có mọi thứ hoạt động ngoại trừ phần tách, là phần gây phiền nhiễu nhất. Làm thế nào để phân chia một mảng byte tại dấu phân cách? Có cách nào dễ hơn để thực hiện việc này không?

Đây là mã cho bài tôi có cho đến nay.

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

Cảm ơn bạn đã được trợ giúp.

+1

Mã hóa thành UTF8 không lý tưởng. Bạn có thể nhận được codepoints unicode không hợp lệ. Bạn nên thử lặp qua mảng byte. – Polynomial

+0

Làm cách nào để thay đổi chuỗi của tôi thành mảng byte? Tôi cần phải thay đổi dấu phân cách của mình trước khi tôi có thể tìm kiếm nó trừ khi bạn biết một hàm sẽ cho phép tôi tìm kiếm thông qua một mảng byte với một giá trị chuỗi. Tôi cũng đã sửa mã, tôi vô tình sử dụng một phiên bản cũ mà tôi có. – redcodefinal

+0

@Roger Nó ném một loạt các lỗi vào tôi: (Nó nói chuỗi không có một ToArray () phương pháp – redcodefinal

Trả lời

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

Thực hiện của bạn có vẻ rất vững chắc nhưng, tại sao Seperate trả về một byte [] [] và không phải là một byte thông thường Tôi chỉ cần một lĩnh vực cuối cùng, vì chỉ có một người seperator – redcodefinal

+0

sử dụng riêng biệt (..). Last() –

+0

Cảm ơn bạn, hãy để tôi thử điều này thật nhanh: D – redcodefinal

0

Cách tiếp cận của bạn có một số sai sót - bạn đang đọc toàn bộ Byte [] vào bộ nhớ, nhưng giải mã là quá trình có thể phát trực tuyến, do đó bạn không cần lãng phí bộ nhớ. Thứ hai, bạn không thể "tách" một mảng (hoặc một chuỗi, cho vấn đề đó) trong CLR. Khi bạn tách một chuỗi CLR nó tạo ra các bản sao, mà lãng phí bộ nhớ.

Hãy thử điều này:

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 
} 

Ở đó, không có byte lộn xộn [] mảng :)

+0

Không thực sự chắc chắn làm thế nào để đi về việc thực hiện điều này. d BianryReader trước đây. Tôi cũng không thực sự quan tâm đến lãng phí bộ nhớ vì nó không làm bất cứ điều gì chuyên sâu, chỉ giải mã các exe và chạy nó trước khi chấm dứt chính nó. – redcodefinal

1

Tôi biết tôi thực sự, thực sự muộn để đảng, nhưng ... Bạn có thể thay đổi tất nhiên điều này để trả về một Danh sách dễ dàng nếu được ưu tiên. Tôi để lại bình luận/writelines trong trường hợp nó sẽ hữu ích ... Đây có thể không phải là tối ưu nhất/tối ưu hóa mã nhưng hoạt động tốt cho trường hợp sử dụng cụ thể của tôi và tôi nghĩ rằng tôi sẽ chia sẻ.

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(); 
    } 
Các vấn đề liên quan