Last active
May 4, 2023 16:48
-
-
Save stevemk14ebr/7c1418b61d09726671e2681454153a98 to your computer and use it in GitHub Desktop.
FindPattern.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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