Skip to content

Instantly share code, notes, and snippets.

@pigeonhands
Last active December 23, 2017 04:09
Show Gist options
  • Save pigeonhands/6dd3e62266f721ee6422ff9a196aafab to your computer and use it in GitHub Desktop.
Save pigeonhands/6dd3e62266f721ee6422ff9a196aafab to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
/// <summary>
/// BahNahNah
/// Example sig:
/// 01 02 ?3 04
/// will match with
/// 01 02 A3 04
/// 01 02 03 04
/// but not with
/// 01 02 3A 04
/// A0 02 3A 04
/// etc.
/// </summary>
static unsafe class ByteScan {
/// <summary>
// If you want best performance, use CompileSig once, then call Scan on the sig.
/// </summary>
/// <param name="scan">Bytes to scan</param>
/// <param name="sig">Byte sig</param>
/// <returns>Index of scan array where pattern match. -1 on failure.</returns>
public static int GetIndexOfSig(byte[] scan, string sig) => CompileSig(sig).Scan(scan);
public static Sig CompileSig(string sig) {
var cArray = sig.Split(' ').Select(c => {
ushort flag = 0;
if (c == "??") {
return flag;
}
if (c[0] != '?') { //LEFT
flag |= 0xF0;
}
if (c[1] != '?') { //RIGHT
flag |= 0x0F;
}
c = c.Replace('?', '0');
flag |= (ushort)(Convert.ToByte(c, 16) << 8);
return flag;
}).ToArray();
return new Sig(cArray);
}
public static Sig CompileSig(byte[] arr) => new Sig(arr.Select(x => (ushort)((x << 8) | 0xFF)).ToArray());
public class Sig {
private ushort[] SigFlagHold;
public Sig(ushort[] _sc) {
SigFlagHold = _sc;
}
public int Scan(byte[] scan) {
var SigFlags = SigFlagHold;
if (scan.Length < SigFlagHold.Length)
return -1;
fixed (byte* scrArrayPtr = &scan[0]) {
int len = SigFlags.Length;
var end = (scrArrayPtr + scan.Length - len + 1);
ushort flag = SigFlags[0];
for (var scrEnum = scrArrayPtr; scrEnum != end; scrEnum++, flag = SigFlags[0]) {
for (int i = 0; (*(scrEnum + i) & flag) == (flag >> 8); flag = SigFlags[++i]) {
if (i == len - 1) {
return (int)(scrEnum - scrArrayPtr);
}
}
}
}
return -1;
}
}
}
extern "C" __declspec(dllexport) int ScanNative(char* source, int sourceLen, unsigned short* pattern, int patternLen) {
unsigned short flag = pattern[0];
for (int sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++, flag = pattern[0]) {
for (int i = 0; (char)(source[i + sourceIndex] & flag) == (char)(flag >> 8); flag = pattern[++i]) {
if (i == patternLen - 1)
return sourceIndex;
}
}
return -1;
}
@KektJ
Copy link

KektJ commented Aug 17, 2017

Excellent 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment