Open
Description
Here are two ideas to make string deobfuscation more challenging:
- Random Constants as Function Parameters
Move some random constants into the parameters of the deobfuscation function. This will force analysts to examine the function's call sites and extract all the necessary parameters, making deobfuscation significantly harder:
package main
func main() {
println(string(func(c1 byte, c2 byte) string {
data := []byte("ၯ\x88\x8f\xf1\xfcorld")
positions := [...]byte{4, 1, 5, 2, 6, 2, 3, 1, 0, 6, c1, 1}
for i := 0; i < 12; i += 2 {
localKey := byte(i) + byte(positions[i]^positions[i+1]) + c2
data[positions[i]], data[positions[i+1]] = data[positions[i+1]]+localKey, data[positions[i]]+localKey
}
return string(data)
}(4, 104)))
}
- Proxying string(data) Calls
The string(data) call is a key marker used for string deobfuscation. By introducing a proxy function for this operation, we can obscure the decryption mechanism and complicate automatic deobfuscation attempts.
package main
func main() {
println(string(func() string {
type proxy struct {
a func([]byte) float64
b func([]byte) float64
c func([]byte, int, int, int) string
d func([]byte) float64
}
x := proxy{c: func(bytes []byte, a int, b int, c int) string {
return string(bytes)
}}
data := []byte("ၯ\x88\x8f\xf1\xfcorld")
positions := [...]byte{4, 1, 5, 2, 6, 2, 3, 1, 0, 6, 4, 1}
for i := 0; i < 12; i += 2 {
localKey := byte(i) + byte(positions[i]^positions[i+1]) + 104
data[positions[i]], data[positions[i+1]] = data[positions[i+1]]+localKey, data[positions[i]]+localKey
}
return x.c(data, 9, 9, 9)
}()))
}
Interested in your opinions @mvdan @lu4p, does it make sense to implement something like this