Skip to content

Instantly share code, notes, and snippets.

@stevemk14ebr
Last active May 4, 2023 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevemk14ebr/7c1418b61d09726671e2681454153a98 to your computer and use it in GitHub Desktop.
Save stevemk14ebr/7c1418b61d09726671e2681454153a98 to your computer and use it in GitHub Desktop.
FindPattern.go
package main
func getPatternSize(signature []byte) int {
// c = 2 * b + (b - 1) . 2 chars per byte + b - 1 spaces between
return (len(signature) + 1) / 3
}
func getBits(x byte) byte {
// ascii numbers to byte
if x >= '0' && x <= '9' {
return x - '0'
} else { // ascii letters to hex byte
// & 0xDF converts lowercase ascii to uppercase
return (x & 0xDF) - 'A' + 0xa
}
}
// signature must use ? as mask for nibbles, have a space between each byte, must not prefix bytes with 0x or \x, and be ascii.
// upper and lowercase supported.
func findPattern(signature []byte, data []byte) []uint64 {
matches := make([]uint64, 0)
patternSize := getPatternSize(signature)
for i := range data {
sigIdx := 0
for sigIdx < patternSize && i+sigIdx < len(data) {
sigPatIdx := sigIdx * 3
sigHi := getBits(signature[sigPatIdx:][0]) << 4
sigLo := getBits(signature[sigPatIdx:][1])
datByt := data[i+sigIdx:][0]
// check for ex: A?
if signature[sigPatIdx+1] == '?' {
sigLo = datByt & 0xF
}
if signature[sigPatIdx] == '?' {
sigHi = datByt & 0xF0
}
if datByt != (sigHi | sigLo) {
break
}
sigIdx += 1
}
if sigIdx >= patternSize {
matches = append(matches, uint64(i))
}
}
return matches
}
func main() {
haystack := []byte{0xAA, 0xBD, 0xCC, 0xDD, 0xCA, 0xBB, 0xCC}
signature := "AA B? ?? ?? ?A BB CC"
ptr := findPattern([]byte(signature), haystack)
println(ptr)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment