-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathobfuscator.go
More file actions
133 lines (113 loc) · 3.82 KB
/
obfuscator.go
File metadata and controls
133 lines (113 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"fmt"
"math/rand"
"regexp"
"strings"
"time"
)
type Obfuscator struct {
rng *rand.Rand
variableMap map[string]string
}
func NewObfuscator() *Obfuscator {
source := rand.NewSource(time.Now().UnixNano())
rng := rand.New(source)
return &Obfuscator{
rng: rng,
variableMap: make(map[string]string),
}
}
func (o *Obfuscator) randomVarName() string {
letters := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
name := fmt.Sprintf("_v%c%d", letters[o.rng.Intn(len(letters))], o.rng.Intn(1000))
return name
}
func (o *Obfuscator) Obfuscate(jsCode string, config ObfuscationConfig) string {
if config.ChangeVariable {
// Obfuscate variable names
varRegex := regexp.MustCompile(`\b(var|let|const)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\b`)
jsCode = varRegex.ReplaceAllStringFunc(jsCode, func(match string) string {
parts := varRegex.FindStringSubmatch(match)
keyword, varName := parts[1], parts[2]
if _, exists := o.variableMap[varName]; !exists {
o.variableMap[varName] = o.randomVarName()
}
return fmt.Sprintf("%s %s", keyword, o.variableMap[varName])
})
}
// Obfuscate normal strings (single and double quotes)
stringRegex := regexp.MustCompile(`"([^"]*)"|'([^']*)'`)
jsCode = stringRegex.ReplaceAllStringFunc(jsCode, func(match string) string {
quote := match[:1] // Extract opening quote
content := match[1:] // Remove opening quote
content = content[:len(content)-1] // Remove closing quote
var encoded strings.Builder
for _, char := range content {
encoded.WriteString(fmt.Sprintf("\\x%02x", char))
}
return quote + encoded.String() + quote
})
// Obfuscate template literals (preserve `${}` expressions and replace variables)
templateRegex := regexp.MustCompile("`([^`]*)`")
jsCode = templateRegex.ReplaceAllStringFunc(jsCode, func(match string) string {
content := match[1 : len(match)-1] // Remove backticks
var encoded strings.Builder
inExpression := false
nestedLevel := 0 // Track `${}` depth
var expressionBuffer strings.Builder
for i := 0; i < len(content); i++ {
if content[i] == '$' && i+1 < len(content) && content[i+1] == '{' {
inExpression = true
nestedLevel++
encoded.WriteString("${")
i++ // Skip next '{'
expressionBuffer.Reset()
continue
}
if inExpression {
if content[i] == '}' {
nestedLevel--
if nestedLevel == 0 {
inExpression = false
expression := expressionBuffer.String()
if obfVar, exists := o.variableMap[expression]; exists {
encoded.WriteString(obfVar)
} else {
encoded.WriteString(expression) // Keep unchanged if not found
}
encoded.WriteString("}")
continue
}
}
expressionBuffer.WriteByte(content[i])
} else {
encoded.WriteString(fmt.Sprintf("\\x%02x", content[i])) // Encode static text
}
}
return "`" + encoded.String() + "`"
})
if config.ChangeVariable {
// Replace variable names inside the entire JS code
for original, obfuscated := range o.variableMap {
jsCode = strings.ReplaceAll(jsCode, original, obfuscated)
}
}
if config.RemoveComments {
// Remove single-line and multi-line comments
commentRegex := regexp.MustCompile(`(?s)/\*.*?\*/|(?m)^\s*//.*?$`)
jsCode = commentRegex.ReplaceAllString(jsCode, "")
// Remove empty lines
emptyLineRegex := regexp.MustCompile(`(?m)^\s*\n`)
jsCode = emptyLineRegex.ReplaceAllString(jsCode, "")
}
if config.RemoveWhiteSpace {
// Ensure each line ends with a semicolon if it doesn't already
semicolonRegex := regexp.MustCompile(`(?m)([^\s;])\s*$`)
jsCode = semicolonRegex.ReplaceAllString(jsCode, "$1;")
// Remove all unnecessary whitespace
jsCode = regexp.MustCompile(`\s+`).ReplaceAllString(jsCode, " ")
jsCode = regexp.MustCompile(`\s*([=+\-*/{}(),;])\s*`).ReplaceAllString(jsCode, "$1")
}
return jsCode
}