Files
go-obfuscation/pkg/stringcrypt/stringcrypt_test.go
T
lukaszraczylo b6c3bacd23 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.
2026-06-01 14:08:50 +01:00

106 lines
2.8 KiB
Go

package stringcrypt
import (
"bytes"
"encoding/base64"
"testing"
)
func TestEncryptDecryptRoundtrip(t *testing.T) {
cases := []string{
"",
"x",
"hello world",
"sk-proj-FAKE-KEY-1234567890abcdef",
"unicode: \u00e9\u4e2d\u6587",
"line1\nline2\ttabbed",
}
for _, pt := range cases {
enc := Encrypt(pt)
if pt != "" && bytes.Equal(enc.ciphertext, []byte(pt)) {
t.Errorf("ciphertext equals plaintext for %q", pt)
}
if got := enc.Decrypt(); got != pt {
t.Errorf("Decrypt() = %q, want %q", got, pt)
}
}
}
func TestEncryptUniqueKeys(t *testing.T) {
pt := "same plaintext"
a := Encrypt(pt)
b := Encrypt(pt)
if bytes.Equal(a.key, b.key) {
t.Error("two Encrypt calls produced identical keys (low probability event, but should not happen)")
}
if bytes.Equal(a.ciphertext, b.ciphertext) {
t.Error("two Encrypt calls produced identical ciphertext (keys should differ)")
}
}
func TestEncryptedStringB64Roundtrip(t *testing.T) {
enc := Encrypt("hello")
ct, err := base64.StdEncoding.DecodeString(enc.CiphertextB64())
if err != nil {
t.Fatalf("CiphertextB64() invalid base64: %v", err)
}
if !bytes.Equal(ct, enc.ciphertext) {
t.Error("CiphertextB64() does not roundtrip to raw ciphertext")
}
ky, err := base64.StdEncoding.DecodeString(enc.KeyB64())
if err != nil {
t.Fatalf("KeyB64() invalid base64: %v", err)
}
if !bytes.Equal(ky, enc.key) {
t.Error("KeyB64() does not roundtrip to raw key")
}
}
func TestRandomIdent(t *testing.T) {
const prefix = "x"
const length = 5
id := RandomIdent(prefix, length)
if len(id) != len(prefix)+length {
t.Errorf("RandomIdent len = %d, want %d (got %q)", len(id), len(prefix)+length, id)
}
if id[:len(prefix)] != prefix {
t.Errorf("RandomIdent prefix mismatch: %q", id)
}
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for _, r := range id[len(prefix):] {
if !bytes.ContainsRune([]byte(charset), r) {
t.Errorf("RandomIdent contains unexpected char %q in %q", r, id)
}
}
}
func TestRandomIdentUniqueness(t *testing.T) {
seen := make(map[string]struct{})
for i := 0; i < 1000; i++ {
id := RandomIdent("_p", 6)
if _, dup := seen[id]; dup {
t.Fatalf("RandomIdent collision after %d iterations: %q", i, id)
}
seen[id] = struct{}{}
}
}
func TestRandomIdentZeroLength(t *testing.T) {
id := RandomIdent("p_", 0)
if id != "p_" {
t.Errorf("RandomIdent with 0 length = %q, want %q", id, "p_")
}
}
func TestGenerateRuntimeDecryptCallStructure(t *testing.T) {
src := GenerateRuntimeDecryptCall("aGVsbG8=", "a2V5")
if src == "" {
t.Error("GenerateRuntimeDecryptCall returned empty string")
}
for _, want := range []string{"base64.StdEncoding", "DecodeString", "return", "string(_pt)"} {
if !bytes.Contains([]byte(src), []byte(want)) {
t.Errorf("GenerateRuntimeDecryptCall missing %q in output:\n%s", want, src)
}
}
}