我遇到了一些问题,这里的其他问题对我没什么帮助。
我是一名安全学生,我正在尝试为项目编写一个管章。对于那些不知道它是什么的人,你可以在这里阅读。 http://www.gamekiller.net/tutorials-guides/17187-tut-making-crypter-vb6-using-rc4.html
无论如何,快速解释一下,加密程序是指通过加密程序然后在前面粘贴“存根”(这是一个解密它的程序)来绕过防病毒的程序。我分割文件时遇到了一个非常烦人的问题。
最大的烦恼是我必须将加密的可执行文件放入一个字节数组中,因为字符串会杀死我的加密可执行文件中的某些字符,使其无法执行。更糟糕的是,我仍然需要“拆分”exe,这就是麻烦开始的地方。
存根的基本思想是:
除了分裂部分之外我一切都在工作,这是最烦人的。如何在分隔符处拆分字节数组?有更简单的方法吗?
这是我到目前为止存根的代码。
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);
}
感谢您的帮助。
答案 0 :(得分:6)
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;
}
答案 1 :(得分:1)
我知道我真的,非常迟到了派对,但是......如果愿意的话,你当然可以修改它以便轻松返回List。我留下了评论/写条款,以防它有用...这可能不是最优/优化的代码,但适用于我的特定用例,我想我会分享。
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();
}
答案 2 :(得分:0)
你的方法有很多缺陷 - 你正在将整个Byte []读入内存,但解密是一个可流动的过程,所以你不必要地浪费内存。其次,你不能在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 []数组:)
答案 3 :(得分:0)
这是我的。它只进行了一次分割。我没有试图让它变得高效。
public static byte[][] Split(this byte[] composite, byte[] seperator)
{
bool found = false;
int i = 0;
for (; i < composite.Length - seperator.Length; i++)
{
var compositeView = new byte[seperator.Length];
Array.Copy(composite, i, compositeView, 0, seperator.Length);
found = compositeView.SequenceEqual(seperator);
if (found) break;
}
if(found == false)
{
return null;
}
var component1Length = i;
var component1 = new byte[component1Length];
var component2Length = composite.Length - seperator.Length - component1Length;
var component2 = new byte[component2Length];
var component2Index = i + seperator.Length;
Array.Copy(composite, 0, component1, 0, component1Length);
Array.Copy(composite, component2Index, component2, 0, component2Length);
return new byte[][]
{
component1,
component2
};
}
测试(部分):
byte[] b1 = new byte[] { 1, 2, 3, 4, 1, 1, 5 };
byte[] b2 = new byte[] { 1, 1 };
var parts1 = b1.Split(b2); // [1,2,3,4],[5]
byte[] b3 = new byte[] { 1, 1, 3, 4, 4, 1, 5 };
byte[] b4 = new byte[] { 1, 1 };
var parts2 = b3.Split(b4); // [],[3,4,4,1,5]
byte[] b5 = new byte[] { 0, 0, 3, 4, 4, 1, 1 };
byte[] b6 = new byte[] { 1, 1 };
var parts3 = b5.Split(b6); // [0,0,3,4,4],[]
byte[] b7 = new byte[] { 1, 2, 3, 4, 5 };
byte[] b8 = new byte[] { 1, 2, 3, 4 };
var parts4 = b7.Split(b8); // [],[5]
byte[] b9 = new byte[] { 1, 2, 3, 4, 5 };
byte[] b0 = new byte[] { 2, 3, 4, 5 };
var parts5 = b9.Split(b0); // [1],[]
byte[] c1 = new byte[] { 1, 2, 3, 4, 5 };
byte[] c2 = new byte[] { 6 };
var parts6 = c1.Split(c2); // null
答案 4 :(得分:0)
对于想要就地使用字节而不是将其复制到新数组的人,您可以使用ArraySegment
来实现此目的。
这是一个实现:
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]) continue;
if (j++ != delimiter.Length - 1) continue;
var segLen = i - segStart - (delimiter.Length - 1);
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;
}
答案 5 :(得分:0)
这是通用版本
public static IList<ArraySegment<T>> Split<T>(this T[] arr, params T[] delimiter)
{
var result = new List<ArraySegment<T>>();
var segStart = 0;
for (int i = 0, j = 0; i < arr.Length; i++)
{
//If is match
if (arr.Skip(i).Take(delimiter.Length).SequenceEqual(delimiter))
{
//Skip first empty segment
if (i > 0)
{
result.Add(new ArraySegment<T>(arr, segStart, i - segStart));
}
//Reset
segStart = i;
}
}
//Add last item
if (segStart < arr.Length)
{
result.Add(new ArraySegment<T>(arr, segStart, arr.Length - segStart));
}
return result;
}