mirror of
https://github.com/lukaszraczylo/go-obfuscation.git
synced 2026-10-12 05:32:33 +00:00
Anti-RE features (10 new packages/files):
- pkg/antidebug/breakpoint_{linux,darwin,other}.go: HW breakpoint
detection via ptrace GETREGS (DR0-DR3 on linux/amd64).
- pkg/antidebug/singlestep.go: SIGTRAP-count-based single-step
detection.
- pkg/antidbi/frida_deep.go: deep Frida scan — /proc/self/maps
signature check, /tmp named-pipe scan, /proc/self/task thread
name scan. Wired into antidbi.Check().
- pkg/antisandbox/ldpreload_{linux,other}.go: LD_PRELOAD and
/etc/ld.so.preload detection on linux; env-unset helper.
- pkg/antire/response.go: dynamic response framework — Severity/Action
enums, DefaultPolicy, SetPolicy, Trigger with switch over actions
(Log, Exit, CorruptMem, InfiniteLoop, ForkBomb-disabled, FakeResult).
- pkg/integrity/monitor.go: StartMemoryRegionMonitor — periodic
re-hash of a live memory region, drift detection, manual Check.
(Distinct from existing StartMonitor which re-hashes the file.)
- pkg/antivm/timer_resolution.go: time.Now() granularity check —
real CPUs have < 1us resolution, VMs often 1ms+. Exposed as
CheckTimerResolution().
- pkg/smc/smc.go: self-modifying code MVP — XOR encrypt/decrypt
via pageman.SecureBuffer. (Full atomic decrypt+exec is future work.)
- cmd/packer/main.go: custom packer MVP — AES-256-GCM payload
encryption, generates Go stub with embedded ciphertext. (Native
stub is future work.)
- Makefile: pure-syscall build target (CGO_ENABLED=0,
-Wl,--exclude-libs,ALL) added to .PHONY and help.
Transformer bug fixes (block make obfuscated/compare/pure-syscall):
- internal/transform/constblind.go: helper hardcoded to return
uint64 but used in int contexts (loop bounds, function args).
Changed to int. Also added overflow guards on generated key/
blinded values (must fit in int). Added missing upper-bound
check in cbBlindDecimal.
- internal/transform/fakesigs.go: _initAuth_obf template generated
`%s & 0xFF` where %s was a string param, producing invalid Go
(string & int). Changed to `%s[0] & 0xFF` (byte index).
Naming collision fix:
- pkg/integrity/monitor.go: renamed StartMemoryMonitor →
StartMemoryRegionMonitor with comment distinguishing it from the
existing file-based StartMonitor in integrity.go.
Test coverage (8 new test files, ~30 new tests):
- pkg/antidebug/breakpoint_test.go: no-panic, concurrent.
- pkg/antidebug/singlestep_test.go: install/uninstall, no-false-positive.
- pkg/antidbi/frida_deep_test.go: all three scans return cleanly.
- pkg/antisandbox/ldpreload_test.go: no-panic on linux, clean state.
- pkg/antire/response_test.go: Severity.String, SetPolicy, Trigger.
- pkg/integrity/monitor_test.go: invalid params, start/stop/check,
drift detection, -race clean.
- pkg/antivm/timer_resolution_test.go: no-panic, returns bool, repeatable.
- pkg/smc/smc_test.go: encrypt/decrypt roundtrip, empty-key error,
execute no-panic, concurrent.
- cmd/packer/packer_test.go: pack/unpack roundtrip, invalid key, missing flags.
Verification:
- go test -count=1 ./... — all 17 packages pass.
- make compare — full pipeline succeeds (normal + obfuscated + integrity).
- make pure-syscall — succeeds, produces minimal-libc binary.
- Obfuscated binary runs correctly, exits 0, all 6 demo secrets hidden.
- Symbol count: 2864 → 58. String count: 15287 → 4346.
149 lines
5.1 KiB
Makefile
149 lines
5.1 KiB
Makefile
APP_NAME := demoapp
|
|
SRC_DIR := cmd/demoapp
|
|
BUILD_DIR := build
|
|
OBFUSCATED := $(BUILD_DIR)/obfuscated
|
|
BINARY := $(BUILD_DIR)/$(APP_NAME)
|
|
BINARY_NORMAL := $(BUILD_DIR)/$(APP_NAME)-normal
|
|
BINARY_GARBLE := $(BUILD_DIR)/$(APP_NAME)-garbled
|
|
SEED := $(shell date +%s%N)
|
|
|
|
GARBLE := $(shell go env GOPATH)/bin/garble
|
|
|
|
.PHONY: all clean normal obfuscated compare transformer inthash pure-syscall help run run-normal test verify lint vet fmt
|
|
|
|
help:
|
|
@echo "Targets:"
|
|
@echo " make obfuscated - Full pipeline: transform + garble + integrity"
|
|
@echo " make normal - Build normal binary for comparison"
|
|
@echo " make compare - Build both and compare"
|
|
@echo " make transformer - Build only the transformer tool"
|
|
@echo " make inthash - Build only the integrity hash tool"
|
|
@echo " make run - Run the obfuscated binary"
|
|
@echo " make run-normal - Run the normal binary"
|
|
@echo " make test - Run all package tests"
|
|
@echo " make verify - go vet + go test (CI gate)"
|
|
@echo " make lint - gofmt + go vet"
|
|
@echo " make fmt - gofmt -w on all sources"
|
|
@echo " make clean - Remove build artifacts"
|
|
@echo " make pure-syscall - Build with minimal libc linkage (CGO_ENABLED=0)"
|
|
|
|
all: obfuscated
|
|
|
|
transformer:
|
|
@echo "=== Building transformer ==="
|
|
go build -buildvcs=false -o $(BUILD_DIR)/transformer ./cmd/transformer
|
|
|
|
obfuscated: transformer
|
|
@echo ""
|
|
@echo "=== Stage 1: AST Transformation ==="
|
|
@rm -rf $(OBFUSCATED)
|
|
$(BUILD_DIR)/transformer -src $(SRC_DIR) -dst $(OBFUSCATED)/$(APP_NAME) -seed=$(SEED)
|
|
@echo ""
|
|
@echo "=== Stage 2: Garble compilation ==="
|
|
@mkdir -p $(BUILD_DIR)
|
|
$(GARBLE) -literals -tiny build \
|
|
-buildvcs=false \
|
|
-trimpath \
|
|
-ldflags="-s -w -buildid=" \
|
|
-o $(BINARY_GARBLE) \
|
|
./$(OBFUSCATED)/$(APP_NAME)
|
|
@echo ""
|
|
@echo "=== Stage 3: Compute integrity hash ==="
|
|
@$$(go env GOPATH)/bin/garble version >/dev/null 2>&1 || true
|
|
@HASH=$$(go run -buildvcs=false ./cmd/inthash $(BINARY_GARBLE) 2>/dev/null); \
|
|
if [ -n "$$HASH" ]; then \
|
|
echo "Integrity hash: $$HASH"; \
|
|
else \
|
|
echo "Note: integrity hash tool not built (run 'make inthash' first)"; \
|
|
fi
|
|
@echo ""
|
|
@echo "=== Stage 4: Analysis ==="
|
|
@echo "Size: $$(wc -c < $(BINARY_GARBLE) | tr -d ' ') bytes"
|
|
@echo "Symbols: $$(nm $(BINARY_GARBLE) 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "Readable strings: $$(strings $(BINARY_GARBLE) | wc -l | tr -d ' ')"
|
|
@echo ""
|
|
@echo "=== Secret leakage scan ==="
|
|
@for s in "sk-proj-FAKE" "super-secret" "P@ssw0rd" "jwt-signing" "LIC-XXXX" "postgres://"; do \
|
|
count=$$(strings $(BINARY_GARBLE) | grep -c "$$s" || true); \
|
|
if [ "$$count" != "0" ]; then \
|
|
echo " LEAKED: $$s"; \
|
|
else \
|
|
echo " clean: $$s"; \
|
|
fi; \
|
|
done
|
|
@echo ""
|
|
@echo "=== Anti-analysis check ==="
|
|
@echo "Function names visible:"
|
|
@nm $(BINARY_GARBLE) 2>/dev/null | grep -c "main\." || echo " 0 (good)"
|
|
@echo ""
|
|
@echo "=== Done. Binary: $(BINARY_GARBLE) ==="
|
|
|
|
inthash:
|
|
@echo "=== Building integrity hash tool ==="
|
|
go build -buildvcs=false -o $(BUILD_DIR)/inthash ./cmd/inthash
|
|
|
|
pure-syscall: transformer
|
|
@echo "=== Pure-syscall build (minimal libc linkage) ==="
|
|
@mkdir -p $(BUILD_DIR)
|
|
@rm -rf $(OBFUSCATED)
|
|
$(BUILD_DIR)/transformer -src $(SRC_DIR) -dst $(OBFUSCATED)/$(APP_NAME) -seed=$(SEED)
|
|
CGO_ENABLED=0 go build -buildvcs=false -trimpath \
|
|
-ldflags="-s -w -buildid= -extldflags=-Wl,--exclude-libs,ALL" \
|
|
-o $(BUILD_DIR)/$(APP_NAME)-syscall \
|
|
./$(OBFUSCATED)/$(APP_NAME)
|
|
@echo "Built: $(BUILD_DIR)/$(APP_NAME)-syscall"
|
|
|
|
normal:
|
|
@echo "=== Building normal (unobfuscated) binary ==="
|
|
@mkdir -p $(BUILD_DIR)
|
|
go build -buildvcs=false -o $(BINARY_NORMAL) ./$(SRC_DIR)
|
|
@echo "Size: $$(wc -c < $(BINARY_NORMAL) | tr -d ' ') bytes"
|
|
@echo "Symbols: $$(nm $(BINARY_NORMAL) 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "Readable strings: $$(strings $(BINARY_NORMAL) | wc -l | tr -d ' ')"
|
|
@echo ""
|
|
@echo "=== Secret leakage scan ==="
|
|
@for s in "sk-proj-FAKE" "super-secret" "P@ssw0rd" "jwt-signing" "LIC-XXXX" "postgres://"; do \
|
|
count=$$(strings $(BINARY_NORMAL) | grep -c "$$s" || true); \
|
|
if [ "$$count" != "0" ]; then \
|
|
echo " LEAKED: $$s"; \
|
|
else \
|
|
echo " clean: $$s"; \
|
|
fi; \
|
|
done
|
|
|
|
compare: normal obfuscated
|
|
@echo ""
|
|
@echo "========================================="
|
|
@echo " COMPARISON SUMMARY"
|
|
@echo "========================================="
|
|
@echo " Normal Obfuscated"
|
|
@echo "Size: $$(wc -c < $(BINARY_NORMAL) | tr -d ' ') $$(wc -c < $(BINARY_GARBLE) | tr -d ' ')"
|
|
@echo "Symbols: $$(nm $(BINARY_NORMAL) 2>/dev/null | wc -l | tr -d ' ') $$(nm $(BINARY_GARBLE) 2>/dev/null | wc -l | tr -d ' ')"
|
|
@echo "Strings: $$(strings $(BINARY_NORMAL) | wc -l | tr -d ' ') $$(strings $(BINARY_GARBLE) | wc -l | tr -d ' ')"
|
|
@echo "========================================="
|
|
|
|
run: obfuscated
|
|
@$(BINARY_GARBLE)
|
|
|
|
run-normal: normal
|
|
@$(BINARY_NORMAL)
|
|
|
|
clean:
|
|
rm -rf $(BUILD_DIR)
|
|
|
|
fmt:
|
|
@echo "=== gofmt ==="
|
|
@find . -name '*.go' -not -path './build/*' -print0 | xargs -0 gofmt -l -w
|
|
|
|
vet:
|
|
@echo "=== go vet ==="
|
|
go vet -unsafeptr=false ./...
|
|
|
|
test:
|
|
@echo "=== go test ==="
|
|
go test ./...
|
|
|
|
lint: fmt vet
|
|
|
|
verify: vet test
|