mirror of
https://github.com/gatariee/ldrgen
synced 2026-06-06 15:44:29 +00:00
lots and lots of fixes
This commit is contained in:
Binary file not shown.
+1
-2
@@ -28,11 +28,9 @@ github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT
|
||||
github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/microcosm-cc/bluemonday v1.0.17/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||
github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
@@ -53,5 +51,6 @@ github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGj
|
||||
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
|
||||
+63
-39
@@ -6,9 +6,12 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
gen "ldrgen/cmd/generator"
|
||||
utils "ldrgen/cmd/utils"
|
||||
)
|
||||
|
||||
var generateCmd = &cobra.Command{
|
||||
@@ -60,22 +63,14 @@ var generateCmd = &cobra.Command{
|
||||
fmt.Println("[!] there was an error reading your config, this is what we are trying to read: ", filepath.Join(templatePath, "config.yaml"))
|
||||
return
|
||||
}
|
||||
|
||||
switch ldrToken {
|
||||
case "":
|
||||
cmd.Help()
|
||||
fmt.Println("\n--loader -> you must specify a loader token")
|
||||
ldrFound := gen.TokenExists(ldrToken, config)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if !ldrFound {
|
||||
fmt.Println("\n--loader -> loader token not found, please check your spelling and try again")
|
||||
return
|
||||
default:
|
||||
ldrFound := gen.TokenExists(ldrToken, config)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if !ldrFound {
|
||||
fmt.Println("\n--loader -> loader token not found, please check your spelling and try again")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
enc, _ := cmd.Flags().GetString("enc")
|
||||
@@ -112,22 +107,6 @@ var generateCmd = &cobra.Command{
|
||||
|
||||
cleanup, _ := cmd.Flags().GetBool("cleanup")
|
||||
|
||||
if binPath == "" {
|
||||
cmd.Help()
|
||||
fmt.Println("\n--bin -> you must specify a .bin file to load")
|
||||
return
|
||||
}
|
||||
|
||||
if outputPath == "" {
|
||||
cmd.Help()
|
||||
return
|
||||
}
|
||||
|
||||
if ldrToken == "" {
|
||||
cmd.Help()
|
||||
return
|
||||
}
|
||||
|
||||
needsEnc := gen.TokenEnc(ldrToken, config)
|
||||
if needsEnc && enc == "" {
|
||||
enc = "xor"
|
||||
@@ -157,17 +136,62 @@ var generateCmd = &cobra.Command{
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
absOutputPath, err := filepath.Abs(outputPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
utils.PrintSuccess("Looks like everything worked!", true)
|
||||
message := fmt.Sprintf("Your loader is located at: %s", color.New(color.Bold).Sprintf(absOutputPath))
|
||||
utils.PrintInfo(message, true)
|
||||
|
||||
utils.PrintNewLine()
|
||||
utils.PrintInfo("Compile loader? (y/n)", true)
|
||||
|
||||
rl, err := readline.New("> ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
compile, err := rl.Readline()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
switch compile {
|
||||
case "y":
|
||||
utils.PrintNewLine()
|
||||
utils.PrintInfo("Compiling loader...", true)
|
||||
err = gen.CompileLoader(absOutputPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
utils.PrintSuccess("Loader compiled successfully!", true)
|
||||
default:
|
||||
utils.PrintNewLine()
|
||||
message := fmt.Sprintf("Okay, compile with: `cd %s && make`", absOutputPath)
|
||||
utils.PrintInfo(message, true)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(generateCmd)
|
||||
generateCmd.Flags().StringP("bin", "b", "", "* Path to binary file to load")
|
||||
generateCmd.MarkFlagRequired("bin")
|
||||
generateCmd.Flags().StringP("output", "o", "", "* Path to output directory")
|
||||
generateCmd.MarkFlagRequired("output")
|
||||
generateCmd.Flags().StringP("loader", "l", "", "* Loader token to use")
|
||||
generateCmd.MarkFlagRequired("loader")
|
||||
generateCmd.Flags().StringP("template", "t", "", "Path to template directory")
|
||||
generateCmd.MarkFlagRequired("template")
|
||||
|
||||
generateCmd.Flags().StringP("bin", "b", "", "* Path to binary file to load (required)")
|
||||
generateCmd.Flags().StringP("output", "o", "", "* Path to output directory (required)")
|
||||
generateCmd.Flags().StringP("loader", "l", "", "* Loader token to use (required)")
|
||||
generateCmd.Flags().StringP("enc", "e", "", "Encryption type to use (optional, depending on ldr)")
|
||||
generateCmd.Flags().StringP("args", "a", "", "Arguments to pass to template (optional, depending on ldr)")
|
||||
generateCmd.Flags().StringP("template", "t", "../templates", "Path to template folder (optional, default: ../templates)")
|
||||
generateCmd.Flags().BoolP("cleanup", "c", false, "Cleanup temporary files (optional, default: false)")
|
||||
generateCmd.Flags().StringP("enc", "e", "", "Encryption type to use")
|
||||
generateCmd.Flags().StringP("args", "a", "", "Arguments to pass to template")
|
||||
|
||||
generateCmd.Flags().BoolP("cleanup", "c", false, "Cleanup temporary files")
|
||||
}
|
||||
|
||||
@@ -4,27 +4,41 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"ldrgen/cmd/utils"
|
||||
)
|
||||
|
||||
func ProcessLoaderTemplate(token string, enc string, template_args map[string]string, outputPath string, config *Config, template_path string) error {
|
||||
method := TokenMethod(token, config)
|
||||
fmt.Println("[LDR] Using:", method)
|
||||
|
||||
message := fmt.Sprintf("[ %s ] ", color.New(color.Bold).Sprintf("Loader"))
|
||||
utils.PrintWhite(message)
|
||||
|
||||
message = fmt.Sprintf("Using: %s", color.New(color.Bold).Sprintf(token))
|
||||
utils.Print(message, true)
|
||||
|
||||
message = fmt.Sprintf("Calls: %s", color.New(color.Bold).Sprintf(method))
|
||||
utils.Print(message, true)
|
||||
|
||||
for _, l := range config.Loader {
|
||||
if strings.EqualFold(l.Token, token) {
|
||||
|
||||
// check that number of substitutions, match the number of arguments
|
||||
|
||||
if len(template_args) != countSubs(l.Files) {
|
||||
return fmt.Errorf("number of arguments does not match number of substitutions: expected %d, got %d", countSubs(l.Files), len(template_args))
|
||||
if len(template_args) != CountSubs(l.Files) {
|
||||
return fmt.Errorf("number of arguments does not match number of substitutions: expected %d, got %d", CountSubs(l.Files), len(template_args))
|
||||
}
|
||||
|
||||
// check that all substitutions are present in the arguments
|
||||
err := verifySubstitutions(template_args, l.Files)
|
||||
err := VerifySubstitutions(template_args, l.Files)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
utils.PrintNewLine()
|
||||
message = fmt.Sprintf("[ %s ] ", color.New(color.Bold).Sprintf("Substitution"))
|
||||
utils.PrintWhite(message)
|
||||
|
||||
for _, f := range l.Files {
|
||||
content, err := ReadFile(filepath.Join(template_path, f.SourcePath))
|
||||
if err != nil {
|
||||
@@ -34,8 +48,12 @@ func ProcessLoaderTemplate(token string, enc string, template_args map[string]st
|
||||
for k, v := range template_args {
|
||||
for s, r := range f.Substitutions {
|
||||
if strings.EqualFold(k, s) {
|
||||
fmt.Println("[TEMPLATING] Replacing:", r, "with:", v)
|
||||
message = fmt.Sprintf("%s -> %s", color.New(color.Bold).Sprintf(f.SourcePath), color.New(color.Bold).Sprintf(f.OutputPath))
|
||||
utils.Print(message, true)
|
||||
message = fmt.Sprintf("\t%s -> %s", r, v)
|
||||
utils.Print(message, true)
|
||||
content = strings.ReplaceAll(content, r, v)
|
||||
utils.PrintNewLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,10 +62,12 @@ func ProcessLoaderTemplate(token string, enc string, template_args map[string]st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
/* This should *never* happen */
|
||||
return fmt.Errorf("loader not found")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"ldrgen/cmd/utils"
|
||||
)
|
||||
|
||||
func ProcessShellcodeTemplate(binPath string, enc string, args map[string]string, outputPath string, config *Config, template_path string) error {
|
||||
@@ -18,7 +21,16 @@ func ProcessShellcodeTemplate(binPath string, enc string, args map[string]string
|
||||
switch enc {
|
||||
case "xor":
|
||||
key := args["key"]
|
||||
fmt.Println("[!!!] XORing shellcode with key:", key)
|
||||
|
||||
message := fmt.Sprintf("[ %s ] ", color.New(color.Bold).Sprintf("Shellcode Encryption"))
|
||||
utils.PrintWhite(message)
|
||||
|
||||
message = fmt.Sprintf("Using: %s", color.New(color.Bold).Sprintf("XOR"))
|
||||
utils.Print(message, true)
|
||||
|
||||
message = fmt.Sprintf("Key: %s", color.New(color.Bold).Sprintf(key))
|
||||
utils.Print(message, true)
|
||||
|
||||
shellcode, err := os.ReadFile(binPath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -31,12 +43,25 @@ func ProcessShellcodeTemplate(binPath string, enc string, args map[string]string
|
||||
|
||||
ba := fmt.Sprintf("{ %s }", strings.Join(byteArray, ", "))
|
||||
|
||||
fmt.Println("[Sanity Check] Starting bytes (before XOR): ", ba[0:24], "... }")
|
||||
message = fmt.Sprintf("Size: %s bytes", color.New(color.Bold).Sprintf("%d", len(shellcode)))
|
||||
utils.Print(message, true)
|
||||
|
||||
message = fmt.Sprintf("Before: %s ... }", color.New(color.Bold).Sprintf(ba[0:24]))
|
||||
utils.Print(message, true)
|
||||
|
||||
for i := 0; i < len(shellcode); i++ {
|
||||
shellcode[i] ^= key[i%len(key)]
|
||||
}
|
||||
|
||||
byteArray = nil
|
||||
for _, b := range shellcode {
|
||||
byteArray = append(byteArray, fmt.Sprintf("0x%02X", b))
|
||||
}
|
||||
|
||||
ba = fmt.Sprintf("{ %s }", strings.Join(byteArray, ", "))
|
||||
message = fmt.Sprintf("After: %s ... }", color.New(color.Bold).Sprintf(ba[0:24]))
|
||||
utils.Print(message, true)
|
||||
|
||||
err = os.WriteFile(binPath+".enc", shellcode, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -44,8 +69,7 @@ func ProcessShellcodeTemplate(binPath string, enc string, args map[string]string
|
||||
|
||||
binPath = binPath + ".enc"
|
||||
|
||||
fmt.Printf("[*] Encrypted shellcode saved to: %s\n\n", binPath)
|
||||
|
||||
utils.PrintNewLine()
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -72,28 +96,41 @@ func ProcessShellcodeTemplate(binPath string, enc string, args map[string]string
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[*] Saving generated files to:", abs)
|
||||
message := fmt.Sprintf("[ %s ] ", color.New(color.Bold).Sprintf("%s", config.Shellcode.SourceOutputName))
|
||||
utils.PrintWhite(message)
|
||||
|
||||
fmt.Println("[SHELLCODE] Shellcode size:", fileInfo.Size(), "bytes")
|
||||
fmt.Println("[SHELLCODE] Starting bytes: ", shellcodeArray[0:24], "... }")
|
||||
message = fmt.Sprintf("Size: %s bytes", color.New(color.Bold).Sprintf("%d", fileInfo.Size()))
|
||||
utils.Print(message, true)
|
||||
|
||||
message = fmt.Sprintf("Starting bytes: %s ... }", color.New(color.Bold).Sprintf("%s", shellcodeArray[0:24]))
|
||||
utils.Print(message, true)
|
||||
|
||||
err = SaveToFile(outputPath, config.Shellcode.SourceOutputName, shellcodeTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[*] Shellcode.c -> OK")
|
||||
message = fmt.Sprintf("%s -> %s", config.Shellcode.SourceOutputName, abs+"/"+config.Shellcode.SourceOutputName)
|
||||
utils.Print(message, true)
|
||||
|
||||
header_template, err := ReadFile(filepath.Join(template_path, config.Shellcode.IncludePath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("[*] Shellcode.h -> OK")
|
||||
|
||||
message = fmt.Sprintf("[ %s ] ", color.New(color.Bold).Sprintf("%s", config.Shellcode.IncludeOutputName))
|
||||
utils.PrintNewLine()
|
||||
utils.PrintWhite(message)
|
||||
|
||||
err = SaveToFile(outputPath, config.Shellcode.IncludeOutputName, header_template)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
message = fmt.Sprintf("%s -> %s", config.Shellcode.IncludeOutputName, abs+"/"+config.Shellcode.IncludeOutputName)
|
||||
utils.Print(message, true)
|
||||
|
||||
utils.PrintNewLine()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func countSubs(files []FileConfig) int {
|
||||
func CountSubs(files []FileConfig) int {
|
||||
num_subs := 0
|
||||
for _, f := range files {
|
||||
num_subs += len(f.Substitutions)
|
||||
@@ -12,7 +12,7 @@ func countSubs(files []FileConfig) int {
|
||||
return num_subs
|
||||
}
|
||||
|
||||
func verifySubstitutions(template_args map[string]string, files []FileConfig) error {
|
||||
func VerifySubstitutions(template_args map[string]string, files []FileConfig) error {
|
||||
for _, f := range files {
|
||||
for k := range f.Substitutions {
|
||||
if _, ok := template_args[k]; !ok {
|
||||
|
||||
@@ -3,7 +3,9 @@ package generate
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -61,3 +63,62 @@ func ToCArray(filePath string) (string, error) {
|
||||
}
|
||||
return fmt.Sprintf("{ %s }", strings.Join(byteArray, ", ")), nil
|
||||
}
|
||||
|
||||
func CheckPath(cmd string) (string, error) {
|
||||
path, err := exec.LookPath(cmd)
|
||||
fmt.Println(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to find %s: %v", cmd, err)
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func Compile64(loaderPath string, make string) error {
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd := exec.Command(make, "x64")
|
||||
cmd.Dir = loaderPath
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
} else {
|
||||
cmd := exec.Command("cd " + loaderPath + " && " + make + " x64")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
}
|
||||
|
||||
func Compile32(loaderPath string, make string) error {
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd := exec.Command(make, "x86")
|
||||
cmd.Dir = loaderPath
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
} else {
|
||||
cmd := exec.Command("cd " + loaderPath + " && " + make + " x86")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
}
|
||||
|
||||
func CompileLoader(ldrPath string) error {
|
||||
makes := []string{"make", "mingw32-make.exe"}
|
||||
for _, make := range makes {
|
||||
path_to_make, err := CheckPath(make)
|
||||
if err == nil {
|
||||
err = Compile64(ldrPath, path_to_make)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = Compile32(ldrPath, path_to_make)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("failed to find make or mingw32-make.exe")
|
||||
}
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"ldrgen/cmd/generator"
|
||||
"ldrgen/cmd/utils"
|
||||
|
||||
"github.com/chzyer/readline"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var lintCmd = &cobra.Command{
|
||||
Use: "lint",
|
||||
Short: "Lint a template for errors and warnings",
|
||||
Long: `Lint a template for errors and warnings`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
template_path, _ := cmd.Flags().GetString("template")
|
||||
|
||||
utils.PrintBanner()
|
||||
|
||||
message := fmt.Sprintf("Linting template: '%s'", color.New(color.Bold).Sprintf("%s", template_path))
|
||||
utils.PrintInfo(message, true)
|
||||
|
||||
/*
|
||||
@ generate.ReadConfig(template_path) can error out, so we'll rewrite a function with error handling and linting in mind
|
||||
*/
|
||||
|
||||
cfg, err := generate.ReadConfig(template_path)
|
||||
if err != nil {
|
||||
utils.PrintError(fmt.Sprintf("Error reading config: %s", err), true)
|
||||
return
|
||||
}
|
||||
|
||||
num_ldrs := len(cfg.Loader)
|
||||
if num_ldrs == 0 {
|
||||
utils.PrintError("No loaders found in the config", true)
|
||||
return
|
||||
}
|
||||
|
||||
message = fmt.Sprintf("Successfully read %s loader(s) from the config", color.New(color.Bold).Sprintf("%d", num_ldrs))
|
||||
utils.PrintSuccess(message, true)
|
||||
|
||||
/* Ldr path is always in the same cwd as the config */
|
||||
ldr_path := strings.TrimSuffix(template_path, "config.yaml")
|
||||
|
||||
utils.PrintNewLine()
|
||||
|
||||
rl, err := readline.New("> ")
|
||||
if err != nil {
|
||||
utils.PrintError(fmt.Sprintf("Error creating readline: %s", err), true)
|
||||
return
|
||||
}
|
||||
defer rl.Close()
|
||||
|
||||
PrintAllLdrs(cfg)
|
||||
|
||||
for {
|
||||
utils.PrintNewLine()
|
||||
|
||||
utils.PrintInfo("Enter a token to lint", true)
|
||||
line, err := rl.Readline()
|
||||
if err != nil {
|
||||
utils.PrintError(fmt.Sprintf("Error reading input: %s", err), true)
|
||||
return
|
||||
}
|
||||
|
||||
switch line {
|
||||
case "clear":
|
||||
utils.ClearScreen()
|
||||
continue
|
||||
|
||||
case "help":
|
||||
utils.PrintNewLine()
|
||||
utils.PrintInfo("Available commands:", true)
|
||||
utils.Print("- clear: clear the screen", true)
|
||||
utils.Print("- help: show this help message", true)
|
||||
utils.Print("- ldrs: list all loader tokens", true)
|
||||
utils.Print("- exit: exit the linting session", true)
|
||||
|
||||
continue
|
||||
|
||||
case "exit":
|
||||
return
|
||||
|
||||
case "ldrs":
|
||||
|
||||
PrintAllLdrs(cfg)
|
||||
continue
|
||||
|
||||
case "":
|
||||
continue
|
||||
}
|
||||
|
||||
if !generate.TokenExists(line, cfg) {
|
||||
utils.PrintError(fmt.Sprintf("Token '%s' not found in the config", line), true)
|
||||
continue
|
||||
}
|
||||
|
||||
message = fmt.Sprintf("Token information for: %s", color.New(color.Bold).Sprintf("%s", line))
|
||||
utils.PrintInfo(message, true)
|
||||
PrintLdrInformation(cfg, line)
|
||||
|
||||
err = VerifySubstitutions(cfg, line, ldr_path)
|
||||
if err != nil {
|
||||
utils.PrintError(fmt.Sprintf("Error verifying substitutions: %s", err), true)
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func VerifySubstitutions(cfg *generate.Config, token string, ldr_path string) error {
|
||||
utils.PrintNewLine()
|
||||
|
||||
for _, l := range cfg.Loader {
|
||||
if l.Token == token {
|
||||
for _, f := range l.Files {
|
||||
if len(f.Substitutions) != 0 {
|
||||
message := fmt.Sprintf("Found %s substitutions for file: '%s'", color.New(color.Bold).Sprintf("%d", len(f.Substitutions)), color.New(color.Bold).Sprintf("%s", f.SourcePath))
|
||||
utils.PrintInfo(message, true)
|
||||
|
||||
content, err := os.ReadFile(ldr_path + f.SourcePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
message = fmt.Sprintf("Successfully read %s bytes from file: '%s'", color.New(color.Bold).Sprintf("%d", len(content)), color.New(color.Bold).Sprintf("%s", f.SourcePath))
|
||||
utils.PrintSuccess(message, true)
|
||||
|
||||
for _, v := range f.Substitutions {
|
||||
utils.PrintNewLine()
|
||||
message = fmt.Sprintf("Checking: '%s'", color.New(color.Bold).Sprintf("%s", v))
|
||||
utils.PrintInfo(message, true)
|
||||
if !strings.Contains(string(content), v) {
|
||||
return fmt.Errorf("substitution '%s' not found in file '%s'", v, f.SourcePath)
|
||||
}
|
||||
message = fmt.Sprintf("%s: OK", color.New(color.Bold).Sprintf("%s", v))
|
||||
utils.PrintSuccess(message, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func PrintAllLdrs(cfg *generate.Config) {
|
||||
for _, l := range cfg.Loader {
|
||||
fmt.Println("Token:", l.Token)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintLdrInformation(cfg *generate.Config, token string) {
|
||||
for _, l := range cfg.Loader {
|
||||
if l.Token == token {
|
||||
message := fmt.Sprintf("\tToken: %s", color.New(color.Bold).Sprintf("%s", l.Token))
|
||||
utils.Print(message, true)
|
||||
message = fmt.Sprintf("\tMethod: %s", color.New(color.Bold).Sprintf("%s", l.Method))
|
||||
utils.Print(message, true)
|
||||
message = fmt.Sprintf("\tKey Required: %t", l.KeyRequired)
|
||||
utils.Print(message, true)
|
||||
|
||||
if l.EncType != nil {
|
||||
message = fmt.Sprintf("\tEnc Type: %s", color.New(color.Bold).Sprintf("%s", *l.EncType))
|
||||
utils.Print(message, true)
|
||||
}
|
||||
|
||||
for _, f := range l.Files {
|
||||
message = fmt.Sprintf("\tFile: %s", color.New(color.Bold).Sprintf("%s", f.SourcePath))
|
||||
utils.Print(message, true)
|
||||
message = fmt.Sprintf("\t\tOutput: %s", color.New(color.Bold).Sprintf("%s", f.OutputPath))
|
||||
utils.Print(message, true)
|
||||
|
||||
if len(f.Substitutions) != 0 {
|
||||
message = fmt.Sprintf("\t\tSubstitutions: %d", len(f.Substitutions))
|
||||
utils.Print(message, true)
|
||||
for k, v := range f.Substitutions {
|
||||
message = fmt.Sprintf("\t\t\t%s: %s", color.New(color.Bold).Sprintf("%s", k), color.New(color.Bold).Sprintf("%s", v))
|
||||
utils.Print(message, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
lintCmd.Flags().StringP("template", "t", "", "Path to the template to lint")
|
||||
lintCmd.MarkFlagRequired("template")
|
||||
}
|
||||
@@ -44,3 +44,15 @@ func Execute() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(lintCmd)
|
||||
rootCmd.AddCommand(generateCmd)
|
||||
|
||||
/* Disable default completion command */
|
||||
rootCmd.Root().CompletionOptions.DisableDefaultCmd = true
|
||||
rootCmd.Root().CompletionOptions.DisableDescriptions = true
|
||||
|
||||
/* Disable help command */
|
||||
rootCmd.SetHelpCommand(&cobra.Command{Use: "no-help", Run: func(cmd *cobra.Command, args []string) { /* Do nothing */ }})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
func PrintBanner() {
|
||||
fmt.Println(`
|
||||
⠀⢸⠓⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⢸⠀⠀⠑⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⢸⡆⠀⠀⠀⠙⢤⡷⣤⣦⣀⠤⠖⠚⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⣠⡿⠢⢄⡀⠀⡇⠀⠀⠀⠀⠀⠉⠀⠀⠀⠀⠀⠸⠷⣶⠂⠀⠀⠀⣀⣀⠀⠀⠀
|
||||
⢸⣃⠀⠀⠉⠳⣷⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠉⠉⢉⡭⠋
|
||||
⠀⠘⣆⠀⠀⠀⠁⠀⢀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠋⠀⠀
|
||||
⠀⠀⠘⣦⠆⠀⠀⢀⡎⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⡀⣠⠔⠋⠀⠀⠀⠀
|
||||
⠀⠀⠀⡏⠀⠀⣆⠘⣄⠸⢧⠀⠀⠀⠀⢀⣠⠖⢻⠀⠀⠀⣿⢥⣄⣀⣀⣀⠀⠀
|
||||
⠀⠀⢸⠁⠀⠀⡏⢣⣌⠙⠚⠀⠀⠠⣖⡛⠀⣠⠏⠀⠀⠀⠇⠀⠀⠀⠀⢙⣣⠄
|
||||
⠀⠀⢸⡀⠀⠀⠳⡞⠈⢻⠶⠤⣄⣀⣈⣉⣉⣡⡔⠀⠀⢀⠀⠀⣀⡤⠖⠚⠀⠀
|
||||
⠀⠀⡼⣇⠀⠀⠀⠙⠦⣞⡀⠀⢀⡏⠀⢸⣣⠞⠀⠀⠀⡼⠚⠋⠁⠀⠀⠀⠀⠀
|
||||
⠀⢰⡇⠙⠀⠀⠀⠀⠀⠀⠉⠙⠚⠒⠚⠉⠀⠀⠀⠀⡼⠁⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⢧⡀⠀⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠙⣶⣶⣿⠢⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠉⠀⠀⠀⠙⢿⣳⠞⠳⡄⠀⠀⠀⢀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠀⠀⠹⣄⣀⡤⠋⠀⠀⠀⠀⠀
|
||||
`)
|
||||
}
|
||||
|
||||
func PrintError(msg string, clr bool) {
|
||||
if clr {
|
||||
fmt.Print(color.HiRedString("[!] " + msg + "\n"))
|
||||
} else {
|
||||
fmt.Println("[!] " + msg)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintSuccess(msg string, clr bool) {
|
||||
if clr {
|
||||
fmt.Print(color.HiGreenString("[+] " + msg + "\n"))
|
||||
} else {
|
||||
fmt.Println("[+] " + msg)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintInfo(msg string, clr bool) {
|
||||
if clr {
|
||||
fmt.Print(color.HiWhiteString("[*] " + msg + "\n"))
|
||||
} else {
|
||||
fmt.Println("[*] " + msg)
|
||||
}
|
||||
}
|
||||
|
||||
func Print(msg string, clr bool) {
|
||||
if clr {
|
||||
fmt.Print(color.HiWhiteString(msg) + "\n")
|
||||
} else {
|
||||
fmt.Print(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintWhite(msg string) {
|
||||
fmt.Println(color.HiWhiteString(msg))
|
||||
}
|
||||
|
||||
func PrintNewLine() {
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func ClearScreen() {
|
||||
fmt.Print("\033[H\033[2J")
|
||||
}
|
||||
+22
@@ -8,6 +8,28 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/term v0.6.0 // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/bubbletea v0.25.0
|
||||
github.com/chzyer/readline v1.5.1
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
)
|
||||
|
||||
+48
@@ -1,11 +1,59 @@
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
|
||||
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
|
||||
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
|
||||
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
|
||||
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
|
||||
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
||||
@@ -19,6 +19,9 @@ OUTPUT := implant
|
||||
all:
|
||||
@echo "Usage: make [x64 | x86]"
|
||||
|
||||
.PHONY: both
|
||||
both: x64 x86
|
||||
|
||||
.PHONY: x64
|
||||
x64: $(BIN_DIR)/$(OUTPUT)_x64.exe
|
||||
|
||||
|
||||
Reference in New Issue
Block a user