-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix for (s *stringObfuscator) Obfuscate() #15
Comments
anyway after further inspection it appears it does not work properly at all, so maybe it is worth less to fix. |
I re open because after i start make use of astutil it just works! see https://godoc.org/golang.org/x/tools/go/ast/astutil#Apply func processPackage() error {
var opts packageProcessOpts
flag.StringVar(&opts.Tag, "tag", Appname, "the output build tag of the generated files")
flag.Parse()
pkgpath := flag.Arg(0)
if pkgpath == "" {
return fmt.Errorf("invalid options, missing package. command line is %v <opt> <package>", Appname)
}
var conf loader.Config
conf.Import(pkgpath)
prog, err := conf.Load()
if err != nil {
return err
}
pkg := prog.Package(pkgpath)
if pkg == nil {
return fmt.Errorf("package %q not found in loaded program", pkgpath)
}
//-
for _, f := range pkg.Files {
pre := func(c *astutil.Cursor) bool {
if _, ok := c.Node().(*ast.ImportSpec); ok {
return false
}
if x, ok := c.Node().(*ast.BasicLit); ok {
b := obfuscatedStringCode(x.Value)
expr, err := parser.ParseExpr(string(b))
if err != nil {
log.Println(err)
return false
}
c.Replace(expr)
}
return true
}
res := astutil.Apply(f, pre, nil)
log.Println("")
log.Println(res)
fset := token.NewFileSet()
printer.Fprint(os.Stdout, fset, res)
}
return nil
} |
Good find on astutil's Apply function! Regardless of all else, I should add a to-do to switch to that API for everything. Do you have an example program that triggers the bug you found? I have not seen the error you mentioned before (the obfuscator has worked correctly on all programs I've tried). I also noticed your new code likely doesn't work for string constants, e.g. |
oh yeah it is possible i have forgotten some ast kinds. There are so many! However, reading the earlier source code i think it should work for consts. weird! Anyways, sorry for earlier program example. I realized it was missing a type decl. Here is an updated version which suits my need specifically. I run the program against itself, something like I checked for consts specifically, it worked here. But i have not written any test :x type packageProcessOpts struct {
Tag string
Var string
}
func processPackage() error {
var opts packageProcessOpts
flag.StringVar(&opts.Tag, "tag", Appname, "the output build tag of the generated files")
flag.StringVar(&opts.Var, "var", "", "only this var")
flag.Parse()
if opts.Tag == "" {
return fmt.Errorf("-tag tagname is required")
}
pkgpath := flag.Arg(0)
if pkgpath == "" {
return fmt.Errorf("invalid options, missing package. command line is %v p <opt> <package>", Appname)
}
var conf loader.Config
conf.Import(pkgpath)
prog, err := conf.Load()
if err != nil {
return err
}
pkg := prog.Package(pkgpath)
if pkg == nil {
return fmt.Errorf("package %q not found in loaded program", pkgpath)
}
for _, f := range pkg.Files {
pre := func(c *astutil.Cursor) bool {
// log.Printf("%T\n", c.Node())
if _, ok := c.Node().(*ast.ImportSpec); ok {
return false
}
if x, ok := c.Node().(*ast.ValueSpec); ok {
for i, n := range x.Names {
if opts.Var == n.Name {
v, ok := x.Values[i].(*ast.BasicLit)
if ok {
b := obfuscatedStringCode(v.Value)
expr, err := parser.ParseExpr(string(b))
if err != nil {
log.Println(err)
} else {
x.Values[i] = expr
}
}
}
}
return false
}
if x, ok := c.Node().(*ast.BasicLit); ok {
if opts.Var == "" {
b := obfuscatedStringCode(x.Value)
expr, err := parser.ParseExpr(string(b))
if err != nil {
log.Println(err)
return false
}
c.Replace(expr)
}
}
return true
}
res := astutil.Apply(f, pre, nil)
// os.Exit(0)
fset := token.NewFileSet()
fmt.Fprintf(os.Stdout, "//+build %v\n\n", opts.Tag)
printer.Fprint(os.Stdout, fset, res)
}
return nil
}
type generateOpts struct {
Tag string
Var string
Content string
}
func generate() error {
var opts generateOpts
flag.StringVar(&opts.Tag, "tag", Appname, "the output build tag of the generated files")
flag.StringVar(&opts.Var, "var", "", "only this var")
flag.StringVar(&opts.Content, "content", "", "the content of the var")
flag.Parse()
if opts.Tag == "" {
return fmt.Errorf("-tag tagname is required")
}
if opts.Var == "" {
return fmt.Errorf("-var tagname is required")
}
if opts.Content == "" {
b := new(bytes.Buffer)
done := make(chan error)
go func() {
_, err := io.Copy(b, os.Stdin)
done <- err
}()
select {
case err := <-done:
if err != nil {
return err
}
case <-time.After(time.Millisecond * 100):
return fmt.Errorf("stdin is empty..")
}
opts.Content = b.String()
}
if opts.Content == "" {
return fmt.Errorf("-content is required, use stdin otherwise")
}
pkgpath := flag.Arg(0)
if pkgpath == "" {
return fmt.Errorf("invalid options, missing package. command line is %v g <opt> <pkg path>", Appname)
}
var pkgName string
var conf loader.Config
conf.Import(pkgpath)
prog, err := conf.Load()
if err != nil {
return err
}
pkg := prog.Package(pkgpath)
if pkg == nil {
return fmt.Errorf("package %q not found in loaded program", pkgpath)
}
if pkg.Pkg == nil {
return fmt.Errorf("package %q not found in loaded program", pkgpath)
}
pkgName = pkg.Pkg.Name()
if pkgName == "" {
return fmt.Errorf("package name could not be determined")
}
obfuscatedStr := obfuscatedStringCode(opts.Content)
filec := fmt.Sprintf(`package %v
var %v = %s
`, pkgName, opts.Var, obfuscatedStr)
if opts.Tag != "" {
filec = fmt.Sprintf(`//+build %v
%v`, opts.Tag, filec)
}
fmt.Println(filec)
return nil
}
func obfuscatedStringCode(str string) []byte {
var res bytes.Buffer
res.WriteString("(func() string {\n")
res.WriteString("mask := []byte(\"")
mask := make([]byte, len(str))
for i := range mask {
mask[i] = byte(rand.Intn(256))
res.WriteString(fmt.Sprintf("\\x%02x", mask[i]))
}
res.WriteString("\")\nmaskedStr := []byte(\"")
for i, x := range []byte(str) {
res.WriteString(fmt.Sprintf("\\x%02x", x^mask[i]))
}
res.WriteString("\")\nres := make([]byte, ")
res.WriteString(strconv.Itoa(len(mask)))
res.WriteString(`)
for i, m := range mask {
res[i] = m ^ maskedStr[i]
}
return string(res)
}())`)
return res.Bytes()
} |
hey, i had to fix a small bug in the mentioned method.
The fix is
The test program is trying to obfuscate itself and bugs with a
panic: runtime error: slice bounds out of range
The text was updated successfully, but these errors were encountered: