mirror of
https://github.com/lukaszraczylo/go-obfuscation.git
synced 2026-10-18 06:17:52 +00:00
Bug fixes, new transform passes, test coverage, and CI tooling
Bug fixes: - pclntab/rtcorrupt_linux.go: remove duplicate mprotectRW/mprotectRO that broke GOOS=linux builds (they're defined in rtcorrupt_unsafe.go for darwin+linux). - pclntab/pclntab.go: readUint now guards against negative offset (previously panicked via slice out-of-range). - integrity/integrity.go: SetExpectedHashHex now validates length 64 up-front and reports byte index on parse error; added ClearExpectedHash for runtime toggling and test isolation. - transform/mba.go: mbaApplyBinOp used strings.Index on first match instead of the current match; replaced with FindAllStringSubmatchIndex + two-pass replacement. - transform/transform.go: removed duplicate unconditional SplitLongStrings call. New transform passes (CLI flags + Config fields + pipeline wiring): - splice, constblind, mba, fakesigs, funcsplit, bbreorder — all default true. Cleanup: - strenc/keyderive.go: removed unused DeriveFromBinary + buildSeed. - transform/transform.go: removed unused trimFirstParen. - antidebug_hook_darwin.go: modernized readAddr to unsafe.Slice with noescape pattern (vet-safe). Tests (10 packages, 116 tests, all green): - internal/transform: 28 tests covering every pipeline stage. - pkg/strenc: 7 tests for key derivation + XOR stream. - pkg/stringcrypt: 7 tests for CFB round-trip + tamper detection. - pkg/pageman: 14 tests for alignment + mprotect guards. - pkg/integrity: 14 tests including ClearExpectedHash teardown. - pkg/pclntab: 12 tests including readUint negative-offset guard. - pkg/antisandbox: 6 tests for hostname/MAC lists + Check delegation. - pkg/antiemul: 6 tests (1 skipped on non-Linux) for no-panic + timing. Tooling: - Makefile: added test, verify, lint, fmt, vet targets. vet uses -unsafeptr=false (only legitimate uintptr→pointer is the darwin antidebug hook). fmt skips build/ (generated). - README.md: test coverage table + Makefile target reference.
This commit is contained in:
+55
-21
@@ -152,42 +152,60 @@ var mbaOrIdentities = []mbaIdentity{
|
||||
}
|
||||
|
||||
func mbaApplyBinOp(line string, re *regexp.Regexp, identities []mbaIdentity, rng *rand.Rand) string {
|
||||
// Track positions already transformed to avoid double-transforming
|
||||
var transformed []struct{ start, end int }
|
||||
// Use FindAllStringSubmatchIndex so we know the exact position of each match
|
||||
// in the line. FindStringIndex on the match alone only gives a position relative
|
||||
// to the match, not the line, which previously caused us to mis-attribute
|
||||
// already-transformed ranges (the bug: strings.Index(line, match) returns the
|
||||
// first occurrence, not the current one).
|
||||
type range_ struct{ start, end int }
|
||||
var transformed []range_
|
||||
|
||||
return re.ReplaceAllStringFunc(line, func(match string) string {
|
||||
loc := re.FindStringIndex(match)
|
||||
if loc == nil {
|
||||
return match
|
||||
// Mutate the line by recording each replacement and applying in a second pass.
|
||||
// We can't use ReplaceAllStringFunc alone because we need the absolute position.
|
||||
matches := re.FindAllStringSubmatchIndex(line, -1)
|
||||
if len(matches) == 0 {
|
||||
return line
|
||||
}
|
||||
|
||||
type repl struct {
|
||||
start, end int
|
||||
text string
|
||||
}
|
||||
var repls []repl
|
||||
|
||||
for _, loc := range matches {
|
||||
fullStart, fullEnd := loc[0], loc[1]
|
||||
if fullEnd > len(line) {
|
||||
continue
|
||||
}
|
||||
match := line[fullStart:fullEnd]
|
||||
|
||||
// Check if this match overlaps with any already-transformed region
|
||||
absStart := strings.Index(line, match)
|
||||
// Overlap with already-transformed region?
|
||||
overlap := false
|
||||
for _, t := range transformed {
|
||||
if absStart >= t.start && absStart < t.end {
|
||||
return match
|
||||
if fullStart < t.end && fullEnd > t.start {
|
||||
overlap = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if overlap {
|
||||
continue
|
||||
}
|
||||
|
||||
sub := re.FindStringSubmatch(match)
|
||||
if len(sub) < 3 {
|
||||
return match
|
||||
continue
|
||||
}
|
||||
a, b := sub[1], sub[2]
|
||||
|
||||
// Don't transform if either operand looks like a comparison result or is empty
|
||||
if a == "" || b == "" {
|
||||
return match
|
||||
continue
|
||||
}
|
||||
|
||||
// Don't transform pure integer-integer operations (e.g., 2 + 3)
|
||||
// Those are constant-folded by the compiler anyway
|
||||
// Constant-folded by the compiler, no point in transforming.
|
||||
if isPureNumeric(a) && isPureNumeric(b) {
|
||||
return match
|
||||
continue
|
||||
}
|
||||
|
||||
ident := identities[rng.Intn(len(identities))]
|
||||
|
||||
var result string
|
||||
switch len(strings.Split(ident.template, "%s")) - 1 {
|
||||
case 2:
|
||||
@@ -202,8 +220,24 @@ func mbaApplyBinOp(line string, re *regexp.Regexp, identities []mbaIdentity, rng
|
||||
result = fmt.Sprintf(ident.template, a, b)
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
repls = append(repls, repl{start: fullStart, end: fullEnd, text: result})
|
||||
transformed = append(transformed, range_{fullStart, fullEnd})
|
||||
}
|
||||
|
||||
if len(repls) == 0 {
|
||||
return line
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
buf.Grow(len(line))
|
||||
cursor := 0
|
||||
for _, r := range repls {
|
||||
buf.WriteString(line[cursor:r.start])
|
||||
buf.WriteString(r.text)
|
||||
cursor = r.end
|
||||
}
|
||||
buf.WriteString(line[cursor:])
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func mbaApplyUnaryNot(line string, rng *rand.Rand) string {
|
||||
|
||||
Reference in New Issue
Block a user