mirror of
https://github.com/chainreactors/spray.git
synced 2025-05-08 11:36:45 +00:00
168 lines
3.5 KiB
Go
168 lines
3.5 KiB
Go
package internal
|
|
|
|
import (
|
|
"bytes"
|
|
"github.com/antonmedv/expr/ast"
|
|
"github.com/chainreactors/spray/pkg"
|
|
"github.com/chainreactors/words/mask"
|
|
"github.com/chainreactors/words/rule"
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func parseExtension(s string) string {
|
|
if i := strings.Index(s, "."); i != -1 {
|
|
return s[i+1:]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func parseStatus(preset []int, changed string) []int {
|
|
if changed == "" {
|
|
return preset
|
|
}
|
|
if strings.HasPrefix(changed, "+") {
|
|
for _, s := range strings.Split(changed[1:], ",") {
|
|
if t, err := strconv.Atoi(s); err != nil {
|
|
continue
|
|
} else {
|
|
preset = append(preset, t)
|
|
}
|
|
}
|
|
} else if strings.HasPrefix(changed, "!") {
|
|
for _, s := range strings.Split(changed[1:], ",") {
|
|
for i, status := range preset {
|
|
if t, err := strconv.Atoi(s); err != nil {
|
|
break
|
|
} else if t == status {
|
|
preset = append(preset[:i], preset[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
preset = []int{}
|
|
for _, s := range strings.Split(changed, ",") {
|
|
if t, err := strconv.Atoi(s); err != nil {
|
|
continue
|
|
} else {
|
|
preset = append(preset, t)
|
|
}
|
|
}
|
|
}
|
|
return preset
|
|
}
|
|
|
|
func loadFileToSlice(filename string) ([]string, error) {
|
|
var ss []string
|
|
content, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ss = strings.Split(strings.TrimSpace(string(content)), "\n")
|
|
|
|
// 统一windows与linux的回车换行差异
|
|
for i, word := range ss {
|
|
ss[i] = strings.TrimSpace(word)
|
|
}
|
|
|
|
return ss, nil
|
|
}
|
|
|
|
func loadRuleAndCombine(filename []string) (string, error) {
|
|
var bs bytes.Buffer
|
|
for _, f := range filename {
|
|
if data, ok := pkg.Rules[f]; ok {
|
|
bs.WriteString(strings.TrimSpace(data))
|
|
bs.WriteString("\n")
|
|
} else {
|
|
content, err := ioutil.ReadFile(f)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
bs.Write(bytes.TrimSpace(content))
|
|
bs.WriteString("\n")
|
|
}
|
|
}
|
|
return bs.String(), nil
|
|
}
|
|
|
|
func loadFileWithCache(filename string) ([]string, error) {
|
|
if dict, ok := dictCache[filename]; ok {
|
|
return dict, nil
|
|
}
|
|
dict, err := loadFileToSlice(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dictCache[filename] = dict
|
|
return dict, nil
|
|
}
|
|
|
|
func loadDictionaries(filenames []string) ([][]string, error) {
|
|
dicts := make([][]string, len(filenames))
|
|
for i, name := range filenames {
|
|
dict, err := loadFileWithCache(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dicts[i] = dict
|
|
}
|
|
return dicts, nil
|
|
}
|
|
|
|
func loadWordlist(word string, dictNames []string) ([]string, error) {
|
|
if wl, ok := wordlistCache[word+strings.Join(dictNames, ",")]; ok {
|
|
return wl, nil
|
|
}
|
|
dicts, err := loadDictionaries(dictNames)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wl, err := mask.Run(word, dicts, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wordlistCache[word] = wl
|
|
return wl, nil
|
|
}
|
|
|
|
func loadRuleWithFiles(ruleFiles []string, filter string) ([]rule.Expression, error) {
|
|
if rules, ok := ruleCache[strings.Join(ruleFiles, ",")]; ok {
|
|
return rules, nil
|
|
}
|
|
var rules bytes.Buffer
|
|
for _, filename := range ruleFiles {
|
|
content, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rules.Write(content)
|
|
rules.WriteString("\n")
|
|
}
|
|
return rule.Compile(rules.String(), filter).Expressions, nil
|
|
}
|
|
|
|
type bytesPatcher struct{}
|
|
|
|
func (p *bytesPatcher) Visit(node *ast.Node) {
|
|
switch (*node).(type) {
|
|
case *ast.MemberNode:
|
|
ast.Patch(node, &ast.CallNode{
|
|
Callee: &ast.MemberNode{
|
|
Node: *node,
|
|
Name: "String",
|
|
Property: &ast.StringNode{Value: "String"},
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
func wrapWordsFunc(f func(string) string) func(string) []string {
|
|
return func(s string) []string {
|
|
return []string{f(s)}
|
|
}
|
|
}
|