Je suis un peu un problème et, les autres questions ici ne m'a pas beaucoup aidé beaucoup.
Je suis un étudiant en sécurité et j'essaie d'écrire un crypter pour un projet. Pour ceux qui ne savent pas ce que vous pouvez lire ici. http://www.gamekiller.net /Tutorials-guides/17187-Tut-making-CryPter-vb6-utilisant-rc4.html P>
Quoi qu'il en soit, une explication rapide, les crypters sont des programmes destinés à contourner des antivirus en cryptant un programme, puis apposer un "talon" qui est un programme qui le déchiffre, sur le devant. J'ai une question très gênante avec la fractionnement de mon fichier. P>
La grande gêne est que je dois mettre l'exécutable crypté dans un tableau d'octets, car les cordes tuent certains personnages de mon exécutable crypté, ce qui la rend inutilisable. Pour aggraver les choses, je dois encore "diviser" l'EXE et, c'est là que le problème commence. P>
L'idée de base du talon est de: p>
J'ai tout ce qui fonctionne, sauf la partie fractionnée qui, est la plus agaçante. Comment puis-je diviser un tableau d'octets au délimiteur? Y a-t-il un moyen plus facile de faire cela? P>
Voici le code du talon que j'ai jusqu'à présent. P> merci pour toute aide. P > p>
6 Réponses :
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;
}
Votre implémentation semble très solide mais pourquoi retourne-t-il un octet [] [] et non un octet régulier []? J'ai seulement besoin du dernier champ, car il n'y a qu'un seul séparateur.
OK Question rapide, quelle serait la valeur que je devrais mettre dans le <>? Il devrait être d'octet [] juste?
dans séparé.last > (); Il devrait être d'octet [] juste? Ou n'est-ce pas autorisé à me donner un tableau d'octets?
Simple séparé (..). Dernier () ou peut utiliser SéparateAndgetlast (..) du code ci-dessus
La solution peut être juste ce que je cherche. Juste pour comprendre, que se séparait-t-il réellement? Quelle est son utilisation? Souhaitez-vous peut-être afficher un exemple d'utilisation ou commentant le code? Comment ferais-je les deux côtés du séparateur?
Votre approche a un certain nombre de défauts - vous lisez un octet entier [] en mémoire, mais le décryptage est un processus en continu, vous êtes donc inutilement de la mémoire. Deuxièmement, vous ne pouvez pas "diviser" un tableau (ou une chaîne, à cette affaire) dans le CLR. Lorsque vous divisez une chaîne CLR, il crée des copies, ce qui déteste la mémoire.
Essayez ceci: p> là, pas de tableaux d'octets désordonnés [] :) p> < / p>
Pas vraiment sûr comment faire la mise en œuvre de cela. Je n'ai jamais utilisé BianryReader avant. Je ne me soucie pas non plus de perdre la mémoire car elle ne fait rien d'intensité, en décryptant l'EXE et de le gérer avant de se terminer.
Je sais que je suis vraiment, vraiment tard à la fête, mais ... vous pouvez bien sûr modifier cela pour renvoyer facilement une liste si préférée. J'ai laissé des commentaires / des écrivies au cas où il serait utile ... Cela peut ne pas être le code le plus optimal / optimisé, mais fonctionne bien pour mon étui d'utilisation spécifique et je pensais que je partageais.
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();
}
voici la mienne. Cela ne fait que la scission une fois. Je n'ai fait aucune tentative de rendre performante. Testé (partiellement): P> 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
Pour les personnes qui souhaitent utiliser les octets en place, au lieu de les copier à de nouveaux tableaux, vous pouvez utiliser Arraysegment code> à cet effet.
Voici une implémentation: p>
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;
}
Voici la version générique
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;
}
Les réponses du code seulement sont découragées. Veuillez cliquer sur Modifier et ajouter des mots résumant comment votre code répond à la question ou expliquer peut-être comment votre réponse diffère de la réponse / réponses précédentes. Merci
Le codage de UTF8 n'est pas idéal. Vous pouvez obtenir des points de code unicode non valides. Vous devriez essayer d'itération à travers le tableau d'octets.
Comment changer ma chaîne en une matrice d'octet? Je dois changer mon délimiteur avant que je puisse rechercher cela, sauf si vous connaissez une fonction qui me permettra de rechercher à travers un tableau d'octets avec une valeur de chaîne. J'ai aussi corrigé le code, j'ai accidentellement utilisé une ancienne version stub que j'ai eue.
@ROGER Il jette une bande d'erreurs sur moi :( il dit que la chaîne n'a pas de méthode toarray ().