├── GUI.go ├── README.md ├── build-gui.cmd ├── config.go ├── decode.go ├── encode.go ├── go.mod ├── go.sum ├── instructions.go ├── keystone.dll ├── obfuscate.go ├── sgn.go ├── sgngui.go └── sgngui ├── config.go ├── decode.go ├── encode.go ├── go.mod ├── go.sum ├── instructions.go ├── obfuscate.go ├── sgn.go └── sgngui.go /GUI.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "os/exec" 7 | "sgngui" 8 | "strings" 9 | "syscall" 10 | 11 | "fyne.io/fyne/v2" 12 | "fyne.io/fyne/v2/app" 13 | "fyne.io/fyne/v2/canvas" 14 | "fyne.io/fyne/v2/container" 15 | "fyne.io/fyne/v2/widget" 16 | ) 17 | 18 | func buildCommand(params *sgngui.Options) string { 19 | args := []string{ 20 | "sgn.exe", 21 | "-i", params.Input, 22 | "-o", params.Output, 23 | "-a", fmt.Sprintf("%d", params.Arch), 24 | "-c", fmt.Sprintf("%d", params.EncCount), 25 | "-M", fmt.Sprintf("%d", params.ObsLevel), 26 | } 27 | 28 | if params.PlainDecoder { 29 | args = append(args, "-plain") 30 | } 31 | if params.AsciiPayload { 32 | args = append(args, "-ascii") 33 | } 34 | if params.Safe { 35 | args = append(args, "-S") 36 | } 37 | if params.BadChars != "" { 38 | args = append(args, "-badchars", params.BadChars) 39 | } 40 | if params.Verbose { 41 | args = append(args, "-v") 42 | } 43 | 44 | return strings.Join(args, " ") 45 | } 46 | 47 | func main() { 48 | myApp := app.New() 49 | myWindow := myApp.NewWindow("Sh311C0d3CryPt0") 50 | statusLabel := canvas.NewText("Empty*", color.RGBA{255, 0, 0, 255}) 51 | outputPathLabel := canvas.NewText("", color.RGBA{0, 0, 255, 255}) 52 | 53 | var params *sgngui.Options 54 | 55 | startButton := widget.NewButton("sgnCONFIG", func() { 56 | sgngui.ShowGUI(myWindow, statusLabel, func(updatedOptions *sgngui.Options) { 57 | params = updatedOptions 58 | }) 59 | }) 60 | 61 | buildButton := widget.NewButton("Build", func() { 62 | if params == nil { 63 | statusLabel.Text = "Error: Parameters not configured" 64 | statusLabel.Color = color.RGBA{255, 0, 0, 255} 65 | statusLabel.Refresh() 66 | return 67 | } 68 | statusLabel.Text = "Progressing" 69 | statusLabel.Color = color.RGBA{255, 255, 0, 255} 70 | statusLabel.Refresh() 71 | 72 | command := buildCommand(params) 73 | fmt.Println("Executing command:", command) 74 | cmd := exec.Command("cmd", "/C", command) 75 | 76 | cmd.SysProcAttr = &syscall.SysProcAttr{ 77 | HideWindow: true, 78 | } 79 | 80 | err := cmd.Run() 81 | if err != nil { 82 | statusLabel.Text = "Error: Command failed" 83 | statusLabel.Color = color.RGBA{255, 0, 0, 255} 84 | } else { 85 | statusLabel.Text = "Success" 86 | statusLabel.Color = color.RGBA{0, 255, 0, 255} 87 | outputPathLabel.Text = "Generated file: " + params.Output 88 | outputPathLabel.Refresh() 89 | } 90 | statusLabel.Refresh() 91 | }) 92 | 93 | content := container.NewVBox( 94 | container.NewHBox(startButton, statusLabel), 95 | buildButton, 96 | outputPathLabel, 97 | ) 98 | myWindow.SetContent(content) 99 | defaultSize := myWindow.Canvas().Size() 100 | myWindow.Resize(defaultSize.Add(fyne.NewSize(defaultSize.Width*0.3, defaultSize.Height*0.3))) 101 | myWindow.SetFixedSize(true) 102 | myWindow.ShowAndRun() 103 | } 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sgn-donut-Bypass-GUI 2 | Shellcode encoder&loader written in Go language, which can encrypt binary or PE files. It offers a variety of complex encryption algorithms to choose from, with sgn&donut GUI form. The output files include the encrypted binary files and an EXE file compiled using the built-in compiler. 3 | ### **Preversion_v0.0.1** 4 | Only a GUI of sgn encoder, written in Go , nothing shine 5 | PLEASE MAKE SURE sgn.exe and GUI.exe are under the same folder 6 | ![0240519](https://github.com/A1bu5/sgn-donut-Bypass-GUI/assets/170033147/02aec086-085e-4d3e-9c75-fc7c2547493d) 7 | ![图片](https://github.com/A1bu5/sgn-donut-Bypass-GUI/assets/170033147/fd7a2ed8-4f2f-4f7b-a68b-d23fb73e01a9) 8 | 9 | **MUCH MUCH** more function will be add **SOON** 10 | To DO: 11 | 1. Donut (Change exe to RAW) 12 | 2. **Shellcode Insert with Random AI algorithm with built in decoder-generate 13 | 3. MORE BYPASS OPTIONs VEH/SEH/DLL etc. 14 | 4. Command&Control built in** 15 | 5. MUCH MORE 16 | Out of the self-confidence of SGN's author and its epic bypassAV ability, I first integrated sgn code today, but then realised that it's really not necessary, rather than just calling the compiled PE file. The next step, which is in a few days, is that I'll do a secondary development of Donut and integrate it into the software for further operations. Then I now have unique ideas, out of the current AI scanner for each no-kill tool's features recognition ability is too strong, not conducive to the red team, I decided to use my existing AI foundation, working on video, pictures, audio and a variety of other files shellcode insertion, and this step is not simply stuffed into the file, but after my development of a unique random algorithm, to achieve multiple characters corresponding to one character of random passwords, and compiled the decryptor into implant, and also used SEH, VEH, multi-threaded injection, etc., to achieve bypass. But the workload is large, and my life has been in a lot of difficulties recently, so please help me to continue my life and project development. 17 | Plz DONATE For PROJECT&My life and wife and child 18 | 19 | USDT-TRON:TCwYZDuTsxkaNRszya7p5dnKVheovLkbcu 20 | 21 | 22 | 23 | XMR:88cRmE9GTCUd4vb5HkgbeeAqpvbxANjxSCXNjwSqwNdxYHYhe9zex1FiuG2qA2RR6Y6KB1irZ1iC46kXetjuJk2j8U324H5 24 | 25 | ![图片](https://github.com/A1bu5/sgn-donut-Bypass-GUI/assets/170033147/c8d4daaf-1b48-4806-84d2-3658b70b3d8c) 26 | 27 | 28 | 29 | BTC:bc1qj4sztr0r4r6z6s4qxg0wfpqe43lyyuv7ljr8qdmep7s307yvwe0qjr4yxf 30 | 31 | 32 | ![图片](https://github.com/A1bu5/sgn-donut-Bypass-GUI/assets/170033147/37852b7d-5a68-4a01-9ce8-df0442e8ca06) 33 | 34 | Plz DONATE For PROJECT&My life and wife and child 35 | EVERY single dollar is great mean to me! 36 | -------------------------------------------------------------------------------- /build-gui.cmd: -------------------------------------------------------------------------------- 1 | go build -ldflags "-H windowsgui" -o Sh311C0d3CryPt0.exe -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "errors" 5 | 6 | "fyne.io/fyne/v2" 7 | "fyne.io/fyne/v2/dialog" 8 | ) 9 | 10 | var ( 11 | Version = "?" 12 | ) 13 | 14 | type Options struct { 15 | Input string 16 | Output string 17 | Arch int 18 | EncCount int 19 | ObsLevel int 20 | PlainDecoder bool 21 | AsciiPayload bool 22 | Safe bool 23 | BadChars string 24 | Verbose bool 25 | } 26 | 27 | func ValidateOptions(opts *Options, window fyne.Window) error { 28 | if opts.Input == "" { 29 | dialog.ShowError(errors.New("input file parameter is mandatory"), window) 30 | return errors.New("input file parameter is mandatory") 31 | } 32 | if opts.Output == "" { 33 | dialog.ShowError(errors.New("output file parameter is mandatory"), window) 34 | return errors.New("output file parameter is mandatory") 35 | } 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /decode.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | // STUB will contain the decoder stub for the selected architecture 11 | // Values will be set on init 12 | var STUB map[int]string 13 | 14 | // x86DecoderStub is base decoder assembly for 32 bit binaries 15 | const X86_DECODER_STUB = ` 16 | CALL getip 17 | getip: 18 | POP {R} 19 | MOV ECX,{S} 20 | MOV {RL},{K} 21 | decode: 22 | XOR BYTE PTR [{R}+ECX+data-6],{RL} 23 | ADD {RL},BYTE PTR [{R}+ECX+data-6] 24 | LOOP decode 25 | data: 26 | ` 27 | 28 | // x64DecoderStub is base decoder assembly for 64 bit binaries 29 | const X64_DECODER_STUB = ` 30 | MOV {RL},{K} 31 | MOV RCX,{S} 32 | LEA {R},[RIP+data-1] 33 | decode: 34 | XOR BYTE PTR [{R}+RCX],{RL} 35 | ADD {RL},BYTE PTR [{R}+RCX] 36 | LOOP decode 37 | data: 38 | ` 39 | 40 | // NewDecoderAssembly creates a unobfuscated decoder stub to the given encoded payload 41 | // with the given architecture and seed value 42 | func (encoder *Encoder) NewDecoderAssembly(payloadSize int) (string, error) { 43 | 44 | decoder := STUB[encoder.architecture] 45 | reg, err := encoder.GetSafeRandomRegister(encoder.architecture, "ECX") 46 | if err != nil { 47 | return "", err 48 | } 49 | 50 | regL, err := encoder.GetSafeRandomRegister(8, reg, "CL") 51 | if err != nil { 52 | return "", err 53 | } 54 | 55 | decoder = strings.ReplaceAll(decoder, "{R}", reg) 56 | decoder = strings.ReplaceAll(decoder, "{RL}", regL) 57 | decoder = strings.ReplaceAll(decoder, "{K}", fmt.Sprintf("0x%x", encoder.Seed)) 58 | decoder = strings.ReplaceAll(decoder, "{S}", fmt.Sprintf("0x%x", payloadSize)) 59 | // fmt.Println(decoder) 60 | return decoder, nil 61 | } 62 | 63 | // AddADFLDecoder creates decoder stub for binaries that are ciphered with CipherADFL function. 64 | func (encoder *Encoder) AddADFLDecoder(payload []byte) ([]byte, error) { 65 | decoderAssembly, err := encoder.NewDecoderAssembly(len(payload)) 66 | if err != nil { 67 | return nil, err 68 | } 69 | decoder, ok := encoder.Assemble(decoderAssembly) 70 | if !ok { 71 | return nil, errors.New("decoder assembly failed") 72 | } 73 | return append(decoder, payload...), nil 74 | } 75 | 76 | // AddSchemaDecoder creates decoder stub for binaries that are ciphered with SchemaCipher function. 77 | // The schema array that is used on the given payload, architecture of the payload and obfuscation level is required. 78 | func (encoder *Encoder) AddSchemaDecoder(payload []byte, schema SCHEMA) ([]byte, error) { 79 | 80 | index := 0 81 | // Add garbage instrctions before the ciphered decoder stub 82 | garbage, err := encoder.GenerateGarbageInstructions() 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | // Add call instruction over the ciphered payload 88 | payload, err = encoder.AddCallOver(payload) 89 | if err != nil { 90 | return nil, err 91 | } 92 | 93 | payload = append(garbage, payload...) 94 | index += len(garbage) 95 | 96 | // Add garbage instrctions after the ciphered decoder stub 97 | garbage, err = encoder.GenerateGarbageInstructions() 98 | if err != nil { 99 | return nil, err 100 | } 101 | payload = append(payload, garbage...) 102 | 103 | reg, err := encoder.GetSafeRandomRegister(encoder.architecture, encoder.GetStackPointer()) 104 | if err != nil { 105 | return nil, err 106 | } 107 | 108 | pop, ok := encoder.Assemble(fmt.Sprintf("POP %s;", reg)) // !! 109 | if !ok { 110 | return nil, errors.New("schema decoder assembly failed") 111 | } 112 | payload = append(payload, pop...) 113 | 114 | for _, cursor := range schema { 115 | 116 | // Mandatory obfuscation with coin flip for true polimorphism 117 | garbage, err = encoder.GenerateGarbageInstructions() 118 | if err != nil { 119 | return nil, err 120 | } 121 | payload = append(payload, garbage...) 122 | 123 | stepAssembly := "" 124 | if cursor.Key == nil { 125 | stepAssembly += fmt.Sprintf("\t%s DWORD PTR [%s+0x%x];\n", cursor.OP, reg, index) 126 | } else { 127 | stepAssembly += fmt.Sprintf("\t%s DWORD PTR [%s+0x%x],0x%x;\n", cursor.OP, reg, index, binary.BigEndian.Uint32(cursor.Key)) 128 | } 129 | //fmt.Println(stepAssembly) 130 | decipherStep, ok := encoder.Assemble(stepAssembly) 131 | if !ok { 132 | //fmt.Println(stepAssembly) 133 | return nil, errors.New("schema decoder step assembly failed") 134 | } 135 | payload = append(payload, decipherStep...) 136 | index += 4 137 | } 138 | 139 | returnInstruction, ok := encoder.Assemble(fmt.Sprintf("jmp %s;", reg)) 140 | if !ok { 141 | return nil, errors.New("schema decoder return assembly failed") 142 | } 143 | 144 | return append(payload, returnInstruction...), nil 145 | } 146 | -------------------------------------------------------------------------------- /encode.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "fmt" 7 | "math/bits" 8 | "math/rand" 9 | "strings" 10 | 11 | "github.com/olekukonko/tablewriter" 12 | ) 13 | 14 | // OPERANDS string array containing logical & arithmetic operands 15 | // for encoding the decoder stub 16 | var OPERANDS = []string{"XOR", "SUB", "ADD", "ROL", "ROR", "NOT"} 17 | 18 | // SCHEMA contains the operand and keys to apply single step encoding 19 | type SCHEMA []struct { 20 | OP string 21 | Key []byte 22 | } 23 | 24 | // Encoder struct for keeping encoder specs 25 | type Encoder struct { 26 | architecture int 27 | ObfuscationLimit int 28 | PlainDecoder bool 29 | Seed byte 30 | EncodingCount int 31 | SaveRegisters bool 32 | } 33 | 34 | // NewEncoder for creating new encoder structures 35 | func NewEncoder(arch int) (*Encoder, error) { 36 | // Create with default settings 37 | encoder := Encoder{ 38 | ObfuscationLimit: 50, 39 | PlainDecoder: false, 40 | Seed: GetRandomByte(), 41 | EncodingCount: 1, 42 | SaveRegisters: false, 43 | } 44 | 45 | switch arch { 46 | case 32: 47 | encoder.architecture = 32 48 | case 64: 49 | encoder.architecture = 64 50 | default: 51 | return nil, errors.New("invalid architecture") 52 | } 53 | 54 | return &encoder, nil 55 | } 56 | 57 | // SetArchitecture sets the encoder architecture 58 | func (encoder *Encoder) SetArchitecture(arch int) error { 59 | switch arch { 60 | case 32: 61 | encoder.architecture = 32 62 | case 64: 63 | encoder.architecture = 64 64 | default: 65 | return errors.New("invalid architecture") 66 | } 67 | return nil 68 | } 69 | 70 | // GetArchitecture returns the encoder architecture 71 | func (encoder *Encoder) GetArchitecture() int { 72 | return encoder.architecture 73 | } 74 | 75 | // Encode function is the primary encode method for SGN 76 | // all necessary options and parameters are contained inside the encoder struct 77 | func (encoder *Encoder) Encode(payload []byte) ([]byte, error) { 78 | var final []byte 79 | if encoder.SaveRegisters { 80 | payload = append(payload, SafeRegisterSuffix[encoder.architecture]...) 81 | } 82 | 83 | // Add garbage instructions before the un-encoded payload 84 | garbage, err := encoder.GenerateGarbageInstructions() 85 | if err != nil { 86 | return nil, err 87 | } 88 | payload = append(garbage, payload...) 89 | 90 | // Apply ADFL cipher to payload 91 | cipheredPayload := CipherADFL(payload, encoder.Seed) 92 | encodedPayload, err := encoder.AddADFLDecoder(cipheredPayload) 93 | if err != nil { 94 | return nil, err 95 | } 96 | 97 | if encoder.PlainDecoder { 98 | final = encodedPayload 99 | } else { 100 | // Add more garbage instructions before the decoder stub 101 | garbage, err = encoder.GenerateGarbageInstructions() 102 | if err != nil { 103 | return nil, err 104 | } 105 | encodedPayload = append(garbage, encodedPayload...) 106 | 107 | // Calculate schema size 108 | schemaSize := ((len(encodedPayload) - len(cipheredPayload)) / (encoder.architecture / 8)) + 1 109 | randomSchema := encoder.NewCipherSchema(schemaSize) 110 | 111 | obfuscatedEncodedPayload := encoder.SchemaCipher(encodedPayload, 0, randomSchema) 112 | final, err = encoder.AddSchemaDecoder(obfuscatedEncodedPayload, randomSchema) 113 | if err != nil { 114 | return nil, err 115 | } 116 | } 117 | 118 | if encoder.EncodingCount > 1 { 119 | encoder.EncodingCount-- 120 | encoder.Seed = GetRandomByte() 121 | final, err = encoder.Encode(final) 122 | if err != nil { 123 | return nil, err 124 | } 125 | } 126 | 127 | if encoder.SaveRegisters { 128 | final = append(SafeRegisterPrefix[encoder.architecture], final...) 129 | } 130 | 131 | return final, nil 132 | } 133 | 134 | // CipherADFL (Additive Feedback Loop) performs an additive feedback XOR operation 135 | // similar to LFSR (Linear-feedback shift register) IN REVERSE ORDER !! with the supplied seed 136 | func CipherADFL(data []byte, seed byte) []byte { 137 | for i := 1; i < len(data)+1; i++ { 138 | current := data[len(data)-i] 139 | data[len(data)-i] ^= seed 140 | seed = byte((int(current) + int(seed)) % 256) 141 | } 142 | return data 143 | } 144 | 145 | // SchemaCipher encodes a part of the given binary starting from the given index. 146 | // Encoding done without using any loop conditions based on the schema values. 147 | // Function performs logical/arithmetic operations given in the schema array. 148 | // If invalid operand supplied function returns nil 149 | func (encoder *Encoder) SchemaCipher(data []byte, index int, schema SCHEMA) []byte { 150 | for _, cursor := range schema { 151 | switch cursor.OP { 152 | case "XOR": 153 | binary.BigEndian.PutUint32(data[index:index+4], (binary.BigEndian.Uint32(data[index:index+4]) ^ binary.LittleEndian.Uint32(cursor.Key))) 154 | case "ADD": 155 | binary.LittleEndian.PutUint32(data[index:index+4], (binary.LittleEndian.Uint32(data[index:index+4])-binary.BigEndian.Uint32(cursor.Key))%0xFFFFFFFF) 156 | case "SUB": 157 | binary.LittleEndian.PutUint32(data[index:index+4], (binary.LittleEndian.Uint32(data[index:index+4])+binary.BigEndian.Uint32(cursor.Key))%0xFFFFFFFF) 158 | case "ROL": 159 | binary.LittleEndian.PutUint32(data[index:index+4], bits.RotateLeft32(binary.LittleEndian.Uint32(data[index:index+4]), -int(binary.BigEndian.Uint32(cursor.Key)))) 160 | case "ROR": 161 | binary.LittleEndian.PutUint32(data[index:index+4], bits.RotateLeft32(binary.LittleEndian.Uint32(data[index:index+4]), int(binary.BigEndian.Uint32(cursor.Key)))) 162 | case "NOT": 163 | binary.BigEndian.PutUint32(data[index:index+4], (^binary.BigEndian.Uint32(data[index : index+4]))) 164 | } 165 | index += 4 166 | } 167 | return data 168 | } 169 | 170 | // RandomOperand generates a random operand string 171 | func RandomOperand() string { 172 | return OPERANDS[rand.Intn(len(OPERANDS))] 173 | } 174 | 175 | // GetRandomByte generates a random single byte 176 | func GetRandomByte() byte { 177 | return byte(rand.Intn(255)) 178 | } 179 | 180 | // GetRandomBytes generates a random byte slice with given size 181 | func GetRandomBytes(num int) []byte { 182 | slice := make([]byte, num) 183 | for i := range slice { 184 | slice[i] = GetRandomByte() 185 | } 186 | return slice 187 | } 188 | 189 | // CoinFlip implements a coin flip which returns true/false 190 | func CoinFlip() bool { 191 | return rand.Intn(2) == 0 192 | } 193 | 194 | // NewCipherSchema generates random schema for 195 | // using in the SchemaCipher function. 196 | // Generated schema contains random operands and keys. 197 | func (encoder *Encoder) NewCipherSchema(num int) SCHEMA { 198 | schema := make(SCHEMA, num) 199 | 200 | for i, cursor := range schema { 201 | cursor.OP = RandomOperand() 202 | if cursor.OP == "NOT" { 203 | cursor.Key = nil 204 | } else if cursor.OP == "ROL" || cursor.OP == "ROR" { 205 | cursor.Key = []byte{0, 0, 0, GetRandomByte()} 206 | } else { 207 | cursor.Key = GetRandomBytes(4) 208 | } 209 | schema[i] = cursor 210 | } 211 | return schema 212 | } 213 | 214 | // GetSchemaTable returns the printable encoder schema table 215 | func GetSchemaTable(schema SCHEMA) string { 216 | data := &strings.Builder{} 217 | table := tablewriter.NewWriter(data) 218 | table.SetHeader([]string{"OPERAND", "KEY"}) 219 | for _, cursor := range schema { 220 | if cursor.Key == nil { 221 | table.Append([]string{cursor.OP, "0x00000000"}) 222 | } else { 223 | table.Append([]string{cursor.OP, fmt.Sprintf("0x%x", cursor.Key)}) 224 | } 225 | } 226 | table.Render() 227 | 228 | return data.String() 229 | } 230 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module config.go 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | fyne.io/fyne/v2 v2.4.5 7 | github.com/EgeBalci/keystone-go v0.0.0-20200525180613-e6c7cd32ceae 8 | github.com/olekukonko/tablewriter v0.0.5 9 | ) 10 | 11 | require ( 12 | github.com/fredbi/uri v1.0.0 // indirect 13 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect 14 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect 15 | github.com/go-text/render v0.1.0 // indirect 16 | github.com/go-text/typesetting v0.1.0 // indirect 17 | github.com/gopherjs/gopherjs v1.17.2 // indirect 18 | github.com/mattn/go-runewidth v0.0.15 // indirect 19 | github.com/rivo/uniseg v0.4.7 // indirect 20 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect 21 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect 22 | github.com/yuin/goldmark v1.5.5 // indirect 23 | golang.org/x/image v0.11.0 // indirect 24 | golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect 25 | golang.org/x/net v0.17.0 // indirect 26 | golang.org/x/sys v0.13.0 // indirect 27 | golang.org/x/text v0.13.0 // indirect 28 | ) 29 | -------------------------------------------------------------------------------- /instructions.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | // ConditionalJumpMnemonics contains the conditional branching instruction mnemonics 4 | var ConditionalJumpMnemonics = []string{ 5 | "JAE", 6 | "JA", 7 | "JBE", 8 | "JB", 9 | "JC", 10 | "JE", 11 | "JGE", 12 | "JG", 13 | "JLE", 14 | "JL", 15 | "JNAE", 16 | "JNA", 17 | "JNBE", 18 | "JNB", 19 | "JNC", 20 | "JNE", 21 | "JNGE", 22 | "JNG", 23 | "JNLE", 24 | "JNL", 25 | "JNO", 26 | "JNP", 27 | "JNS", 28 | "JNZ", 29 | "JO", 30 | "JPE", 31 | "JPO", 32 | "JP", 33 | "JS", 34 | "JZ", 35 | } 36 | 37 | // SafeGarbageInstructions array containing safe garbage instructions 38 | // that does not munipulate registers or stack (do not affect the overall execution of the program) 39 | // !!! These instructions must not clobber registers or stack flags may be affected !!! 40 | var SafeGarbageInstructions = []string{ 41 | ";", // no instruction (empty) 42 | "NOP", 43 | "CLD", 44 | "CLC", 45 | "CMC", 46 | "WAIT", 47 | "FNOP", 48 | "FXAM", 49 | "FTST", 50 | "JMP 2", 51 | "XOR {R},0", 52 | "SUB {R},0", 53 | "ADD {R},0", 54 | "BT {R},{R}", 55 | "CMP {R},{R}", 56 | "MOV {R},{R}", 57 | "XCHG {R},{R}", 58 | "TEST {R},{R}", 59 | "CMOVA {R},{R}", 60 | "CMOVB {R},{R}", 61 | "CMOVC {R},{R}", 62 | "CMOVE {R},{R}", 63 | "CMOVG {R},{R}", 64 | "CMOVL {R},{R}", 65 | "CMOVO {R},{R}", 66 | "CMOVP {R},{R}", 67 | "CMOVS {R},{R}", 68 | "CMOVZ {R},{R}", 69 | "CMOVAE {R},{R}", 70 | "CMOVGE {R},{R}", 71 | "CMOVLE {R},{R}", 72 | "CMOVNA {R},{R}", 73 | "CMOVNB {R},{R}", 74 | "CMOVNC {R},{R}", 75 | "CMOVNE {R},{R}", 76 | "CMOVNG {R},{R}", 77 | "CMOVNL {R},{R}", 78 | "CMOVNO {R},{R}", 79 | "CMOVNP {R},{R}", 80 | "CMOVNS {R},{R}", 81 | "CMOVNZ {R},{R}", 82 | "CMOVPE {R},{R}", 83 | "CMOVPO {R},{R}", 84 | "CMOVBE {R},{R}", 85 | "CMOVNAE {R},{R}", 86 | "CMOVNBE {R},{R}", 87 | "CMOVNLE {R},{R}", 88 | "CMOVNGE {R},{R}", 89 | // Recursion starts here... 90 | "JMP {L};{G};{L}:", 91 | "NOT {R};{G};NOT {R}", 92 | "NEG {R};{G};NEG {R}", 93 | "INC {R};{G};DEC {R}", 94 | "DEC {R};{G};INC {R}", 95 | "PUSH {R};{G};POP {R}", 96 | "BSWAP {R};{G};BSWAP {R}", 97 | "ADD {R},{K};{G};SUB {R},{K}", 98 | "SUB {R},{K};{G};ADD {R},{K}", 99 | "ROR {R},{K};{G};ROL {R},{K}", 100 | "ROL {R},{K};{G};ROR {R},{K}", 101 | } 102 | 103 | // SupportedOperandTypes contains all operand types supported by SGN 104 | var SupportedOperandTypes = []string{ 105 | "imm8", 106 | "imm16", 107 | "imm32", 108 | "imm64", 109 | "r8", 110 | "r16", 111 | "r32", 112 | "r64", 113 | "r/m8", 114 | "r/m16", 115 | "r/m32", 116 | "r/m64", 117 | "m", 118 | "m8", 119 | "m16", 120 | "m32", 121 | "m64", 122 | "RAX", 123 | "RCX", 124 | "RDX", 125 | "RBX", 126 | "RSP", 127 | "RBP", 128 | "RSI", 129 | "RDI", 130 | "EAX", 131 | "ECX", 132 | "EDX", 133 | "EBX", 134 | "ESP", 135 | "EBP", 136 | "ESI", 137 | "EDI", 138 | "AX", 139 | "CX", 140 | "DX", 141 | "BX", 142 | "SP", 143 | "BP", 144 | "SI", 145 | "DI", 146 | "AH", 147 | "AL", 148 | "CH", 149 | "CL", 150 | "DH", 151 | "DL", 152 | "BH", 153 | "BL", 154 | "SPL", 155 | "BPL", 156 | "SIL", 157 | "DIL", 158 | } 159 | 160 | // JMP 2 -> Jumps to next instruction 161 | // func addGarbageJumpMnemonics() { 162 | // // for _, i := range ConditionalJumpMnemonics { 163 | // // GarbageMnemonics = append(GarbageMnemonics, i+" 2") 164 | // // } 165 | 166 | // for _, i := range ConditionalJumpMnemonics { 167 | // GarbageMnemonics = append(GarbageMnemonics, i+" {L};{G};{L}:") 168 | // } 169 | // } 170 | 171 | /* 172 | !! BLACKLISTED INSTRUCTIONS !! 173 | 174 | * XCHG 175 | * UD1 176 | * CMPXCHG 177 | * CMPXCHG8B 178 | 179 | */ 180 | 181 | // INSTRUCTIONS contains the ENTIRE x86/x64 instruction set 182 | const INSTRUCTIONS string = ` 183 | 184 | 185 | [ 186 | { 187 | "Mnemonic": "AAD", 188 | "V64": true, 189 | "V32": true, 190 | "Operands": [ 191 | { 192 | "Types": [ 193 | "imm8" 194 | ] 195 | } 196 | ] 197 | }, 198 | { 199 | "Mnemonic": "AAM", 200 | "V64": true, 201 | "V32": true, 202 | "Operands": [ 203 | { 204 | "Types": [ 205 | "imm8" 206 | ] 207 | } 208 | ] 209 | }, 210 | { 211 | "Mnemonic": "ADC", 212 | "V64": true, 213 | "V32": true, 214 | "Operands": [ 215 | { 216 | "Types": [ 217 | "AL", 218 | "AX", 219 | "EAX", 220 | "RAX", 221 | "r/m8", 222 | "r/m8", 223 | "r/m16", 224 | "r/m32", 225 | "r/m64", 226 | "r/m16", 227 | "r/m32", 228 | "r/m64", 229 | "r/m8", 230 | "r/m8", 231 | "r/m16", 232 | "r/m32", 233 | "r/m64", 234 | "r8", 235 | "r8", 236 | "r16", 237 | "r32", 238 | "r64" 239 | ] 240 | }, 241 | { 242 | "Types": [ 243 | "imm8", 244 | "imm16", 245 | "imm32", 246 | "imm32", 247 | "imm8", 248 | "imm8", 249 | "imm16", 250 | "imm32", 251 | "imm32", 252 | "imm8", 253 | "imm8", 254 | "imm8", 255 | "r8", 256 | "r8", 257 | "r16", 258 | "r32", 259 | "r64", 260 | "r/m8", 261 | "r/m8", 262 | "r/m16", 263 | "r/m32", 264 | "r/m64" 265 | ] 266 | } 267 | ] 268 | }, 269 | { 270 | "Mnemonic": "ADCX", 271 | "V64": true, 272 | "V32": true, 273 | "Operands": [ 274 | { 275 | "Types": [ 276 | "r32", 277 | "r64" 278 | ] 279 | }, 280 | { 281 | "Types": [ 282 | "r/m32", 283 | "r/m64" 284 | ] 285 | } 286 | ] 287 | }, 288 | { 289 | "Mnemonic": "ADD", 290 | "V64": true, 291 | "V32": true, 292 | "Operands": [ 293 | { 294 | "Types": [ 295 | "AL", 296 | "AX", 297 | "EAX", 298 | "RAX", 299 | "r/m8", 300 | "r/m8", 301 | "r/m16", 302 | "r/m32", 303 | "r/m64", 304 | "r/m16", 305 | "r/m32", 306 | "r/m64", 307 | "r/m8", 308 | "r/m8", 309 | "r/m16", 310 | "r/m32", 311 | "r/m64", 312 | "r8", 313 | "r8", 314 | "r16", 315 | "r32", 316 | "r64" 317 | ] 318 | }, 319 | { 320 | "Types": [ 321 | "imm8", 322 | "imm16", 323 | "imm32", 324 | "imm32", 325 | "imm8", 326 | "imm8", 327 | "imm16", 328 | "imm32", 329 | "imm32", 330 | "imm8", 331 | "imm8", 332 | "imm8", 333 | "r8", 334 | "r8", 335 | "r16", 336 | "r32", 337 | "r64", 338 | "r/m8", 339 | "r/m8", 340 | "r/m16", 341 | "r/m32", 342 | "r/m64" 343 | ] 344 | } 345 | ] 346 | }, 347 | { 348 | "Mnemonic": "ADOX", 349 | "V64": true, 350 | "V32": true, 351 | "Operands": [ 352 | { 353 | "Types": [ 354 | "r32", 355 | "r64" 356 | ] 357 | }, 358 | { 359 | "Types": [ 360 | "r/m32", 361 | "r/m64" 362 | ] 363 | } 364 | ] 365 | }, 366 | { 367 | "Mnemonic": "AND", 368 | "V64": true, 369 | "V32": true, 370 | "Operands": [ 371 | { 372 | "Types": [ 373 | "AL", 374 | "AX", 375 | "EAX", 376 | "RAX", 377 | "r/m8", 378 | "r/m8", 379 | "r/m16", 380 | "r/m32", 381 | "r/m64", 382 | "r/m16", 383 | "r/m32", 384 | "r/m64", 385 | "r/m8", 386 | "r/m8", 387 | "r/m16", 388 | "r/m32", 389 | "r/m64", 390 | "r8", 391 | "r8", 392 | "r16", 393 | "r32", 394 | "r64" 395 | ] 396 | }, 397 | { 398 | "Types": [ 399 | "imm8", 400 | "imm16", 401 | "imm32", 402 | "imm32", 403 | "imm8", 404 | "imm8", 405 | "imm16", 406 | "imm32", 407 | "imm32", 408 | "imm8", 409 | "imm8", 410 | "imm8", 411 | "r8", 412 | "r8", 413 | "r16", 414 | "r32", 415 | "r64", 416 | "r/m8", 417 | "r/m8", 418 | "r/m16", 419 | "r/m32", 420 | "r/m64" 421 | ] 422 | } 423 | ] 424 | }, 425 | { 426 | "Mnemonic": "BLSI", 427 | "V64": true, 428 | "V32": true, 429 | "Operands": [ 430 | { 431 | "Types": [ 432 | "r32", 433 | "r64" 434 | ] 435 | }, 436 | { 437 | "Types": [ 438 | "r/m32", 439 | "r/m64" 440 | ] 441 | } 442 | ] 443 | }, 444 | { 445 | "Mnemonic": "BLSMSK", 446 | "V64": true, 447 | "V32": true, 448 | "Operands": [ 449 | { 450 | "Types": [ 451 | "r32", 452 | "r64" 453 | ] 454 | }, 455 | { 456 | "Types": [ 457 | "r/m32", 458 | "r/m64" 459 | ] 460 | } 461 | ] 462 | }, 463 | { 464 | "Mnemonic": "BLSR", 465 | "V64": true, 466 | "V32": true, 467 | "Operands": [ 468 | { 469 | "Types": [ 470 | "r32", 471 | "r64" 472 | ] 473 | }, 474 | { 475 | "Types": [ 476 | "r/m32", 477 | "r/m64" 478 | ] 479 | } 480 | ] 481 | }, 482 | { 483 | "Mnemonic": "BSF", 484 | "V64": true, 485 | "V32": true, 486 | "Operands": [ 487 | { 488 | "Types": [ 489 | "r16", 490 | "r32", 491 | "r64" 492 | ] 493 | }, 494 | { 495 | "Types": [ 496 | "r/m16", 497 | "r/m32", 498 | "r/m64" 499 | ] 500 | } 501 | ] 502 | }, 503 | { 504 | "Mnemonic": "BSR", 505 | "V64": true, 506 | "V32": true, 507 | "Operands": [ 508 | { 509 | "Types": [ 510 | "r16", 511 | "r32", 512 | "r64" 513 | ] 514 | }, 515 | { 516 | "Types": [ 517 | "r/m16", 518 | "r/m32", 519 | "r/m64" 520 | ] 521 | } 522 | ] 523 | }, 524 | { 525 | "Mnemonic": "BSWAP", 526 | "V64": true, 527 | "V32": true, 528 | "Operands": [ 529 | { 530 | "Types": [ 531 | "r32", 532 | "r64" 533 | ] 534 | } 535 | ] 536 | }, 537 | { 538 | "Mnemonic": "BT", 539 | "V64": true, 540 | "V32": true, 541 | "Operands": [ 542 | { 543 | "Types": [ 544 | "r/m16", 545 | "r/m32", 546 | "r/m64", 547 | "r/m16", 548 | "r/m32", 549 | "r/m64" 550 | ] 551 | }, 552 | { 553 | "Types": [ 554 | "r16", 555 | "r32", 556 | "r64", 557 | "imm8", 558 | "imm8", 559 | "imm8" 560 | ] 561 | } 562 | ] 563 | }, 564 | { 565 | "Mnemonic": "BTC", 566 | "V64": true, 567 | "V32": true, 568 | "Operands": [ 569 | { 570 | "Types": [ 571 | "r/m16", 572 | "r/m32", 573 | "r/m64", 574 | "r/m16", 575 | "r/m32", 576 | "r/m64" 577 | ] 578 | }, 579 | { 580 | "Types": [ 581 | "r16", 582 | "r32", 583 | "r64", 584 | "imm8", 585 | "imm8", 586 | "imm8" 587 | ] 588 | } 589 | ] 590 | }, 591 | { 592 | "Mnemonic": "BTR", 593 | "V64": true, 594 | "V32": true, 595 | "Operands": [ 596 | { 597 | "Types": [ 598 | "r/m16", 599 | "r/m32", 600 | "r/m64", 601 | "r/m16", 602 | "r/m32", 603 | "r/m64" 604 | ] 605 | }, 606 | { 607 | "Types": [ 608 | "r16", 609 | "r32", 610 | "r64", 611 | "imm8", 612 | "imm8", 613 | "imm8" 614 | ] 615 | } 616 | ] 617 | }, 618 | { 619 | "Mnemonic": "BTS", 620 | "V64": true, 621 | "V32": true, 622 | "Operands": [ 623 | { 624 | "Types": [ 625 | "r/m16", 626 | "r/m32", 627 | "r/m64", 628 | "r/m16", 629 | "r/m32", 630 | "r/m64" 631 | ] 632 | }, 633 | { 634 | "Types": [ 635 | "r16", 636 | "r32", 637 | "r64", 638 | "imm8", 639 | "imm8", 640 | "imm8" 641 | ] 642 | } 643 | ] 644 | }, 645 | { 646 | "Mnemonic": "CALL", 647 | "V64": true, 648 | "V32": true, 649 | "Operands": [ 650 | { 651 | "Types": [ 652 | "r/m16", 653 | "r/m32", 654 | "r/m64" 655 | ] 656 | } 657 | ] 658 | }, 659 | { 660 | "Mnemonic": "CLFLUSH", 661 | "V64": true, 662 | "V32": true, 663 | "Operands": [ 664 | { 665 | "Types": [ 666 | "m8" 667 | ] 668 | } 669 | ] 670 | }, 671 | { 672 | "Mnemonic": "CLFLUSHOPT", 673 | "V64": true, 674 | "V32": true, 675 | "Operands": [ 676 | { 677 | "Types": [ 678 | "m8" 679 | ] 680 | } 681 | ] 682 | }, 683 | { 684 | "Mnemonic": "CLWB", 685 | "V64": true, 686 | "V32": true, 687 | "Operands": [ 688 | { 689 | "Types": [ 690 | "m8" 691 | ] 692 | } 693 | ] 694 | }, 695 | { 696 | "Mnemonic": "CMOVA", 697 | "V64": true, 698 | "V32": true, 699 | "Operands": [ 700 | { 701 | "Types": [ 702 | "r16", 703 | "r32", 704 | "r64" 705 | ] 706 | }, 707 | { 708 | "Types": [ 709 | "r/m16", 710 | "r/m32", 711 | "r/m64" 712 | ] 713 | } 714 | ] 715 | }, 716 | { 717 | "Mnemonic": "CMOVAE", 718 | "V64": true, 719 | "V32": true, 720 | "Operands": [ 721 | { 722 | "Types": [ 723 | "r16", 724 | "r32", 725 | "r64" 726 | ] 727 | }, 728 | { 729 | "Types": [ 730 | "r/m16", 731 | "r/m32", 732 | "r/m64" 733 | ] 734 | } 735 | ] 736 | }, 737 | { 738 | "Mnemonic": "CMOVB", 739 | "V64": true, 740 | "V32": true, 741 | "Operands": [ 742 | { 743 | "Types": [ 744 | "r16", 745 | "r32", 746 | "r64" 747 | ] 748 | }, 749 | { 750 | "Types": [ 751 | "r/m16", 752 | "r/m32", 753 | "r/m64" 754 | ] 755 | } 756 | ] 757 | }, 758 | { 759 | "Mnemonic": "CMOVBE", 760 | "V64": true, 761 | "V32": true, 762 | "Operands": [ 763 | { 764 | "Types": [ 765 | "r16", 766 | "r32", 767 | "r64" 768 | ] 769 | }, 770 | { 771 | "Types": [ 772 | "r/m16", 773 | "r/m32", 774 | "r/m64" 775 | ] 776 | } 777 | ] 778 | }, 779 | { 780 | "Mnemonic": "CMOVC", 781 | "V64": true, 782 | "V32": true, 783 | "Operands": [ 784 | { 785 | "Types": [ 786 | "r16", 787 | "r32", 788 | "r64" 789 | ] 790 | }, 791 | { 792 | "Types": [ 793 | "r/m16", 794 | "r/m32", 795 | "r/m64" 796 | ] 797 | } 798 | ] 799 | }, 800 | { 801 | "Mnemonic": "CMOVE", 802 | "V64": true, 803 | "V32": true, 804 | "Operands": [ 805 | { 806 | "Types": [ 807 | "r16", 808 | "r32", 809 | "r64" 810 | ] 811 | }, 812 | { 813 | "Types": [ 814 | "r/m16", 815 | "r/m32", 816 | "r/m64" 817 | ] 818 | } 819 | ] 820 | }, 821 | { 822 | "Mnemonic": "CMOVG", 823 | "V64": true, 824 | "V32": true, 825 | "Operands": [ 826 | { 827 | "Types": [ 828 | "r16", 829 | "r32", 830 | "r64" 831 | ] 832 | }, 833 | { 834 | "Types": [ 835 | "r/m16", 836 | "r/m32", 837 | "r/m64" 838 | ] 839 | } 840 | ] 841 | }, 842 | { 843 | "Mnemonic": "CMOVGE", 844 | "V64": true, 845 | "V32": true, 846 | "Operands": [ 847 | { 848 | "Types": [ 849 | "r16", 850 | "r32", 851 | "r64" 852 | ] 853 | }, 854 | { 855 | "Types": [ 856 | "r/m16", 857 | "r/m32", 858 | "r/m64" 859 | ] 860 | } 861 | ] 862 | }, 863 | { 864 | "Mnemonic": "CMOVL", 865 | "V64": true, 866 | "V32": true, 867 | "Operands": [ 868 | { 869 | "Types": [ 870 | "r16", 871 | "r32", 872 | "r64" 873 | ] 874 | }, 875 | { 876 | "Types": [ 877 | "r/m16", 878 | "r/m32", 879 | "r/m64" 880 | ] 881 | } 882 | ] 883 | }, 884 | { 885 | "Mnemonic": "CMOVLE", 886 | "V64": true, 887 | "V32": true, 888 | "Operands": [ 889 | { 890 | "Types": [ 891 | "r16", 892 | "r32", 893 | "r64" 894 | ] 895 | }, 896 | { 897 | "Types": [ 898 | "r/m16", 899 | "r/m32", 900 | "r/m64" 901 | ] 902 | } 903 | ] 904 | }, 905 | { 906 | "Mnemonic": "CMOVNA", 907 | "V64": true, 908 | "V32": true, 909 | "Operands": [ 910 | { 911 | "Types": [ 912 | "r16", 913 | "r32", 914 | "r64" 915 | ] 916 | }, 917 | { 918 | "Types": [ 919 | "r/m16", 920 | "r/m32", 921 | "r/m64" 922 | ] 923 | } 924 | ] 925 | }, 926 | { 927 | "Mnemonic": "CMOVNAE", 928 | "V64": true, 929 | "V32": true, 930 | "Operands": [ 931 | { 932 | "Types": [ 933 | "r16", 934 | "r32", 935 | "r64" 936 | ] 937 | }, 938 | { 939 | "Types": [ 940 | "r/m16", 941 | "r/m32", 942 | "r/m64" 943 | ] 944 | } 945 | ] 946 | }, 947 | { 948 | "Mnemonic": "CMOVNB", 949 | "V64": true, 950 | "V32": true, 951 | "Operands": [ 952 | { 953 | "Types": [ 954 | "r16", 955 | "r32", 956 | "r64" 957 | ] 958 | }, 959 | { 960 | "Types": [ 961 | "r/m16", 962 | "r/m32", 963 | "r/m64" 964 | ] 965 | } 966 | ] 967 | }, 968 | { 969 | "Mnemonic": "CMOVNBE", 970 | "V64": true, 971 | "V32": true, 972 | "Operands": [ 973 | { 974 | "Types": [ 975 | "r16", 976 | "r32", 977 | "r64" 978 | ] 979 | }, 980 | { 981 | "Types": [ 982 | "r/m16", 983 | "r/m32", 984 | "r/m64" 985 | ] 986 | } 987 | ] 988 | }, 989 | { 990 | "Mnemonic": "CMOVNC", 991 | "V64": true, 992 | "V32": true, 993 | "Operands": [ 994 | { 995 | "Types": [ 996 | "r16", 997 | "r32", 998 | "r64" 999 | ] 1000 | }, 1001 | { 1002 | "Types": [ 1003 | "r/m16", 1004 | "r/m32", 1005 | "r/m64" 1006 | ] 1007 | } 1008 | ] 1009 | }, 1010 | { 1011 | "Mnemonic": "CMOVNE", 1012 | "V64": true, 1013 | "V32": true, 1014 | "Operands": [ 1015 | { 1016 | "Types": [ 1017 | "r16", 1018 | "r32", 1019 | "r64" 1020 | ] 1021 | }, 1022 | { 1023 | "Types": [ 1024 | "r/m16", 1025 | "r/m32", 1026 | "r/m64" 1027 | ] 1028 | } 1029 | ] 1030 | }, 1031 | { 1032 | "Mnemonic": "CMOVNG", 1033 | "V64": true, 1034 | "V32": true, 1035 | "Operands": [ 1036 | { 1037 | "Types": [ 1038 | "r16", 1039 | "r32", 1040 | "r64" 1041 | ] 1042 | }, 1043 | { 1044 | "Types": [ 1045 | "r/m16", 1046 | "r/m32", 1047 | "r/m64" 1048 | ] 1049 | } 1050 | ] 1051 | }, 1052 | { 1053 | "Mnemonic": "CMOVNGE", 1054 | "V64": true, 1055 | "V32": true, 1056 | "Operands": [ 1057 | { 1058 | "Types": [ 1059 | "r16", 1060 | "r32", 1061 | "r64" 1062 | ] 1063 | }, 1064 | { 1065 | "Types": [ 1066 | "r/m16", 1067 | "r/m32", 1068 | "r/m64" 1069 | ] 1070 | } 1071 | ] 1072 | }, 1073 | { 1074 | "Mnemonic": "CMOVNL", 1075 | "V64": true, 1076 | "V32": true, 1077 | "Operands": [ 1078 | { 1079 | "Types": [ 1080 | "r16", 1081 | "r32", 1082 | "r64" 1083 | ] 1084 | }, 1085 | { 1086 | "Types": [ 1087 | "r/m16", 1088 | "r/m32", 1089 | "r/m64" 1090 | ] 1091 | } 1092 | ] 1093 | }, 1094 | { 1095 | "Mnemonic": "CMOVNLE", 1096 | "V64": true, 1097 | "V32": true, 1098 | "Operands": [ 1099 | { 1100 | "Types": [ 1101 | "r16", 1102 | "r32", 1103 | "r64" 1104 | ] 1105 | }, 1106 | { 1107 | "Types": [ 1108 | "r/m16", 1109 | "r/m32", 1110 | "r/m64" 1111 | ] 1112 | } 1113 | ] 1114 | }, 1115 | { 1116 | "Mnemonic": "CMOVNO", 1117 | "V64": true, 1118 | "V32": true, 1119 | "Operands": [ 1120 | { 1121 | "Types": [ 1122 | "r16", 1123 | "r32", 1124 | "r64" 1125 | ] 1126 | }, 1127 | { 1128 | "Types": [ 1129 | "r/m16", 1130 | "r/m32", 1131 | "r/m64" 1132 | ] 1133 | } 1134 | ] 1135 | }, 1136 | { 1137 | "Mnemonic": "CMOVNP", 1138 | "V64": true, 1139 | "V32": true, 1140 | "Operands": [ 1141 | { 1142 | "Types": [ 1143 | "r16", 1144 | "r32", 1145 | "r64" 1146 | ] 1147 | }, 1148 | { 1149 | "Types": [ 1150 | "r/m16", 1151 | "r/m32", 1152 | "r/m64" 1153 | ] 1154 | } 1155 | ] 1156 | }, 1157 | { 1158 | "Mnemonic": "CMOVNS", 1159 | "V64": true, 1160 | "V32": true, 1161 | "Operands": [ 1162 | { 1163 | "Types": [ 1164 | "r16", 1165 | "r32", 1166 | "r64" 1167 | ] 1168 | }, 1169 | { 1170 | "Types": [ 1171 | "r/m16", 1172 | "r/m32", 1173 | "r/m64" 1174 | ] 1175 | } 1176 | ] 1177 | }, 1178 | { 1179 | "Mnemonic": "CMOVNZ", 1180 | "V64": true, 1181 | "V32": true, 1182 | "Operands": [ 1183 | { 1184 | "Types": [ 1185 | "r16", 1186 | "r32", 1187 | "r64" 1188 | ] 1189 | }, 1190 | { 1191 | "Types": [ 1192 | "r/m16", 1193 | "r/m32", 1194 | "r/m64" 1195 | ] 1196 | } 1197 | ] 1198 | }, 1199 | { 1200 | "Mnemonic": "CMOVO", 1201 | "V64": true, 1202 | "V32": true, 1203 | "Operands": [ 1204 | { 1205 | "Types": [ 1206 | "r16", 1207 | "r32", 1208 | "r64" 1209 | ] 1210 | }, 1211 | { 1212 | "Types": [ 1213 | "r/m16", 1214 | "r/m32", 1215 | "r/m64" 1216 | ] 1217 | } 1218 | ] 1219 | }, 1220 | { 1221 | "Mnemonic": "CMOVP", 1222 | "V64": true, 1223 | "V32": true, 1224 | "Operands": [ 1225 | { 1226 | "Types": [ 1227 | "r16", 1228 | "r32", 1229 | "r64" 1230 | ] 1231 | }, 1232 | { 1233 | "Types": [ 1234 | "r/m16", 1235 | "r/m32", 1236 | "r/m64" 1237 | ] 1238 | } 1239 | ] 1240 | }, 1241 | { 1242 | "Mnemonic": "CMOVPE", 1243 | "V64": true, 1244 | "V32": true, 1245 | "Operands": [ 1246 | { 1247 | "Types": [ 1248 | "r16", 1249 | "r32", 1250 | "r64" 1251 | ] 1252 | }, 1253 | { 1254 | "Types": [ 1255 | "r/m16", 1256 | "r/m32", 1257 | "r/m64" 1258 | ] 1259 | } 1260 | ] 1261 | }, 1262 | { 1263 | "Mnemonic": "CMP", 1264 | "V64": true, 1265 | "V32": true, 1266 | "Operands": [ 1267 | { 1268 | "Types": [ 1269 | "AL", 1270 | "AX", 1271 | "EAX", 1272 | "RAX", 1273 | "r/m8", 1274 | "r/m8", 1275 | "r/m16", 1276 | "r/m32", 1277 | "r/m64", 1278 | "r/m16", 1279 | "r/m32", 1280 | "r/m64", 1281 | "r/m8", 1282 | "r/m8", 1283 | "r/m16", 1284 | "r/m32", 1285 | "r/m64", 1286 | "r8", 1287 | "r8", 1288 | "r16", 1289 | "r32", 1290 | "r64" 1291 | ] 1292 | }, 1293 | { 1294 | "Types": [ 1295 | "imm8", 1296 | "imm16", 1297 | "imm32", 1298 | "imm32", 1299 | "imm8", 1300 | "imm8", 1301 | "imm16", 1302 | "imm32", 1303 | "imm32", 1304 | "imm8", 1305 | "imm8", 1306 | "imm8", 1307 | "r8", 1308 | "r8", 1309 | "r16", 1310 | "r32", 1311 | "r64", 1312 | "r/m8", 1313 | "r/m8", 1314 | "r/m16", 1315 | "r/m32", 1316 | "r/m64" 1317 | ] 1318 | } 1319 | ] 1320 | }, 1321 | { 1322 | "Mnemonic": "CMPS", 1323 | "V64": true, 1324 | "V32": true, 1325 | "Operands": [ 1326 | { 1327 | "Types": [ 1328 | "m8", 1329 | "m16", 1330 | "m32", 1331 | "m64" 1332 | ] 1333 | }, 1334 | { 1335 | "Types": [ 1336 | "m8", 1337 | "m16", 1338 | "m32", 1339 | "m64" 1340 | ] 1341 | } 1342 | ] 1343 | }, 1344 | { 1345 | "Mnemonic": "CRC32", 1346 | "V64": true, 1347 | "V32": true, 1348 | "Operands": [ 1349 | { 1350 | "Types": [ 1351 | "r32", 1352 | "r32", 1353 | "r32", 1354 | "r32", 1355 | "r64", 1356 | "r64" 1357 | ] 1358 | }, 1359 | { 1360 | "Types": [ 1361 | "r/m8", 1362 | "r/m8", 1363 | "r/m16", 1364 | "r/m32", 1365 | "r/m8", 1366 | "r/m64" 1367 | ] 1368 | } 1369 | ] 1370 | }, 1371 | { 1372 | "Mnemonic": "DEC", 1373 | "V64": true, 1374 | "V32": true, 1375 | "Operands": [ 1376 | { 1377 | "Types": [ 1378 | "r/m8", 1379 | "r/m8", 1380 | "r/m16", 1381 | "r/m32", 1382 | "r/m64", 1383 | "r16", 1384 | "r32" 1385 | ] 1386 | } 1387 | ] 1388 | }, 1389 | { 1390 | "Mnemonic": "DIV", 1391 | "V64": true, 1392 | "V32": true, 1393 | "Operands": [ 1394 | { 1395 | "Types": [ 1396 | "r/m8", 1397 | "r/m8", 1398 | "r/m16", 1399 | "r/m32", 1400 | "r/m64" 1401 | ] 1402 | } 1403 | ] 1404 | }, 1405 | { 1406 | "Mnemonic": "ENTER", 1407 | "V64": true, 1408 | "V32": true, 1409 | "Operands": [ 1410 | { 1411 | "Types": [ 1412 | "imm16" 1413 | ] 1414 | }, 1415 | { 1416 | "Types": [ 1417 | "imm8" 1418 | ] 1419 | } 1420 | ] 1421 | }, 1422 | { 1423 | "Mnemonic": "FSTSW", 1424 | "V64": true, 1425 | "V32": true, 1426 | "Operands": [ 1427 | { 1428 | "Types": [ 1429 | "AX" 1430 | ] 1431 | } 1432 | ] 1433 | }, 1434 | { 1435 | "Mnemonic": "FNSTSW", 1436 | "V64": true, 1437 | "V32": true, 1438 | "Operands": [ 1439 | { 1440 | "Types": [ 1441 | "AX" 1442 | ] 1443 | } 1444 | ] 1445 | }, 1446 | { 1447 | "Mnemonic": "IDIV", 1448 | "V64": true, 1449 | "V32": true, 1450 | "Operands": [ 1451 | { 1452 | "Types": [ 1453 | "r/m8", 1454 | "r/m8", 1455 | "r/m16", 1456 | "r/m32", 1457 | "r/m64" 1458 | ] 1459 | } 1460 | ] 1461 | }, 1462 | { 1463 | "Mnemonic": "IMUL", 1464 | "V64": true, 1465 | "V32": true, 1466 | "Operands": [ 1467 | { 1468 | "Types": [ 1469 | "r/m8", 1470 | "r/m16", 1471 | "r/m32", 1472 | "r/m64" 1473 | ] 1474 | } 1475 | ] 1476 | }, 1477 | { 1478 | "Mnemonic": "INC", 1479 | "V64": true, 1480 | "V32": true, 1481 | "Operands": [ 1482 | { 1483 | "Types": [ 1484 | "r/m8", 1485 | "r/m8", 1486 | "r/m16", 1487 | "r/m32", 1488 | "r/m64", 1489 | "r16", 1490 | "r32" 1491 | ] 1492 | } 1493 | ] 1494 | }, 1495 | { 1496 | "Mnemonic": "INS", 1497 | "V64": true, 1498 | "V32": true, 1499 | "Operands": [ 1500 | { 1501 | "Types": [ 1502 | "m8", 1503 | "m16", 1504 | "m32" 1505 | ] 1506 | }, 1507 | { 1508 | "Types": [ 1509 | "DX", 1510 | "DX", 1511 | "DX" 1512 | ] 1513 | } 1514 | ] 1515 | }, 1516 | { 1517 | "Mnemonic": "INVLPG", 1518 | "V64": true, 1519 | "V32": true, 1520 | "Operands": [ 1521 | { 1522 | "Types": [ 1523 | "m" 1524 | ] 1525 | } 1526 | ] 1527 | }, 1528 | { 1529 | "Mnemonic": "JMP", 1530 | "V64": true, 1531 | "V32": true, 1532 | "Operands": [ 1533 | { 1534 | "Types": [ 1535 | "r/m16", 1536 | "r/m32", 1537 | "r/m64" 1538 | ] 1539 | } 1540 | ] 1541 | }, 1542 | { 1543 | "Mnemonic": "LDMXCSR", 1544 | "V64": true, 1545 | "V32": true, 1546 | "Operands": [ 1547 | { 1548 | "Types": [ 1549 | "m32" 1550 | ] 1551 | } 1552 | ] 1553 | }, 1554 | { 1555 | "Mnemonic": "VLDMXCSR", 1556 | "V64": true, 1557 | "V32": true, 1558 | "Operands": [ 1559 | { 1560 | "Types": [ 1561 | "m32" 1562 | ] 1563 | } 1564 | ] 1565 | }, 1566 | { 1567 | "Mnemonic": "LEA", 1568 | "V64": true, 1569 | "V32": true, 1570 | "Operands": [ 1571 | { 1572 | "Types": [ 1573 | "r16", 1574 | "r32", 1575 | "r64" 1576 | ] 1577 | }, 1578 | { 1579 | "Types": [ 1580 | "m", 1581 | "m", 1582 | "m" 1583 | ] 1584 | } 1585 | ] 1586 | }, 1587 | { 1588 | "Mnemonic": "LMSW", 1589 | "V64": true, 1590 | "V32": true, 1591 | "Operands": [ 1592 | { 1593 | "Types": [ 1594 | "r/m16" 1595 | ] 1596 | } 1597 | ] 1598 | }, 1599 | { 1600 | "Mnemonic": "LODS", 1601 | "V64": true, 1602 | "V32": true, 1603 | "Operands": [ 1604 | { 1605 | "Types": [ 1606 | "m8", 1607 | "m16", 1608 | "m32", 1609 | "m64" 1610 | ] 1611 | } 1612 | ] 1613 | }, 1614 | { 1615 | "Mnemonic": "LZCNT", 1616 | "V64": true, 1617 | "V32": true, 1618 | "Operands": [ 1619 | { 1620 | "Types": [ 1621 | "r16", 1622 | "r32", 1623 | "r64" 1624 | ] 1625 | }, 1626 | { 1627 | "Types": [ 1628 | "r/m16", 1629 | "r/m32", 1630 | "r/m64" 1631 | ] 1632 | } 1633 | ] 1634 | }, 1635 | { 1636 | "Mnemonic": "MOV", 1637 | "V64": true, 1638 | "V32": true, 1639 | "Operands": [ 1640 | { 1641 | "Types": [ 1642 | "r/m8", 1643 | "r/m8", 1644 | "r/m16", 1645 | "r/m32", 1646 | "r/m64", 1647 | "r8", 1648 | "r8", 1649 | "r16", 1650 | "r32", 1651 | "r64", 1652 | "r8", 1653 | "r8", 1654 | "r16", 1655 | "r32", 1656 | "r64", 1657 | "r/m8", 1658 | "r/m8", 1659 | "r/m16", 1660 | "r/m32", 1661 | "r/m64" 1662 | ] 1663 | }, 1664 | { 1665 | "Types": [ 1666 | "r8", 1667 | "r8", 1668 | "r16", 1669 | "r32", 1670 | "r64", 1671 | "r/m8", 1672 | "r/m8", 1673 | "r/m16", 1674 | "r/m32", 1675 | "r/m64", 1676 | "imm8", 1677 | "imm8", 1678 | "imm16", 1679 | "imm32", 1680 | "imm64", 1681 | "imm8", 1682 | "imm8", 1683 | "imm16", 1684 | "imm32", 1685 | "imm32" 1686 | ] 1687 | } 1688 | ] 1689 | }, 1690 | { 1691 | "Mnemonic": "MOVBE", 1692 | "V64": true, 1693 | "V32": true, 1694 | "Operands": [ 1695 | { 1696 | "Types": [ 1697 | "r16", 1698 | "r32", 1699 | "r64", 1700 | "m16", 1701 | "m32", 1702 | "m64" 1703 | ] 1704 | }, 1705 | { 1706 | "Types": [ 1707 | "m16", 1708 | "m32", 1709 | "m64", 1710 | "r16", 1711 | "r32", 1712 | "r64" 1713 | ] 1714 | } 1715 | ] 1716 | }, 1717 | { 1718 | "Mnemonic": "MOVNTI", 1719 | "V64": true, 1720 | "V32": true, 1721 | "Operands": [ 1722 | { 1723 | "Types": [ 1724 | "m32", 1725 | "m64" 1726 | ] 1727 | }, 1728 | { 1729 | "Types": [ 1730 | "r32", 1731 | "r64" 1732 | ] 1733 | } 1734 | ] 1735 | }, 1736 | { 1737 | "Mnemonic": "MOVS", 1738 | "V64": true, 1739 | "V32": true, 1740 | "Operands": [ 1741 | { 1742 | "Types": [ 1743 | "m8", 1744 | "m16", 1745 | "m32", 1746 | "m64" 1747 | ] 1748 | }, 1749 | { 1750 | "Types": [ 1751 | "m8", 1752 | "m16", 1753 | "m32", 1754 | "m64" 1755 | ] 1756 | } 1757 | ] 1758 | }, 1759 | { 1760 | "Mnemonic": "MOVSX", 1761 | "V64": true, 1762 | "V32": true, 1763 | "Operands": [ 1764 | { 1765 | "Types": [ 1766 | "r16", 1767 | "r32", 1768 | "r64", 1769 | "r32", 1770 | "r64" 1771 | ] 1772 | }, 1773 | { 1774 | "Types": [ 1775 | "r/m8", 1776 | "r/m8", 1777 | "r/m8", 1778 | "r/m16", 1779 | "r/m16" 1780 | ] 1781 | } 1782 | ] 1783 | }, 1784 | { 1785 | "Mnemonic": "MOVZX", 1786 | "V64": true, 1787 | "V32": true, 1788 | "Operands": [ 1789 | { 1790 | "Types": [ 1791 | "r16", 1792 | "r32", 1793 | "r64", 1794 | "r32", 1795 | "r64" 1796 | ] 1797 | }, 1798 | { 1799 | "Types": [ 1800 | "r/m8", 1801 | "r/m8", 1802 | "r/m8", 1803 | "r/m16", 1804 | "r/m16" 1805 | ] 1806 | } 1807 | ] 1808 | }, 1809 | { 1810 | "Mnemonic": "MUL", 1811 | "V64": true, 1812 | "V32": true, 1813 | "Operands": [ 1814 | { 1815 | "Types": [ 1816 | "r/m8", 1817 | "r/m8", 1818 | "r/m16", 1819 | "r/m32", 1820 | "r/m64" 1821 | ] 1822 | } 1823 | ] 1824 | }, 1825 | { 1826 | "Mnemonic": "NEG", 1827 | "V64": true, 1828 | "V32": true, 1829 | "Operands": [ 1830 | { 1831 | "Types": [ 1832 | "r/m8", 1833 | "r/m8", 1834 | "r/m16", 1835 | "r/m32", 1836 | "r/m64" 1837 | ] 1838 | } 1839 | ] 1840 | }, 1841 | { 1842 | "Mnemonic": "NOP", 1843 | "V64": true, 1844 | "V32": true, 1845 | "Operands": [ 1846 | { 1847 | "Types": [ 1848 | "r/m16", 1849 | "r/m32" 1850 | ] 1851 | } 1852 | ] 1853 | }, 1854 | { 1855 | "Mnemonic": "NOT", 1856 | "V64": true, 1857 | "V32": true, 1858 | "Operands": [ 1859 | { 1860 | "Types": [ 1861 | "r/m8", 1862 | "r/m8", 1863 | "r/m16", 1864 | "r/m32", 1865 | "r/m64" 1866 | ] 1867 | } 1868 | ] 1869 | }, 1870 | { 1871 | "Mnemonic": "OR", 1872 | "V64": true, 1873 | "V32": true, 1874 | "Operands": [ 1875 | { 1876 | "Types": [ 1877 | "AL", 1878 | "AX", 1879 | "EAX", 1880 | "RAX", 1881 | "r/m8", 1882 | "r/m8", 1883 | "r/m16", 1884 | "r/m32", 1885 | "r/m64", 1886 | "r/m16", 1887 | "r/m32", 1888 | "r/m64", 1889 | "r/m8", 1890 | "r/m8", 1891 | "r/m16", 1892 | "r/m32", 1893 | "r/m64", 1894 | "r8", 1895 | "r8", 1896 | "r16", 1897 | "r32", 1898 | "r64" 1899 | ] 1900 | }, 1901 | { 1902 | "Types": [ 1903 | "imm8", 1904 | "imm16", 1905 | "imm32", 1906 | "imm32", 1907 | "imm8", 1908 | "imm8", 1909 | "imm16", 1910 | "imm32", 1911 | "imm32", 1912 | "imm8", 1913 | "imm8", 1914 | "imm8", 1915 | "r8", 1916 | "r8", 1917 | "r16", 1918 | "r32", 1919 | "r64", 1920 | "r/m8", 1921 | "r/m8", 1922 | "r/m16", 1923 | "r/m32", 1924 | "r/m64" 1925 | ] 1926 | } 1927 | ] 1928 | }, 1929 | { 1930 | "Mnemonic": "OUT", 1931 | "V64": true, 1932 | "V32": true, 1933 | "Operands": [ 1934 | { 1935 | "Types": [ 1936 | "imm8", 1937 | "imm8", 1938 | "imm8", 1939 | "DX", 1940 | "DX", 1941 | "DX" 1942 | ] 1943 | }, 1944 | { 1945 | "Types": [ 1946 | "AL", 1947 | "AX", 1948 | "EAX", 1949 | "AL", 1950 | "AX", 1951 | "EAX" 1952 | ] 1953 | } 1954 | ] 1955 | }, 1956 | { 1957 | "Mnemonic": "OUTS", 1958 | "V64": true, 1959 | "V32": true, 1960 | "Operands": [ 1961 | { 1962 | "Types": [ 1963 | "DX", 1964 | "DX", 1965 | "DX" 1966 | ] 1967 | }, 1968 | { 1969 | "Types": [ 1970 | "m8", 1971 | "m16", 1972 | "m32" 1973 | ] 1974 | } 1975 | ] 1976 | }, 1977 | { 1978 | "Mnemonic": "POP", 1979 | "V64": true, 1980 | "V32": true, 1981 | "Operands": [ 1982 | { 1983 | "Types": [ 1984 | "r/m16", 1985 | "r/m32", 1986 | "r/m64", 1987 | "r16", 1988 | "r32", 1989 | "r64" 1990 | ] 1991 | } 1992 | ] 1993 | }, 1994 | { 1995 | "Mnemonic": "POPCNT", 1996 | "V64": true, 1997 | "V32": true, 1998 | "Operands": [ 1999 | { 2000 | "Types": [ 2001 | "r16", 2002 | "r32", 2003 | "r64" 2004 | ] 2005 | }, 2006 | { 2007 | "Types": [ 2008 | "r/m16", 2009 | "r/m32", 2010 | "r/m64" 2011 | ] 2012 | } 2013 | ] 2014 | }, 2015 | { 2016 | "Mnemonic": "PREFETCHT0", 2017 | "V64": true, 2018 | "V32": true, 2019 | "Operands": [ 2020 | { 2021 | "Types": [ 2022 | "m8" 2023 | ] 2024 | } 2025 | ] 2026 | }, 2027 | { 2028 | "Mnemonic": "PREFETCHT1", 2029 | "V64": true, 2030 | "V32": true, 2031 | "Operands": [ 2032 | { 2033 | "Types": [ 2034 | "m8" 2035 | ] 2036 | } 2037 | ] 2038 | }, 2039 | { 2040 | "Mnemonic": "PREFETCHT2", 2041 | "V64": true, 2042 | "V32": true, 2043 | "Operands": [ 2044 | { 2045 | "Types": [ 2046 | "m8" 2047 | ] 2048 | } 2049 | ] 2050 | }, 2051 | { 2052 | "Mnemonic": "PREFETCHNTA", 2053 | "V64": true, 2054 | "V32": true, 2055 | "Operands": [ 2056 | { 2057 | "Types": [ 2058 | "m8" 2059 | ] 2060 | } 2061 | ] 2062 | }, 2063 | { 2064 | "Mnemonic": "PREFETCHW", 2065 | "V64": true, 2066 | "V32": true, 2067 | "Operands": [ 2068 | { 2069 | "Types": [ 2070 | "m8" 2071 | ] 2072 | } 2073 | ] 2074 | }, 2075 | { 2076 | "Mnemonic": "PREFETCHWT1", 2077 | "V64": true, 2078 | "V32": true, 2079 | "Operands": [ 2080 | { 2081 | "Types": [ 2082 | "m8" 2083 | ] 2084 | } 2085 | ] 2086 | }, 2087 | { 2088 | "Mnemonic": "PUSH", 2089 | "V64": true, 2090 | "V32": true, 2091 | "Operands": [ 2092 | { 2093 | "Types": [ 2094 | "r/m16", 2095 | "r/m32", 2096 | "r/m64", 2097 | "r16", 2098 | "r32", 2099 | "r64", 2100 | "imm8", 2101 | "imm16", 2102 | "imm32" 2103 | ] 2104 | } 2105 | ] 2106 | }, 2107 | { 2108 | "Mnemonic": "RCL", 2109 | "V64": true, 2110 | "V32": true, 2111 | "Operands": [ 2112 | { 2113 | "Types": [ 2114 | "r/m8", 2115 | "r/m8", 2116 | "r/m8", 2117 | "r/m8", 2118 | "r/m16", 2119 | "r/m16", 2120 | "r/m32", 2121 | "r/m64", 2122 | "r/m32", 2123 | "r/m64" 2124 | ] 2125 | }, 2126 | { 2127 | "Types": [ 2128 | "CL", 2129 | "CL", 2130 | "imm8", 2131 | "imm8", 2132 | "CL", 2133 | "imm8", 2134 | "CL", 2135 | "CL", 2136 | "imm8", 2137 | "imm8" 2138 | ] 2139 | } 2140 | ] 2141 | }, 2142 | { 2143 | "Mnemonic": "RCR", 2144 | "V64": true, 2145 | "V32": true, 2146 | "Operands": [ 2147 | { 2148 | "Types": [ 2149 | "r/m8", 2150 | "r/m8", 2151 | "r/m8", 2152 | "r/m8", 2153 | "r/m16", 2154 | "r/m16", 2155 | "r/m32", 2156 | "r/m64", 2157 | "r/m32", 2158 | "r/m64" 2159 | ] 2160 | }, 2161 | { 2162 | "Types": [ 2163 | "CL", 2164 | "CL", 2165 | "imm8", 2166 | "imm8", 2167 | "CL", 2168 | "imm8", 2169 | "CL", 2170 | "CL", 2171 | "imm8", 2172 | "imm8" 2173 | ] 2174 | } 2175 | ] 2176 | }, 2177 | { 2178 | "Mnemonic": "ROL", 2179 | "V64": true, 2180 | "V32": true, 2181 | "Operands": [ 2182 | { 2183 | "Types": [ 2184 | "r/m8", 2185 | "r/m8", 2186 | "r/m8", 2187 | "r/m8", 2188 | "r/m16", 2189 | "r/m16", 2190 | "r/m32", 2191 | "r/m64", 2192 | "r/m32", 2193 | "r/m64" 2194 | ] 2195 | }, 2196 | { 2197 | "Types": [ 2198 | "CL", 2199 | "CL", 2200 | "imm8", 2201 | "imm8", 2202 | "CL", 2203 | "imm8", 2204 | "CL", 2205 | "CL", 2206 | "imm8", 2207 | "imm8" 2208 | ] 2209 | } 2210 | ] 2211 | }, 2212 | { 2213 | "Mnemonic": "ROR", 2214 | "V64": true, 2215 | "V32": true, 2216 | "Operands": [ 2217 | { 2218 | "Types": [ 2219 | "r/m8", 2220 | "r/m8", 2221 | "r/m8", 2222 | "r/m8", 2223 | "r/m16", 2224 | "r/m16", 2225 | "r/m32", 2226 | "r/m64", 2227 | "r/m32", 2228 | "r/m64" 2229 | ] 2230 | }, 2231 | { 2232 | "Types": [ 2233 | "CL", 2234 | "CL", 2235 | "imm8", 2236 | "imm8", 2237 | "CL", 2238 | "imm8", 2239 | "CL", 2240 | "CL", 2241 | "imm8", 2242 | "imm8" 2243 | ] 2244 | } 2245 | ] 2246 | }, 2247 | { 2248 | "Mnemonic": "RDRAND", 2249 | "V64": true, 2250 | "V32": true, 2251 | "Operands": [ 2252 | { 2253 | "Types": [ 2254 | "r16", 2255 | "r32", 2256 | "r64" 2257 | ] 2258 | } 2259 | ] 2260 | }, 2261 | { 2262 | "Mnemonic": "RDSEED", 2263 | "V64": true, 2264 | "V32": true, 2265 | "Operands": [ 2266 | { 2267 | "Types": [ 2268 | "r16", 2269 | "r32", 2270 | "r64" 2271 | ] 2272 | } 2273 | ] 2274 | }, 2275 | { 2276 | "Mnemonic": "RET", 2277 | "V64": true, 2278 | "V32": true, 2279 | "Operands": [ 2280 | { 2281 | "Types": [ 2282 | "imm16", 2283 | "imm16" 2284 | ] 2285 | } 2286 | ] 2287 | }, 2288 | { 2289 | "Mnemonic": "SAL", 2290 | "V64": true, 2291 | "V32": true, 2292 | "Operands": [ 2293 | { 2294 | "Types": [ 2295 | "r/m8", 2296 | "r/m8", 2297 | "r/m8", 2298 | "r/m8", 2299 | "r/m16", 2300 | "r/m16", 2301 | "r/m32", 2302 | "r/m64", 2303 | "r/m32", 2304 | "r/m64" 2305 | ] 2306 | }, 2307 | { 2308 | "Types": [ 2309 | "CL", 2310 | "CL", 2311 | "imm8", 2312 | "imm8", 2313 | "CL", 2314 | "imm8", 2315 | "CL", 2316 | "CL", 2317 | "imm8", 2318 | "imm8" 2319 | ] 2320 | } 2321 | ] 2322 | }, 2323 | { 2324 | "Mnemonic": "SAR", 2325 | "V64": true, 2326 | "V32": true, 2327 | "Operands": [ 2328 | { 2329 | "Types": [ 2330 | "r/m8", 2331 | "r/m8", 2332 | "r/m8", 2333 | "r/m8", 2334 | "r/m16", 2335 | "r/m16", 2336 | "r/m32", 2337 | "r/m64", 2338 | "r/m32", 2339 | "r/m64" 2340 | ] 2341 | }, 2342 | { 2343 | "Types": [ 2344 | "CL", 2345 | "CL", 2346 | "imm8", 2347 | "imm8", 2348 | "CL", 2349 | "imm8", 2350 | "CL", 2351 | "CL", 2352 | "imm8", 2353 | "imm8" 2354 | ] 2355 | } 2356 | ] 2357 | }, 2358 | { 2359 | "Mnemonic": "SHL", 2360 | "V64": true, 2361 | "V32": true, 2362 | "Operands": [ 2363 | { 2364 | "Types": [ 2365 | "r/m8", 2366 | "r/m8", 2367 | "r/m8", 2368 | "r/m8", 2369 | "r/m16", 2370 | "r/m16", 2371 | "r/m32", 2372 | "r/m64", 2373 | "r/m32", 2374 | "r/m64" 2375 | ] 2376 | }, 2377 | { 2378 | "Types": [ 2379 | "CL", 2380 | "CL", 2381 | "imm8", 2382 | "imm8", 2383 | "CL", 2384 | "imm8", 2385 | "CL", 2386 | "CL", 2387 | "imm8", 2388 | "imm8" 2389 | ] 2390 | } 2391 | ] 2392 | }, 2393 | { 2394 | "Mnemonic": "SHR", 2395 | "V64": true, 2396 | "V32": true, 2397 | "Operands": [ 2398 | { 2399 | "Types": [ 2400 | "r/m8", 2401 | "r/m8", 2402 | "r/m8", 2403 | "r/m8", 2404 | "r/m16", 2405 | "r/m16", 2406 | "r/m32", 2407 | "r/m64", 2408 | "r/m32", 2409 | "r/m64" 2410 | ] 2411 | }, 2412 | { 2413 | "Types": [ 2414 | "CL", 2415 | "CL", 2416 | "imm8", 2417 | "imm8", 2418 | "CL", 2419 | "imm8", 2420 | "CL", 2421 | "CL", 2422 | "imm8", 2423 | "imm8" 2424 | ] 2425 | } 2426 | ] 2427 | }, 2428 | { 2429 | "Mnemonic": "SBB", 2430 | "V64": true, 2431 | "V32": true, 2432 | "Operands": [ 2433 | { 2434 | "Types": [ 2435 | "AL", 2436 | "AX", 2437 | "EAX", 2438 | "RAX", 2439 | "r/m8", 2440 | "r/m8", 2441 | "r/m16", 2442 | "r/m32", 2443 | "r/m64", 2444 | "r/m16", 2445 | "r/m32", 2446 | "r/m64", 2447 | "r/m8", 2448 | "r/m8", 2449 | "r/m16", 2450 | "r/m32", 2451 | "r/m64", 2452 | "r8", 2453 | "r8", 2454 | "r16", 2455 | "r32", 2456 | "r64" 2457 | ] 2458 | }, 2459 | { 2460 | "Types": [ 2461 | "imm8", 2462 | "imm16", 2463 | "imm32", 2464 | "imm32", 2465 | "imm8", 2466 | "imm8", 2467 | "imm16", 2468 | "imm32", 2469 | "imm32", 2470 | "imm8", 2471 | "imm8", 2472 | "imm8", 2473 | "r8", 2474 | "r8", 2475 | "r16", 2476 | "r32", 2477 | "r64", 2478 | "r/m8", 2479 | "r/m8", 2480 | "r/m16", 2481 | "r/m32", 2482 | "r/m64" 2483 | ] 2484 | } 2485 | ] 2486 | }, 2487 | { 2488 | "Mnemonic": "SCAS", 2489 | "V64": true, 2490 | "V32": true, 2491 | "Operands": [ 2492 | { 2493 | "Types": [ 2494 | "m8", 2495 | "m16", 2496 | "m32", 2497 | "m64" 2498 | ] 2499 | } 2500 | ] 2501 | }, 2502 | { 2503 | "Mnemonic": "SETA", 2504 | "V64": true, 2505 | "V32": true, 2506 | "Operands": [ 2507 | { 2508 | "Types": [ 2509 | "r/m8", 2510 | "r/m8" 2511 | ] 2512 | } 2513 | ] 2514 | }, 2515 | { 2516 | "Mnemonic": "SETAE", 2517 | "V64": true, 2518 | "V32": true, 2519 | "Operands": [ 2520 | { 2521 | "Types": [ 2522 | "r/m8", 2523 | "r/m8" 2524 | ] 2525 | } 2526 | ] 2527 | }, 2528 | { 2529 | "Mnemonic": "SETB", 2530 | "V64": true, 2531 | "V32": true, 2532 | "Operands": [ 2533 | { 2534 | "Types": [ 2535 | "r/m8", 2536 | "r/m8" 2537 | ] 2538 | } 2539 | ] 2540 | }, 2541 | { 2542 | "Mnemonic": "SETBE", 2543 | "V64": true, 2544 | "V32": true, 2545 | "Operands": [ 2546 | { 2547 | "Types": [ 2548 | "r/m8", 2549 | "r/m8" 2550 | ] 2551 | } 2552 | ] 2553 | }, 2554 | { 2555 | "Mnemonic": "SETC", 2556 | "V64": true, 2557 | "V32": true, 2558 | "Operands": [ 2559 | { 2560 | "Types": [ 2561 | "r/m8", 2562 | "r/m8" 2563 | ] 2564 | } 2565 | ] 2566 | }, 2567 | { 2568 | "Mnemonic": "SETE", 2569 | "V64": true, 2570 | "V32": true, 2571 | "Operands": [ 2572 | { 2573 | "Types": [ 2574 | "r/m8", 2575 | "r/m8" 2576 | ] 2577 | } 2578 | ] 2579 | }, 2580 | { 2581 | "Mnemonic": "SETG", 2582 | "V64": true, 2583 | "V32": true, 2584 | "Operands": [ 2585 | { 2586 | "Types": [ 2587 | "r/m8", 2588 | "r/m8" 2589 | ] 2590 | } 2591 | ] 2592 | }, 2593 | { 2594 | "Mnemonic": "SETGE", 2595 | "V64": true, 2596 | "V32": true, 2597 | "Operands": [ 2598 | { 2599 | "Types": [ 2600 | "r/m8", 2601 | "r/m8" 2602 | ] 2603 | } 2604 | ] 2605 | }, 2606 | { 2607 | "Mnemonic": "SETL", 2608 | "V64": true, 2609 | "V32": true, 2610 | "Operands": [ 2611 | { 2612 | "Types": [ 2613 | "r/m8", 2614 | "r/m8" 2615 | ] 2616 | } 2617 | ] 2618 | }, 2619 | { 2620 | "Mnemonic": "SETLE", 2621 | "V64": true, 2622 | "V32": true, 2623 | "Operands": [ 2624 | { 2625 | "Types": [ 2626 | "r/m8", 2627 | "r/m8" 2628 | ] 2629 | } 2630 | ] 2631 | }, 2632 | { 2633 | "Mnemonic": "SETNA", 2634 | "V64": true, 2635 | "V32": true, 2636 | "Operands": [ 2637 | { 2638 | "Types": [ 2639 | "r/m8", 2640 | "r/m8" 2641 | ] 2642 | } 2643 | ] 2644 | }, 2645 | { 2646 | "Mnemonic": "SETNAE", 2647 | "V64": true, 2648 | "V32": true, 2649 | "Operands": [ 2650 | { 2651 | "Types": [ 2652 | "r/m8", 2653 | "r/m8" 2654 | ] 2655 | } 2656 | ] 2657 | }, 2658 | { 2659 | "Mnemonic": "SETNB", 2660 | "V64": true, 2661 | "V32": true, 2662 | "Operands": [ 2663 | { 2664 | "Types": [ 2665 | "r/m8", 2666 | "r/m8" 2667 | ] 2668 | } 2669 | ] 2670 | }, 2671 | { 2672 | "Mnemonic": "SETNBE", 2673 | "V64": true, 2674 | "V32": true, 2675 | "Operands": [ 2676 | { 2677 | "Types": [ 2678 | "r/m8", 2679 | "r/m8" 2680 | ] 2681 | } 2682 | ] 2683 | }, 2684 | { 2685 | "Mnemonic": "SETNC", 2686 | "V64": true, 2687 | "V32": true, 2688 | "Operands": [ 2689 | { 2690 | "Types": [ 2691 | "r/m8", 2692 | "r/m8" 2693 | ] 2694 | } 2695 | ] 2696 | }, 2697 | { 2698 | "Mnemonic": "SETNE", 2699 | "V64": true, 2700 | "V32": true, 2701 | "Operands": [ 2702 | { 2703 | "Types": [ 2704 | "r/m8", 2705 | "r/m8" 2706 | ] 2707 | } 2708 | ] 2709 | }, 2710 | { 2711 | "Mnemonic": "SETNG", 2712 | "V64": true, 2713 | "V32": true, 2714 | "Operands": [ 2715 | { 2716 | "Types": [ 2717 | "r/m8", 2718 | "r/m8" 2719 | ] 2720 | } 2721 | ] 2722 | }, 2723 | { 2724 | "Mnemonic": "SETNGE", 2725 | "V64": true, 2726 | "V32": true, 2727 | "Operands": [ 2728 | { 2729 | "Types": [ 2730 | "r/m8", 2731 | "r/m8" 2732 | ] 2733 | } 2734 | ] 2735 | }, 2736 | { 2737 | "Mnemonic": "SETNL", 2738 | "V64": true, 2739 | "V32": true, 2740 | "Operands": [ 2741 | { 2742 | "Types": [ 2743 | "r/m8", 2744 | "r/m8" 2745 | ] 2746 | } 2747 | ] 2748 | }, 2749 | { 2750 | "Mnemonic": "SETNLE", 2751 | "V64": true, 2752 | "V32": true, 2753 | "Operands": [ 2754 | { 2755 | "Types": [ 2756 | "r/m8" 2757 | ] 2758 | } 2759 | ] 2760 | }, 2761 | { 2762 | "Mnemonic": "SGDT", 2763 | "V64": true, 2764 | "V32": true, 2765 | "Operands": [ 2766 | { 2767 | "Types": [ 2768 | "m" 2769 | ] 2770 | } 2771 | ] 2772 | }, 2773 | { 2774 | "Mnemonic": "SIDT", 2775 | "V64": true, 2776 | "V32": true, 2777 | "Operands": [ 2778 | { 2779 | "Types": [ 2780 | "m" 2781 | ] 2782 | } 2783 | ] 2784 | }, 2785 | { 2786 | "Mnemonic": "SLDT", 2787 | "V64": true, 2788 | "V32": true, 2789 | "Operands": [ 2790 | { 2791 | "Types": [ 2792 | "r/m16" 2793 | ] 2794 | } 2795 | ] 2796 | }, 2797 | { 2798 | "Mnemonic": "SMSW", 2799 | "V64": true, 2800 | "V32": true, 2801 | "Operands": [ 2802 | { 2803 | "Types": [ 2804 | "r/m16" 2805 | ] 2806 | } 2807 | ] 2808 | }, 2809 | { 2810 | "Mnemonic": "STMXCSR", 2811 | "V64": true, 2812 | "V32": true, 2813 | "Operands": [ 2814 | { 2815 | "Types": [ 2816 | "m32" 2817 | ] 2818 | } 2819 | ] 2820 | }, 2821 | { 2822 | "Mnemonic": "VSTMXCSR", 2823 | "V64": true, 2824 | "V32": true, 2825 | "Operands": [ 2826 | { 2827 | "Types": [ 2828 | "m32" 2829 | ] 2830 | } 2831 | ] 2832 | }, 2833 | { 2834 | "Mnemonic": "STOS", 2835 | "V64": true, 2836 | "V32": true, 2837 | "Operands": [ 2838 | { 2839 | "Types": [ 2840 | "m8", 2841 | "m16", 2842 | "m32", 2843 | "m64" 2844 | ] 2845 | } 2846 | ] 2847 | }, 2848 | { 2849 | "Mnemonic": "STR", 2850 | "V64": true, 2851 | "V32": true, 2852 | "Operands": [ 2853 | { 2854 | "Types": [ 2855 | "r/m16" 2856 | ] 2857 | } 2858 | ] 2859 | }, 2860 | { 2861 | "Mnemonic": "SUB", 2862 | "V64": true, 2863 | "V32": true, 2864 | "Operands": [ 2865 | { 2866 | "Types": [ 2867 | "AL", 2868 | "AX", 2869 | "EAX", 2870 | "RAX", 2871 | "r/m8", 2872 | "r/m8", 2873 | "r/m16", 2874 | "r/m32", 2875 | "r/m64", 2876 | "r/m16", 2877 | "r/m32", 2878 | "r/m64", 2879 | "r/m8", 2880 | "r/m8", 2881 | "r/m16", 2882 | "r/m32", 2883 | "r/m64", 2884 | "r8", 2885 | "r8", 2886 | "r16", 2887 | "r32", 2888 | "r64" 2889 | ] 2890 | }, 2891 | { 2892 | "Types": [ 2893 | "imm8", 2894 | "imm16", 2895 | "imm32", 2896 | "imm32", 2897 | "imm8", 2898 | "imm8", 2899 | "imm16", 2900 | "imm32", 2901 | "imm32", 2902 | "imm8", 2903 | "imm8", 2904 | "imm8", 2905 | "r8", 2906 | "r8", 2907 | "r16", 2908 | "r32", 2909 | "r64", 2910 | "r/m8", 2911 | "r/m8", 2912 | "r/m16", 2913 | "r/m32", 2914 | "r/m64" 2915 | ] 2916 | } 2917 | ] 2918 | }, 2919 | { 2920 | "Mnemonic": "TEST", 2921 | "V64": true, 2922 | "V32": true, 2923 | "Operands": [ 2924 | { 2925 | "Types": [ 2926 | "AL", 2927 | "AX", 2928 | "EAX", 2929 | "RAX", 2930 | "r/m8", 2931 | "r/m8", 2932 | "r/m16", 2933 | "r/m32", 2934 | "r/m64", 2935 | "r/m8", 2936 | "r/m8", 2937 | "r/m16", 2938 | "r/m32", 2939 | "r/m64" 2940 | ] 2941 | }, 2942 | { 2943 | "Types": [ 2944 | "imm8", 2945 | "imm16", 2946 | "imm32", 2947 | "imm32", 2948 | "imm8", 2949 | "imm8", 2950 | "imm16", 2951 | "imm32", 2952 | "imm32", 2953 | "r8", 2954 | "r8", 2955 | "r16", 2956 | "r32", 2957 | "r64" 2958 | ] 2959 | } 2960 | ] 2961 | }, 2962 | { 2963 | "Mnemonic": "TZCNT", 2964 | "V64": true, 2965 | "V32": true, 2966 | "Operands": [ 2967 | { 2968 | "Types": [ 2969 | "r16", 2970 | "r32", 2971 | "r64" 2972 | ] 2973 | }, 2974 | { 2975 | "Types": [ 2976 | "r/m16", 2977 | "r/m32", 2978 | "r/m64" 2979 | ] 2980 | } 2981 | ] 2982 | }, 2983 | { 2984 | "Mnemonic": "VERR", 2985 | "V64": true, 2986 | "V32": true, 2987 | "Operands": [ 2988 | { 2989 | "Types": [ 2990 | "r/m16" 2991 | ] 2992 | } 2993 | ] 2994 | }, 2995 | { 2996 | "Mnemonic": "VERW", 2997 | "V64": true, 2998 | "V32": true, 2999 | "Operands": [ 3000 | { 3001 | "Types": [ 3002 | "r/m16" 3003 | ] 3004 | } 3005 | ] 3006 | }, 3007 | { 3008 | "Mnemonic": "XABORT", 3009 | "V64": true, 3010 | "V32": true, 3011 | "Operands": [ 3012 | { 3013 | "Types": [ 3014 | "imm8" 3015 | ] 3016 | } 3017 | ] 3018 | }, 3019 | { 3020 | "Mnemonic": "XADD", 3021 | "V64": true, 3022 | "V32": true, 3023 | "Operands": [ 3024 | { 3025 | "Types": [ 3026 | "r/m8", 3027 | "r/m8", 3028 | "r/m16", 3029 | "r/m32", 3030 | "r/m64" 3031 | ] 3032 | }, 3033 | { 3034 | "Types": [ 3035 | "r8", 3036 | "r8", 3037 | "r16", 3038 | "r32", 3039 | "r64" 3040 | ] 3041 | } 3042 | ] 3043 | }, 3044 | { 3045 | "Mnemonic": "XLAT", 3046 | "V64": true, 3047 | "V32": true, 3048 | "Operands": [ 3049 | { 3050 | "Types": [ 3051 | "m8" 3052 | ] 3053 | } 3054 | ] 3055 | }, 3056 | { 3057 | "Mnemonic": "XOR", 3058 | "V64": true, 3059 | "V32": true, 3060 | "Operands": [ 3061 | { 3062 | "Types": [ 3063 | "AL", 3064 | "AX", 3065 | "EAX", 3066 | "RAX", 3067 | "r/m8", 3068 | "r/m8", 3069 | "r/m16", 3070 | "r/m32", 3071 | "r/m64", 3072 | "r/m16", 3073 | "r/m32", 3074 | "r/m64", 3075 | "r/m8", 3076 | "r/m8", 3077 | "r/m16", 3078 | "r/m32", 3079 | "r/m64", 3080 | "r8", 3081 | "r8", 3082 | "r16", 3083 | "r32", 3084 | "r64" 3085 | ] 3086 | }, 3087 | { 3088 | "Types": [ 3089 | "imm8", 3090 | "imm16", 3091 | "imm32", 3092 | "imm32", 3093 | "imm8", 3094 | "imm8", 3095 | "imm16", 3096 | "imm32", 3097 | "imm32", 3098 | "imm8", 3099 | "imm8", 3100 | "imm8", 3101 | "r8", 3102 | "r8", 3103 | "r16", 3104 | "r32", 3105 | "r64", 3106 | "r/m8", 3107 | "r/m8", 3108 | "r/m16", 3109 | "r/m32", 3110 | "r/m64" 3111 | ] 3112 | } 3113 | ] 3114 | } 3115 | ] 3116 | 3117 | 3118 | 3119 | ` 3120 | -------------------------------------------------------------------------------- /keystone.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/A1bu5/shellcodebypass_GUI/cb91d4d183f3a7e1dd1e5d40bb45ca9b2d8c3f51/keystone.dll -------------------------------------------------------------------------------- /obfuscate.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "math" 8 | "math/rand" 9 | "strings" 10 | ) 11 | 12 | // SGN ASM Label Definitions; 13 | //----------------------------- 14 | // {R} = RANDOM GENERAL PURPOSE REGISTER 15 | // {K} = RANDOM BYTE OF DATA 16 | // {L} = RANDOM ASM LABEL 17 | // {G} = RANDOM GARBAGE ASSEMBLY 18 | 19 | // GenerateGarbageAssembly generates random garbage instruction(s) assemblies 20 | // based on the subject encoder architecture 21 | func (encoder *Encoder) GenerateGarbageAssembly() string { 22 | 23 | switch rand.Intn(4) { 24 | case 1: 25 | randomGarbageAssembly := GetRandomSafeAssembly() 26 | register := encoder.GetRandomRegister(encoder.architecture) 27 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{R}", register) 28 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{K}", fmt.Sprintf("0x%x", GetRandomByte())) 29 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{L}", RandomLabel()) 30 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{G}", encoder.GenerateGarbageAssembly()) 31 | return randomGarbageAssembly + ";" 32 | case 2: 33 | return encoder.GetRandomFunctionAssembly() 34 | case 3: 35 | randRegister, _ := encoder.GetSafeRandomRegister(encoder.architecture, encoder.GetStackPointer()) // we can safely ignore the error 36 | // Save the destination register 37 | // After saving the target register to stack we can munipulate the register unlimited times 38 | unsafeGarbageAssembly := fmt.Sprintf("PUSH %s;", randRegister) 39 | if CoinFlip() { 40 | unsafeGarbageAssembly += encoder.GenerateGarbageAssembly() 41 | } 42 | unsafeGarbageAssembly += encoder.GetRandomUnsafeAssembly(randRegister) 43 | // Keep adding unsafe garbage by chance 44 | for { 45 | if CoinFlip() { 46 | unsafeGarbageAssembly += encoder.GetRandomUnsafeAssembly(randRegister) 47 | } else { 48 | break 49 | } 50 | } 51 | if CoinFlip() { 52 | unsafeGarbageAssembly += encoder.GenerateGarbageAssembly() 53 | } 54 | unsafeGarbageAssembly += fmt.Sprintf("POP %s;", randRegister) 55 | return unsafeGarbageAssembly 56 | default: 57 | return ";" 58 | } 59 | } 60 | 61 | // GenerateGarbageInstructions generates random garbage instruction(s) 62 | // with the specified architecture and returns the assembled bytes 63 | func (encoder *Encoder) GenerateGarbageInstructions() ([]byte, error) { 64 | 65 | randomGarbageAssembly := encoder.GenerateGarbageAssembly() 66 | garbage, ok := encoder.Assemble(randomGarbageAssembly) 67 | if !ok { 68 | //fmt.Println(randomGarbageAssembly) 69 | return nil, errors.New("random garbage instruction assembly failed") 70 | } 71 | 72 | if CoinFlip() { 73 | garbageJmp, err := encoder.GenerateGarbageJump() 74 | if err != nil { 75 | return nil, err 76 | } 77 | if CoinFlip() { 78 | garbage = append(garbageJmp, garbage...) 79 | } else { 80 | garbage = append(garbage, garbageJmp...) 81 | } 82 | } 83 | 84 | if len(garbage) <= encoder.ObfuscationLimit { 85 | //fmt.Println(randomGarbageAssembly) 86 | return garbage, nil 87 | } 88 | 89 | return encoder.GenerateGarbageInstructions() 90 | } 91 | 92 | // GetRandomSafeAssembly return a safe garbage instruction assembly 93 | func GetRandomSafeAssembly() string { 94 | 95 | newSafeGarbageInstructions := SafeGarbageInstructions 96 | // Add garbage confditional jumps for more possibility 97 | for _, jmp := range ConditionalJumpMnemonics { 98 | newSafeGarbageInstructions = append(newSafeGarbageInstructions, jmp+" {L};{G};{L}:") 99 | //newSafeGarbageInstructions = append(newSafeGarbageInstructions, jmp+" 2") 100 | } 101 | return newSafeGarbageInstructions[rand.Intn(len(SafeGarbageInstructions))] 102 | } 103 | 104 | // GetRandomUnsafeAssembly return a safe garbage instruction assembly 105 | func (encoder *Encoder) GetRandomUnsafeAssembly(destReg string) string { 106 | 107 | // Random register size between 8-16-32-64 108 | randRegSize := int(math.Pow(2, float64(rand.Intn(3+(encoder.architecture/64))+3))) 109 | subReg := "" 110 | for _, i := range REGS[encoder.architecture] { 111 | if (encoder.architecture == 32 && i.Extended == destReg) || (encoder.architecture == 64 && i.Full == destReg) { 112 | switch randRegSize { 113 | case 8: 114 | subReg = i.Low 115 | case 16: 116 | subReg = i.High 117 | case 32: 118 | subReg = i.Extended 119 | case 64: 120 | subReg = i.Full 121 | } 122 | } 123 | } 124 | 125 | if subReg == "" { 126 | panic("invalid register selected") 127 | } 128 | 129 | // Add first unsafe garbage. 130 | newUnsafeMnemonic := encoder.GetRandomUnsafeMnemonic(randRegSize) 131 | // Generate a random operand value based on a random oprerand type of the selected instruction 132 | operand := encoder.GetRandomOperandValue(newUnsafeMnemonic.GetRandomMatchingOperandType(randRegSize)) 133 | unsafeGarbageAssembly := fmt.Sprintf("%s %s,%s;", newUnsafeMnemonic.Mnemonic, subReg, operand) 134 | 135 | return unsafeGarbageAssembly 136 | } 137 | 138 | // GetRandomUnsafeMnemonic returns a random unsafe instruction based on the encoder architecture and operand number/type 139 | // Currently SGN only supports instructions with 2 parameter 140 | func (encoder *Encoder) GetRandomUnsafeMnemonic(opRegSize int) *INSTRUCTION { 141 | 142 | // UnsafeInstructions contains instructions that manipulate certain registers/stack/memory 143 | var UnsafeInstructions []INSTRUCTION 144 | 145 | err := json.NewDecoder(strings.NewReader(INSTRUCTIONS)).Decode(&UnsafeInstructions) 146 | if err != nil { 147 | panic(err) 148 | } 149 | 150 | new := UnsafeInstructions[rand.Intn(len(UnsafeInstructions))] 151 | if ((new.V32 && encoder.GetArchitecture() == 32) || (new.V64 && encoder.GetArchitecture() == 64)) && len(new.Operands) == 2 { 152 | if include(new.Operands[0].Types, fmt.Sprintf("r/m%d", opRegSize)) || include(new.Operands[0].Types, fmt.Sprintf("r%d", opRegSize)) { 153 | // for _, ope := range new.Operands[1].Types { 154 | // // Mnemonic operand types include one of the unsupported types abot ! 155 | // // because it may be the only combination for valid assembly 156 | // if !include(SupportedOperandTypes, ope) { 157 | // return encoder.GetRandomUnsafeMnemonic(opRegSize) 158 | // } 159 | // } 160 | return &new 161 | 162 | } 163 | } 164 | return encoder.GetRandomUnsafeMnemonic(opRegSize) 165 | 166 | } 167 | 168 | // GetRandomOperandValue generates a instruction parameter value based on given operand type 169 | // Only some operand types are considered because SGN only uses 32-64 bit registers 170 | func (encoder *Encoder) GetRandomOperandValue(operandType string) string { 171 | 172 | switch operandType { 173 | case "imm8": 174 | return fmt.Sprintf("0x%x", GetRandomByte()%127) 175 | case "imm16": 176 | return fmt.Sprintf("0x%x", rand.Intn(32767)) 177 | case "imm32": 178 | return fmt.Sprintf("0x%x", rand.Int31n((2147483647))) 179 | case "imm64": 180 | return fmt.Sprintf("0x%x", GetRandomBytes(8)) 181 | case "r8": 182 | return encoder.GetRandomRegister(8) 183 | case "r16": 184 | return encoder.GetRandomRegister(16) 185 | case "r32": 186 | return encoder.GetRandomRegister(32) 187 | case "r64": 188 | return encoder.GetRandomRegister(64) 189 | case "r/m8": 190 | if CoinFlip() { 191 | return encoder.GetRandomOperandValue("m8") 192 | } 193 | return encoder.GetRandomRegister(8) 194 | case "r/m16": 195 | if CoinFlip() { 196 | return encoder.GetRandomOperandValue("m16") 197 | } 198 | return encoder.GetRandomRegister(16) 199 | case "r/m32": 200 | if CoinFlip() { 201 | return encoder.GetRandomOperandValue("m32") 202 | } 203 | return encoder.GetRandomRegister(32) 204 | case "r/m64": 205 | if CoinFlip() { 206 | return encoder.GetRandomOperandValue("m64") 207 | } 208 | return encoder.GetRandomRegister(64) 209 | case "m": 210 | return encoder.GetRandomStackAddress() 211 | case "m8": 212 | return fmt.Sprintf("BYTE PTR %s", encoder.GetRandomStackAddress()) 213 | case "m16": 214 | return fmt.Sprintf("WORD PTR %s", encoder.GetRandomStackAddress()) 215 | case "m32": 216 | return fmt.Sprintf("DWORD PTR %s", encoder.GetRandomStackAddress()) 217 | case "m64": 218 | return fmt.Sprintf("QWORD PTR %s", encoder.GetRandomStackAddress()) 219 | case "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "AH", "AL", "CH", "CL", "DH", "DL", "BH", "BL", "SPL", "BPL", "SIL", "DIL": 220 | return operandType 221 | default: 222 | panic("unsupported instruction operand type: " + operandType) 223 | } 224 | } 225 | 226 | // GetRandomMatchingOperandType randomly selects a operand type for subject instruction 227 | func (ins *INSTRUCTION) GetRandomMatchingOperandType(srcRegSize int) string { 228 | if len(ins.Operands) != 2 { 229 | panic(errors.New("instruction operand index out of range")) 230 | } 231 | if len(ins.Operands[0].Types) == 0 || len(ins.Operands[1].Types) == 0 { 232 | panic(errors.New("instruction operand has no type")) 233 | } 234 | if len(ins.Operands[0].Types) != len(ins.Operands[1].Types) { 235 | panic(errors.New("unsupported instruction operand types")) 236 | } 237 | 238 | index := []int{} 239 | 240 | for i, j := range ins.Operands[0].Types { 241 | if j == fmt.Sprintf("r/m%d", srcRegSize) || j == fmt.Sprintf("r%d", srcRegSize) { 242 | index = append(index, i) 243 | } 244 | } 245 | 246 | return ins.Operands[1].Types[index[rand.Intn(len(index))]] 247 | } 248 | 249 | func include(arr []string, str string) bool { 250 | for _, i := range arr { 251 | if i == str { 252 | return true 253 | } 254 | } 255 | return false 256 | } 257 | 258 | // CalculateAverageGarbageInstructionSize calculate the avarage size of generated random garbage instructions 259 | func (encoder *Encoder) CalculateAverageGarbageInstructionSize() (float64, error) { 260 | 261 | var average float64 = 0 262 | for i := 0; i < 100; i++ { 263 | randomGarbageAssembly := encoder.GenerateGarbageAssembly() 264 | garbage, ok := encoder.Assemble(randomGarbageAssembly) 265 | if !ok { 266 | return 0, errors.New("random garbage instruction assembly failed") 267 | } 268 | average += float64(len(garbage)) 269 | } 270 | average = average / 100 271 | return average, nil 272 | } 273 | 274 | func (encoder *Encoder) debugAssembly(str string) string { 275 | for _, i := range strings.Split(str, ";") { 276 | _, ok := encoder.Assemble(i) 277 | if !ok { 278 | return i 279 | } 280 | } 281 | return "" 282 | } 283 | 284 | // GetRandomFunctionAssembly generates a function frame assembly with garbage instructions inside 285 | func (encoder *Encoder) GetRandomFunctionAssembly() string { 286 | 287 | bp := "" 288 | sp := "" 289 | 290 | switch encoder.architecture { 291 | case 32: 292 | bp = "EBP" 293 | sp = "ESP" 294 | case 64: 295 | bp = "RBP" 296 | sp = "RSP" 297 | default: 298 | panic(errors.New("invalid architecture selected")) 299 | } 300 | 301 | prologue := fmt.Sprintf("PUSH %s;", bp) 302 | prologue += fmt.Sprintf("MOV %s,%s;", bp, sp) 303 | prologue += fmt.Sprintf("SUB %s,0x%x;", sp, GetRandomByte()) 304 | 305 | // Fill the function body with garbage instructions 306 | garbage := encoder.GenerateGarbageAssembly() 307 | 308 | epilogue := fmt.Sprintf("MOV %s,%s;", sp, bp) 309 | epilogue += fmt.Sprintf("POP %s;", bp) 310 | 311 | return prologue + garbage + epilogue 312 | } 313 | 314 | // GenerateGarbageJump generates a JMP instruction over random bytes 315 | func (encoder Encoder) GenerateGarbageJump() ([]byte, error) { 316 | GetRandomBytes := GetRandomBytes(encoder.ObfuscationLimit / 10) 317 | garbageJmp, err := encoder.AddJmpOver(GetRandomBytes) 318 | if err != nil { 319 | return nil, err 320 | } 321 | return garbageJmp, nil 322 | } 323 | 324 | // RandomLabel generates a random assembly label 325 | func RandomLabel() string { 326 | numbers := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 327 | b := make([]rune, 5) 328 | for i := range b { 329 | b[i] = numbers[rand.Intn(len(numbers))] 330 | } 331 | return string(b) 332 | } 333 | -------------------------------------------------------------------------------- /sgn.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "math/rand" 8 | 9 | "github.com/EgeBalci/keystone-go" 10 | ) 11 | 12 | // REG structure for registers 13 | type REG struct { 14 | Full string 15 | Extended string 16 | High string 17 | Low string 18 | Arch int 19 | } 20 | 21 | // INSTRUCTION contains instruction information 22 | // Intel syntax mandates "When two operands are present in an arithmetic or logical instruction, the right operand is the source and the left 23 | // operand is the destination." for our case first operand will allways will be considered destination operand 24 | type INSTRUCTION struct { 25 | Mnemonic string `json:"Mnemonic"` 26 | V64 bool `json:"V64"` 27 | V32 bool `json:"V32"` 28 | Operands []struct { 29 | Types []string `json:"Types"` 30 | } `json:"Operands"` 31 | } 32 | 33 | // Initialize the register values 34 | func init() { 35 | 36 | // Setup x86 GP the register values 37 | REGS = make(map[int][]REG) 38 | REGS[32] = append(REGS[32], REG{Extended: "EAX", High: "AX", Low: "AL", Arch: 32}) 39 | REGS[32] = append(REGS[32], REG{Extended: "EBX", High: "BX", Low: "BL", Arch: 32}) 40 | REGS[32] = append(REGS[32], REG{Extended: "ECX", High: "CX", Low: "CL", Arch: 32}) 41 | REGS[32] = append(REGS[32], REG{Extended: "EDX", High: "DX", Low: "DL", Arch: 32}) 42 | // since there is no way to access 1 byte use above instead 43 | REGS[32] = append(REGS[32], REG{Extended: "ESI", High: "SI", Low: "AL", Arch: 32}) 44 | REGS[32] = append(REGS[32], REG{Extended: "EDI", High: "DI", Low: "BL", Arch: 32}) 45 | // Setup x64 GP the register values 46 | REGS[64] = append(REGS[64], REG{Full: "RAX", Extended: "EAX", High: "AX", Low: "AL", Arch: 64}) 47 | REGS[64] = append(REGS[64], REG{Full: "RBX", Extended: "EBX", High: "BX", Low: "BL", Arch: 64}) 48 | REGS[64] = append(REGS[64], REG{Full: "RCX", Extended: "ECX", High: "CX", Low: "CL", Arch: 64}) 49 | REGS[64] = append(REGS[64], REG{Full: "RDX", Extended: "EDX", High: "DX", Low: "DL", Arch: 64}) 50 | REGS[64] = append(REGS[64], REG{Full: "RSI", Extended: "ESI", High: "SI", Low: "SIL", Arch: 64}) 51 | REGS[64] = append(REGS[64], REG{Full: "RDI", Extended: "EDI", High: "DX", Low: "DIL", Arch: 64}) 52 | REGS[64] = append(REGS[64], REG{Full: "R8", Extended: "R8D", High: "R8W", Low: "R8B", Arch: 64}) 53 | REGS[64] = append(REGS[64], REG{Full: "R9", Extended: "R9D", High: "R9W", Low: "R9B", Arch: 64}) 54 | REGS[64] = append(REGS[64], REG{Full: "R10", Extended: "R10D", High: "R10W", Low: "R10B", Arch: 64}) 55 | REGS[64] = append(REGS[64], REG{Full: "R11", Extended: "R11D", High: "R11W", Low: "R11B", Arch: 64}) 56 | REGS[64] = append(REGS[64], REG{Full: "R12", Extended: "R12D", High: "R12W", Low: "R12B", Arch: 64}) 57 | REGS[64] = append(REGS[64], REG{Full: "R13", Extended: "R13D", High: "R13W", Low: "R13B", Arch: 64}) 58 | REGS[64] = append(REGS[64], REG{Full: "R14", Extended: "R14D", High: "R14W", Low: "R14B", Arch: 64}) 59 | REGS[64] = append(REGS[64], REG{Full: "R15", Extended: "R15D", High: "R15W", Low: "R15B", Arch: 64}) 60 | 61 | // Set the decoder stubs 62 | STUB = make(map[int]string) 63 | STUB[32] = X86_DECODER_STUB 64 | STUB[64] = X64_DECODER_STUB 65 | 66 | // Set safe register prefix/suffix 67 | SafeRegisterPrefix = make(map[int]([]byte)) 68 | SafeRegisterSuffix = make(map[int]([]byte)) 69 | SafeRegisterPrefix[32] = X86_REG_SAVE_PREFIX 70 | SafeRegisterPrefix[64] = X64_REG_SAVE_PREFIX 71 | 72 | SafeRegisterSuffix[32] = X86_REG_SAVE_SUFFIX 73 | SafeRegisterSuffix[64] = X64_REG_SAVE_SUFFIX 74 | } 75 | 76 | // SafeRegisterPrefix contains the instructions for saving registers to stack 77 | var SafeRegisterPrefix map[int]([]byte) 78 | 79 | // SafeRegisterSuffix contains the instructions for restoring registers from stack 80 | var SafeRegisterSuffix map[int]([]byte) 81 | 82 | // X86_REG_SAVE_PREFIX instructions for saving registers to stack 83 | var X86_REG_SAVE_PREFIX = []byte{0x60, 0x9c} // PUSHAD, PUSHFD 84 | // X86_REG_SAVE_SUFFIX instructions for saving registers to stack 85 | var X86_REG_SAVE_SUFFIX = []byte{0x9d, 0x61} // POPFD, POPAD 86 | 87 | // X64_REG_SAVE_PREFIX instructions for saving registers to stack 88 | var X64_REG_SAVE_PREFIX = []byte{ 89 | 0x50, 0x53, 0x51, 0x52, // PUSH RAX,RBX,RCX,RDX 90 | 0x56, 0x57, 0x55, 0x54, // PUSH RSI,RDI,RBP,RSP 91 | 0x41, 0x50, 0x41, 0x51, // PUSH R8,R9 92 | 0x41, 0x52, 0x41, 0x53, // PUSH R10,R11 93 | 0x41, 0x54, 0x41, 0x55, // PUSH R12,R13 94 | 0x41, 0x56, 0x41, 0x57, // PUSH R14,R15 95 | } 96 | 97 | // X64_REG_SAVE_SUFFIX instructions for saving registers to stack 98 | var X64_REG_SAVE_SUFFIX = []byte{ 99 | 0x41, 0x5f, 0x41, 0x5e, // POP R15,R14 100 | 0x41, 0x5d, 0x41, 0x5c, // POP R13,R12 101 | 0x41, 0x5b, 0x41, 0x5a, // POP R11,R10 102 | 0x41, 0x59, 0x41, 0x58, // POP R9,R8 103 | 0x5c, 0x5d, 0x5f, 0x5e, // POP RSP,RBP,RDI,RSI 104 | 0x5a, 0x59, 0x5b, 0x58, // POP RDX,RCX,RBX,RAX 105 | } 106 | 107 | // REGS contains 32/64 bit registers 108 | var REGS map[int][]REG 109 | 110 | // GetRandomRegister returns a random register name based on given size and architecture 111 | func (encoder Encoder) GetRandomRegister(size int) string { 112 | switch size { 113 | case 8: 114 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Low 115 | case 16: 116 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].High 117 | case 32: 118 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Extended 119 | case 64: 120 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Full 121 | default: 122 | panic("invalid register size") 123 | } 124 | 125 | } 126 | 127 | // GetRandomStackAddress returns a stack address assembly referance based on the encoder architecture 128 | // Ex: [esp+10] (address range is 1 byte) 129 | func (encoder Encoder) GetRandomStackAddress() string { 130 | if CoinFlip() { 131 | return fmt.Sprintf("[%s+0x%x]", encoder.GetStackPointer(), GetRandomByte()) 132 | } 133 | return fmt.Sprintf("[%s-0x%x]", encoder.GetStackPointer(), GetRandomByte()) 134 | } 135 | 136 | // GetStackPointer returns the stack pointer register string based on the encoder architecture 137 | func (encoder Encoder) GetStackPointer() string { 138 | switch encoder.architecture { 139 | case 32: 140 | return "ESP" 141 | case 64: 142 | return "RSP" 143 | default: 144 | panic("invalid architecture") 145 | } 146 | 147 | } 148 | 149 | // GetBasePointer returns the base pointer register string based on the encoder architecture 150 | func (encoder Encoder) GetBasePointer() string { 151 | switch encoder.architecture { 152 | case 32: 153 | return "EBP" 154 | case 64: 155 | return "RBP" 156 | default: 157 | panic("invalid architecture") 158 | } 159 | 160 | } 161 | 162 | // GetSafeRandomRegister returns a random register among all (registers-excluded parameters) based on given size 163 | func (encoder Encoder) GetSafeRandomRegister(size int, excludes ...string) (string, error) { 164 | regs := make([]REG, len(REGS[encoder.architecture])) 165 | perm := rand.Perm(len(REGS[encoder.architecture])) 166 | for i, v := range perm { 167 | regs[v] = REGS[encoder.architecture][i] 168 | } 169 | 170 | for _, r := range regs { 171 | excluded := false 172 | for _, x := range excludes { 173 | if r.Extended == x || r.Full == x || r.High == x || r.Low == x { 174 | excluded = true 175 | } 176 | } 177 | 178 | if excluded { 179 | continue 180 | } 181 | 182 | switch size { 183 | case 8: 184 | return r.Low, nil 185 | case 16: 186 | return r.High, nil 187 | case 32: 188 | return r.Extended, nil 189 | case 64: 190 | return r.Full, nil 191 | default: 192 | return "", errors.New("invalid register size") 193 | } 194 | } 195 | return "", errors.New("safe register selection failed!") 196 | } 197 | 198 | // Assemble assembes the given instructions 199 | // and return a byte array with a boolean value indicating wether the operation is successful or not 200 | func (encoder Encoder) Assemble(asm string) ([]byte, bool) { 201 | var mode keystone.Mode 202 | switch encoder.architecture { 203 | case 32: 204 | mode = keystone.MODE_32 205 | case 64: 206 | mode = keystone.MODE_64 207 | default: 208 | return nil, false 209 | } 210 | 211 | ks, err := keystone.New(keystone.ARCH_X86, mode) 212 | if err != nil { 213 | return nil, false 214 | } 215 | defer ks.Close() 216 | 217 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 218 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.KS_OPT_SYNTAX_NASM) 219 | err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 220 | if err != nil { 221 | return nil, false 222 | } 223 | //log.Println(asm) 224 | bin, _, ok := ks.Assemble(asm, 0) 225 | return bin, ok 226 | } 227 | 228 | // GetAssemblySize assembes the given instructions and returns the total instruction size 229 | // if assembly fails return value is -1 230 | func (encoder Encoder) GetAssemblySize(asm string) int { 231 | var mode keystone.Mode 232 | switch encoder.architecture { 233 | case 32: 234 | mode = keystone.MODE_32 235 | case 64: 236 | mode = keystone.MODE_64 237 | default: 238 | return -1 239 | } 240 | 241 | ks, err := keystone.New(keystone.ARCH_X86, mode) 242 | if err != nil { 243 | return -1 244 | } 245 | defer ks.Close() 246 | 247 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 248 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.KS_OPT_SYNTAX_NASM) 249 | err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 250 | if err != nil { 251 | return -1 252 | } 253 | //log.Println(asm) 254 | bin, _, ok := ks.Assemble(asm, 0) 255 | 256 | if !ok { 257 | return -1 258 | } 259 | return len(bin) 260 | } 261 | 262 | // GenerateIPToStack function generates instructions series that pushes the instruction pointer to stack 263 | func (encoder Encoder) GenerateIPToStack() []byte { 264 | 265 | callBin, ok := encoder.Assemble("call 5") 266 | if !ok { 267 | panic("call 5 assembly failed") 268 | } 269 | return callBin 270 | } 271 | 272 | // AddCallOver function adds a call instruction over the end of the given payload 273 | // address of the payload will be pushed to the stack and execution will continiou after the end of payload 274 | func (encoder Encoder) AddCallOver(payload []byte) ([]byte, error) { 275 | 276 | // Perform a shport call over the payload 277 | call := fmt.Sprintf("call 0x%x", len(payload)+5) 278 | callBin, ok := encoder.Assemble(call) 279 | if !ok { 280 | return nil, errors.New("call-over assembly failed") 281 | } 282 | payload = append(callBin, payload...) 283 | 284 | return payload, nil 285 | } 286 | 287 | // AddJmpOver function adds a jmp instruction over the end of the given payload 288 | // execution will continiou after the end of payload 289 | func (encoder Encoder) AddJmpOver(payload []byte) ([]byte, error) { 290 | // JMP 2 -> Jumps to next instruction 291 | // Perform a short call over the payload 292 | jmp := fmt.Sprintf("jmp 0x%x", len(payload)+2) 293 | jmpBin, ok := encoder.Assemble(jmp) 294 | if !ok { 295 | return nil, errors.New("jmp-over assembly failed") 296 | } 297 | payload = append(jmpBin, payload...) 298 | 299 | return payload, nil 300 | } 301 | 302 | // AddCondJmpOver function adds a jmp instruction over the end of the given payload 303 | // execution will continiou after the end of payload 304 | func (encoder Encoder) AddCondJmpOver(payload []byte) ([]byte, error) { 305 | // JZ 2 -> Jumps to next instruction 306 | // Perform a short call over the payload 307 | 308 | randomConditional := ConditionalJumpMnemonics[rand.Intn(len(ConditionalJumpMnemonics))] 309 | 310 | jmp := fmt.Sprintf("%s 0x%x", randomConditional, len(payload)+2) 311 | jmpBin, ok := encoder.Assemble(jmp) 312 | if !ok { 313 | return nil, errors.New("conditional call-over assembly failed") 314 | } 315 | payload = append(jmpBin, payload...) 316 | 317 | return payload, nil 318 | } 319 | 320 | // EncodeFunction handles encoding with current stored options 321 | func EncodeFunction(opts *Options) error { 322 | encoder, err := NewEncoder(opts.Arch) 323 | if err != nil { 324 | return fmt.Errorf("error creating encoder: %w", err) 325 | } 326 | 327 | encoder.ObfuscationLimit = opts.ObsLevel 328 | encoder.PlainDecoder = opts.PlainDecoder 329 | encoder.EncodingCount = opts.EncCount 330 | encoder.SaveRegisters = opts.Safe 331 | 332 | inputData, err := ioutil.ReadFile(opts.Input) 333 | if err != nil { 334 | return fmt.Errorf("error reading input file: %w", err) 335 | } 336 | 337 | encodedPayload, err := encoder.Encode(inputData) 338 | if err != nil { 339 | return fmt.Errorf("error encoding payload: %w", err) 340 | } 341 | 342 | err = ioutil.WriteFile(opts.Output, encodedPayload, 0644) 343 | if err != nil { 344 | return fmt.Errorf("error writing output file: %w", err) 345 | } 346 | 347 | return nil 348 | } 349 | -------------------------------------------------------------------------------- /sgngui.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "strconv" 7 | 8 | "fyne.io/fyne/v2" 9 | "fyne.io/fyne/v2/canvas" 10 | "fyne.io/fyne/v2/container" 11 | "fyne.io/fyne/v2/dialog" 12 | "fyne.io/fyne/v2/layout" 13 | "fyne.io/fyne/v2/widget" 14 | ) 15 | 16 | var storedOptions = &Options{ 17 | Arch: 64, 18 | EncCount: 1, 19 | ObsLevel: 50, 20 | } 21 | 22 | func ShowGUI(mainWindow fyne.Window, statusLabel *canvas.Text, onSave func(*Options)) { 23 | opts := storedOptions 24 | 25 | // Create a new window for the form 26 | formWindow := fyne.CurrentApp().NewWindow("Configuration Options") 27 | 28 | inputEntry := widget.NewEntry() 29 | inputEntry.SetPlaceHolder("Raw or EXE File Path") 30 | inputEntry.SetText(opts.Input) 31 | inputFileButton := widget.NewButton("Open File", func() { 32 | dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) { 33 | if err == nil && reader != nil { 34 | inputEntry.SetText(reader.URI().Path()) 35 | } 36 | }, formWindow).Show() 37 | }) 38 | 39 | outputEntry := widget.NewEntry() 40 | outputEntry.SetPlaceHolder("Output Filename") 41 | outputEntry.SetText(opts.Output) 42 | 43 | archSelect := widget.NewSelect([]string{"32-bit", "64-bit"}, func(value string) { 44 | if value == "32-bit" { 45 | opts.Arch = 32 46 | } else { 47 | opts.Arch = 64 48 | } 49 | }) 50 | if opts.Arch == 32 { 51 | archSelect.SetSelected("32-bit") 52 | } else { 53 | archSelect.SetSelected("64-bit") 54 | } 55 | 56 | encCountSlider := widget.NewSlider(1, 50) 57 | encCountSlider.Step = 1 58 | encCountSlider.Value = 1 59 | encCountSlider.SetValue(float64(opts.EncCount)) 60 | encCountLabel := widget.NewLabel(fmt.Sprintf("Encryption Count: %d", int(encCountSlider.Value))) 61 | encCountSlider.OnChanged = func(value float64) { 62 | encCountLabel.SetText(fmt.Sprintf("Encryption Count: %d", int(value))) 63 | opts.EncCount = int(value) 64 | } 65 | 66 | obsLevelEntry := widget.NewEntry() 67 | obsLevelEntry.SetPlaceHolder("Default:50") 68 | obsLevelEntry.SetText(strconv.Itoa(opts.ObsLevel)) 69 | plainDecoderCheck := widget.NewCheck("Do not encode the decoder stub", nil) 70 | plainDecoderCheck.SetChecked(opts.PlainDecoder) 71 | asciiPayloadCheck := widget.NewCheck("Generates a full ASCII printable payload, may take very long time to bruteforce", nil) 72 | asciiPayloadCheck.SetChecked(opts.AsciiPayload) 73 | safeCheck := widget.NewCheck("Preserve all register values (a.k.a. no clobber)", nil) 74 | safeCheck.SetChecked(opts.Safe) 75 | badCharsEntry := widget.NewEntry() 76 | badCharsEntry.SetPlaceHolder("Specified bad characters given in hex format YOU DON'T WANT TO USE") 77 | badCharsEntry.SetText(opts.BadChars) 78 | verboseCheck := widget.NewCheck("BlueTeam Blinder", nil) 79 | verboseCheck.SetChecked(opts.Verbose) 80 | 81 | form := &widget.Form{ 82 | Items: []*widget.FormItem{ 83 | {Text: "Input", Widget: container.NewBorder(nil, nil, nil, inputFileButton, inputEntry)}, 84 | {Text: "Output", Widget: outputEntry}, 85 | {Text: "Architecture", Widget: archSelect}, 86 | {Text: "Encode Count", Widget: encCountSlider}, 87 | {Text: "", Widget: encCountLabel}, 88 | {Text: "Obfuscation Level", Widget: obsLevelEntry}, 89 | {Text: "Plain Decoder", Widget: plainDecoderCheck}, 90 | {Text: "ASCII Payload", Widget: asciiPayloadCheck}, 91 | {Text: "Safe Mode", Widget: safeCheck}, 92 | {Text: "Bad Characters", Widget: badCharsEntry}, 93 | {Text: "Verbose", Widget: verboseCheck}, 94 | }, 95 | OnSubmit: func() { 96 | opts.Input = inputEntry.Text 97 | opts.Output = outputEntry.Text 98 | opts.ObsLevel, _ = strconv.Atoi(obsLevelEntry.Text) 99 | opts.PlainDecoder = plainDecoderCheck.Checked 100 | opts.AsciiPayload = asciiPayloadCheck.Checked 101 | opts.Safe = safeCheck.Checked 102 | opts.BadChars = badCharsEntry.Text 103 | opts.Verbose = verboseCheck.Checked 104 | 105 | err := ValidateOptions(opts, formWindow) 106 | if err != nil { 107 | return 108 | } 109 | 110 | // Update the global stored options 111 | storedOptions = opts 112 | 113 | // Call your function with opts 114 | configureOptions(opts) 115 | statusLabel.Text = "Check" 116 | statusLabel.Color = color.RGBA{0, 255, 0, 255} 117 | statusLabel.Refresh() 118 | formWindow.Close() 119 | onSave(opts) 120 | }, 121 | } 122 | 123 | formWindow.SetContent(container.New(layout.NewVBoxLayout(), form)) 124 | formWindow.Resize(fyne.NewSize(400, 600)) 125 | formWindow.SetFixedSize(true) 126 | formWindow.Show() 127 | } 128 | 129 | func configureOptions(opts *Options) { 130 | // Your existing logic here, adapted for GUI 131 | if opts.Verbose { 132 | // Set verbose mode in your utility 133 | } 134 | 135 | // Handle other options as needed 136 | // For example: 137 | println("Input: ", opts.Input) 138 | println("Output: ", opts.Output) 139 | println("Architecture: ", opts.Arch) 140 | println("Encode Count: ", opts.EncCount) 141 | println("Obfuscation Level: ", opts.ObsLevel) 142 | println("Plain Decoder: ", opts.PlainDecoder) 143 | println("ASCII Payload: ", opts.AsciiPayload) 144 | println("Safe Mode: ", opts.Safe) 145 | println("Bad Characters: ", opts.BadChars) 146 | println("Verbose: ", opts.Verbose) 147 | } 148 | -------------------------------------------------------------------------------- /sgngui/config.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "errors" 5 | 6 | "fyne.io/fyne/v2" 7 | "fyne.io/fyne/v2/dialog" 8 | ) 9 | 10 | var ( 11 | Version = "?" 12 | ) 13 | 14 | type Options struct { 15 | Input string 16 | Output string 17 | Arch int 18 | EncCount int 19 | ObsLevel int 20 | PlainDecoder bool 21 | AsciiPayload bool 22 | Safe bool 23 | BadChars string 24 | Verbose bool 25 | } 26 | 27 | func ValidateOptions(opts *Options, window fyne.Window) error { 28 | if opts.Input == "" { 29 | dialog.ShowError(errors.New("input file parameter is mandatory"), window) 30 | return errors.New("input file parameter is mandatory") 31 | } 32 | if opts.Output == "" { 33 | dialog.ShowError(errors.New("output file parameter is mandatory"), window) 34 | return errors.New("output file parameter is mandatory") 35 | } 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /sgngui/decode.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | // STUB will contain the decoder stub for the selected architecture 11 | // Values will be set on init 12 | var STUB map[int]string 13 | 14 | // x86DecoderStub is base decoder assembly for 32 bit binaries 15 | const X86_DECODER_STUB = ` 16 | CALL getip 17 | getip: 18 | POP {R} 19 | MOV ECX,{S} 20 | MOV {RL},{K} 21 | decode: 22 | XOR BYTE PTR [{R}+ECX+data-6],{RL} 23 | ADD {RL},BYTE PTR [{R}+ECX+data-6] 24 | LOOP decode 25 | data: 26 | ` 27 | 28 | // x64DecoderStub is base decoder assembly for 64 bit binaries 29 | const X64_DECODER_STUB = ` 30 | MOV {RL},{K} 31 | MOV RCX,{S} 32 | LEA {R},[RIP+data-1] 33 | decode: 34 | XOR BYTE PTR [{R}+RCX],{RL} 35 | ADD {RL},BYTE PTR [{R}+RCX] 36 | LOOP decode 37 | data: 38 | ` 39 | 40 | // NewDecoderAssembly creates a unobfuscated decoder stub to the given encoded payload 41 | // with the given architecture and seed value 42 | func (encoder *Encoder) NewDecoderAssembly(payloadSize int) (string, error) { 43 | 44 | decoder := STUB[encoder.architecture] 45 | reg, err := encoder.GetSafeRandomRegister(encoder.architecture, "ECX") 46 | if err != nil { 47 | return "", err 48 | } 49 | 50 | regL, err := encoder.GetSafeRandomRegister(8, reg, "CL") 51 | if err != nil { 52 | return "", err 53 | } 54 | 55 | decoder = strings.ReplaceAll(decoder, "{R}", reg) 56 | decoder = strings.ReplaceAll(decoder, "{RL}", regL) 57 | decoder = strings.ReplaceAll(decoder, "{K}", fmt.Sprintf("0x%x", encoder.Seed)) 58 | decoder = strings.ReplaceAll(decoder, "{S}", fmt.Sprintf("0x%x", payloadSize)) 59 | // fmt.Println(decoder) 60 | return decoder, nil 61 | } 62 | 63 | // AddADFLDecoder creates decoder stub for binaries that are ciphered with CipherADFL function. 64 | func (encoder *Encoder) AddADFLDecoder(payload []byte) ([]byte, error) { 65 | decoderAssembly, err := encoder.NewDecoderAssembly(len(payload)) 66 | if err != nil { 67 | return nil, err 68 | } 69 | decoder, ok := encoder.Assemble(decoderAssembly) 70 | if !ok { 71 | return nil, errors.New("decoder assembly failed") 72 | } 73 | return append(decoder, payload...), nil 74 | } 75 | 76 | // AddSchemaDecoder creates decoder stub for binaries that are ciphered with SchemaCipher function. 77 | // The schema array that is used on the given payload, architecture of the payload and obfuscation level is required. 78 | func (encoder *Encoder) AddSchemaDecoder(payload []byte, schema SCHEMA) ([]byte, error) { 79 | 80 | index := 0 81 | // Add garbage instrctions before the ciphered decoder stub 82 | garbage, err := encoder.GenerateGarbageInstructions() 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | // Add call instruction over the ciphered payload 88 | payload, err = encoder.AddCallOver(payload) 89 | if err != nil { 90 | return nil, err 91 | } 92 | 93 | payload = append(garbage, payload...) 94 | index += len(garbage) 95 | 96 | // Add garbage instrctions after the ciphered decoder stub 97 | garbage, err = encoder.GenerateGarbageInstructions() 98 | if err != nil { 99 | return nil, err 100 | } 101 | payload = append(payload, garbage...) 102 | 103 | reg, err := encoder.GetSafeRandomRegister(encoder.architecture, encoder.GetStackPointer()) 104 | if err != nil { 105 | return nil, err 106 | } 107 | 108 | pop, ok := encoder.Assemble(fmt.Sprintf("POP %s;", reg)) // !! 109 | if !ok { 110 | return nil, errors.New("schema decoder assembly failed") 111 | } 112 | payload = append(payload, pop...) 113 | 114 | for _, cursor := range schema { 115 | 116 | // Mandatory obfuscation with coin flip for true polimorphism 117 | garbage, err = encoder.GenerateGarbageInstructions() 118 | if err != nil { 119 | return nil, err 120 | } 121 | payload = append(payload, garbage...) 122 | 123 | stepAssembly := "" 124 | if cursor.Key == nil { 125 | stepAssembly += fmt.Sprintf("\t%s DWORD PTR [%s+0x%x];\n", cursor.OP, reg, index) 126 | } else { 127 | stepAssembly += fmt.Sprintf("\t%s DWORD PTR [%s+0x%x],0x%x;\n", cursor.OP, reg, index, binary.BigEndian.Uint32(cursor.Key)) 128 | } 129 | //fmt.Println(stepAssembly) 130 | decipherStep, ok := encoder.Assemble(stepAssembly) 131 | if !ok { 132 | //fmt.Println(stepAssembly) 133 | return nil, errors.New("schema decoder step assembly failed") 134 | } 135 | payload = append(payload, decipherStep...) 136 | index += 4 137 | } 138 | 139 | returnInstruction, ok := encoder.Assemble(fmt.Sprintf("jmp %s;", reg)) 140 | if !ok { 141 | return nil, errors.New("schema decoder return assembly failed") 142 | } 143 | 144 | return append(payload, returnInstruction...), nil 145 | } 146 | -------------------------------------------------------------------------------- /sgngui/encode.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "fmt" 7 | "math/bits" 8 | "math/rand" 9 | "strings" 10 | 11 | "github.com/olekukonko/tablewriter" 12 | ) 13 | 14 | // OPERANDS string array containing logical & arithmetic operands 15 | // for encoding the decoder stub 16 | var OPERANDS = []string{"XOR", "SUB", "ADD", "ROL", "ROR", "NOT"} 17 | 18 | // SCHEMA contains the operand and keys to apply single step encoding 19 | type SCHEMA []struct { 20 | OP string 21 | Key []byte 22 | } 23 | 24 | // Encoder struct for keeping encoder specs 25 | type Encoder struct { 26 | architecture int 27 | ObfuscationLimit int 28 | PlainDecoder bool 29 | Seed byte 30 | EncodingCount int 31 | SaveRegisters bool 32 | } 33 | 34 | // NewEncoder for creating new encoder structures 35 | func NewEncoder(arch int) (*Encoder, error) { 36 | // Create with default settings 37 | encoder := Encoder{ 38 | ObfuscationLimit: 50, 39 | PlainDecoder: false, 40 | Seed: GetRandomByte(), 41 | EncodingCount: 1, 42 | SaveRegisters: false, 43 | } 44 | 45 | switch arch { 46 | case 32: 47 | encoder.architecture = 32 48 | case 64: 49 | encoder.architecture = 64 50 | default: 51 | return nil, errors.New("invalid architecture") 52 | } 53 | 54 | return &encoder, nil 55 | } 56 | 57 | // SetArchitecture sets the encoder architecture 58 | func (encoder *Encoder) SetArchitecture(arch int) error { 59 | switch arch { 60 | case 32: 61 | encoder.architecture = 32 62 | case 64: 63 | encoder.architecture = 64 64 | default: 65 | return errors.New("invalid architecture") 66 | } 67 | return nil 68 | } 69 | 70 | // GetArchitecture returns the encoder architecture 71 | func (encoder *Encoder) GetArchitecture() int { 72 | return encoder.architecture 73 | } 74 | 75 | // Encode function is the primary encode method for SGN 76 | // all necessary options and parameters are contained inside the encoder struct 77 | func (encoder *Encoder) Encode(payload []byte) ([]byte, error) { 78 | var final []byte 79 | if encoder.SaveRegisters { 80 | payload = append(payload, SafeRegisterSuffix[encoder.architecture]...) 81 | } 82 | 83 | // Add garbage instructions before the un-encoded payload 84 | garbage, err := encoder.GenerateGarbageInstructions() 85 | if err != nil { 86 | return nil, err 87 | } 88 | payload = append(garbage, payload...) 89 | 90 | // Apply ADFL cipher to payload 91 | cipheredPayload := CipherADFL(payload, encoder.Seed) 92 | encodedPayload, err := encoder.AddADFLDecoder(cipheredPayload) 93 | if err != nil { 94 | return nil, err 95 | } 96 | 97 | if encoder.PlainDecoder { 98 | final = encodedPayload 99 | } else { 100 | // Add more garbage instructions before the decoder stub 101 | garbage, err = encoder.GenerateGarbageInstructions() 102 | if err != nil { 103 | return nil, err 104 | } 105 | encodedPayload = append(garbage, encodedPayload...) 106 | 107 | // Calculate schema size 108 | schemaSize := ((len(encodedPayload) - len(cipheredPayload)) / (encoder.architecture / 8)) + 1 109 | randomSchema := encoder.NewCipherSchema(schemaSize) 110 | 111 | obfuscatedEncodedPayload := encoder.SchemaCipher(encodedPayload, 0, randomSchema) 112 | final, err = encoder.AddSchemaDecoder(obfuscatedEncodedPayload, randomSchema) 113 | if err != nil { 114 | return nil, err 115 | } 116 | } 117 | 118 | if encoder.EncodingCount > 1 { 119 | encoder.EncodingCount-- 120 | encoder.Seed = GetRandomByte() 121 | final, err = encoder.Encode(final) 122 | if err != nil { 123 | return nil, err 124 | } 125 | } 126 | 127 | if encoder.SaveRegisters { 128 | final = append(SafeRegisterPrefix[encoder.architecture], final...) 129 | } 130 | 131 | return final, nil 132 | } 133 | 134 | // CipherADFL (Additive Feedback Loop) performs an additive feedback XOR operation 135 | // similar to LFSR (Linear-feedback shift register) IN REVERSE ORDER !! with the supplied seed 136 | func CipherADFL(data []byte, seed byte) []byte { 137 | for i := 1; i < len(data)+1; i++ { 138 | current := data[len(data)-i] 139 | data[len(data)-i] ^= seed 140 | seed = byte((int(current) + int(seed)) % 256) 141 | } 142 | return data 143 | } 144 | 145 | // SchemaCipher encodes a part of the given binary starting from the given index. 146 | // Encoding done without using any loop conditions based on the schema values. 147 | // Function performs logical/arithmetic operations given in the schema array. 148 | // If invalid operand supplied function returns nil 149 | func (encoder *Encoder) SchemaCipher(data []byte, index int, schema SCHEMA) []byte { 150 | for _, cursor := range schema { 151 | switch cursor.OP { 152 | case "XOR": 153 | binary.BigEndian.PutUint32(data[index:index+4], (binary.BigEndian.Uint32(data[index:index+4]) ^ binary.LittleEndian.Uint32(cursor.Key))) 154 | case "ADD": 155 | binary.LittleEndian.PutUint32(data[index:index+4], (binary.LittleEndian.Uint32(data[index:index+4])-binary.BigEndian.Uint32(cursor.Key))%0xFFFFFFFF) 156 | case "SUB": 157 | binary.LittleEndian.PutUint32(data[index:index+4], (binary.LittleEndian.Uint32(data[index:index+4])+binary.BigEndian.Uint32(cursor.Key))%0xFFFFFFFF) 158 | case "ROL": 159 | binary.LittleEndian.PutUint32(data[index:index+4], bits.RotateLeft32(binary.LittleEndian.Uint32(data[index:index+4]), -int(binary.BigEndian.Uint32(cursor.Key)))) 160 | case "ROR": 161 | binary.LittleEndian.PutUint32(data[index:index+4], bits.RotateLeft32(binary.LittleEndian.Uint32(data[index:index+4]), int(binary.BigEndian.Uint32(cursor.Key)))) 162 | case "NOT": 163 | binary.BigEndian.PutUint32(data[index:index+4], (^binary.BigEndian.Uint32(data[index : index+4]))) 164 | } 165 | index += 4 166 | } 167 | return data 168 | } 169 | 170 | // RandomOperand generates a random operand string 171 | func RandomOperand() string { 172 | return OPERANDS[rand.Intn(len(OPERANDS))] 173 | } 174 | 175 | // GetRandomByte generates a random single byte 176 | func GetRandomByte() byte { 177 | return byte(rand.Intn(255)) 178 | } 179 | 180 | // GetRandomBytes generates a random byte slice with given size 181 | func GetRandomBytes(num int) []byte { 182 | slice := make([]byte, num) 183 | for i := range slice { 184 | slice[i] = GetRandomByte() 185 | } 186 | return slice 187 | } 188 | 189 | // CoinFlip implements a coin flip which returns true/false 190 | func CoinFlip() bool { 191 | return rand.Intn(2) == 0 192 | } 193 | 194 | // NewCipherSchema generates random schema for 195 | // using in the SchemaCipher function. 196 | // Generated schema contains random operands and keys. 197 | func (encoder *Encoder) NewCipherSchema(num int) SCHEMA { 198 | schema := make(SCHEMA, num) 199 | 200 | for i, cursor := range schema { 201 | cursor.OP = RandomOperand() 202 | if cursor.OP == "NOT" { 203 | cursor.Key = nil 204 | } else if cursor.OP == "ROL" || cursor.OP == "ROR" { 205 | cursor.Key = []byte{0, 0, 0, GetRandomByte()} 206 | } else { 207 | cursor.Key = GetRandomBytes(4) 208 | } 209 | schema[i] = cursor 210 | } 211 | return schema 212 | } 213 | 214 | // GetSchemaTable returns the printable encoder schema table 215 | func GetSchemaTable(schema SCHEMA) string { 216 | data := &strings.Builder{} 217 | table := tablewriter.NewWriter(data) 218 | table.SetHeader([]string{"OPERAND", "KEY"}) 219 | for _, cursor := range schema { 220 | if cursor.Key == nil { 221 | table.Append([]string{cursor.OP, "0x00000000"}) 222 | } else { 223 | table.Append([]string{cursor.OP, fmt.Sprintf("0x%x", cursor.Key)}) 224 | } 225 | } 226 | table.Render() 227 | 228 | return data.String() 229 | } 230 | -------------------------------------------------------------------------------- /sgngui/go.mod: -------------------------------------------------------------------------------- 1 | module config.go 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | fyne.io/fyne/v2 v2.4.5 7 | github.com/EgeBalci/keystone-go v0.0.0-20200525180613-e6c7cd32ceae 8 | github.com/olekukonko/tablewriter v0.0.5 9 | ) 10 | 11 | require ( 12 | github.com/fredbi/uri v1.0.0 // indirect 13 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect 14 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect 15 | github.com/go-text/render v0.1.0 // indirect 16 | github.com/go-text/typesetting v0.1.0 // indirect 17 | github.com/gopherjs/gopherjs v1.17.2 // indirect 18 | github.com/mattn/go-runewidth v0.0.15 // indirect 19 | github.com/rivo/uniseg v0.4.7 // indirect 20 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect 21 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect 22 | github.com/yuin/goldmark v1.5.5 // indirect 23 | golang.org/x/image v0.11.0 // indirect 24 | golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect 25 | golang.org/x/net v0.17.0 // indirect 26 | golang.org/x/sys v0.13.0 // indirect 27 | golang.org/x/text v0.13.0 // indirect 28 | ) 29 | -------------------------------------------------------------------------------- /sgngui/instructions.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | // ConditionalJumpMnemonics contains the conditional branching instruction mnemonics 4 | var ConditionalJumpMnemonics = []string{ 5 | "JAE", 6 | "JA", 7 | "JBE", 8 | "JB", 9 | "JC", 10 | "JE", 11 | "JGE", 12 | "JG", 13 | "JLE", 14 | "JL", 15 | "JNAE", 16 | "JNA", 17 | "JNBE", 18 | "JNB", 19 | "JNC", 20 | "JNE", 21 | "JNGE", 22 | "JNG", 23 | "JNLE", 24 | "JNL", 25 | "JNO", 26 | "JNP", 27 | "JNS", 28 | "JNZ", 29 | "JO", 30 | "JPE", 31 | "JPO", 32 | "JP", 33 | "JS", 34 | "JZ", 35 | } 36 | 37 | // SafeGarbageInstructions array containing safe garbage instructions 38 | // that does not munipulate registers or stack (do not affect the overall execution of the program) 39 | // !!! These instructions must not clobber registers or stack flags may be affected !!! 40 | var SafeGarbageInstructions = []string{ 41 | ";", // no instruction (empty) 42 | "NOP", 43 | "CLD", 44 | "CLC", 45 | "CMC", 46 | "WAIT", 47 | "FNOP", 48 | "FXAM", 49 | "FTST", 50 | "JMP 2", 51 | "XOR {R},0", 52 | "SUB {R},0", 53 | "ADD {R},0", 54 | "BT {R},{R}", 55 | "CMP {R},{R}", 56 | "MOV {R},{R}", 57 | "XCHG {R},{R}", 58 | "TEST {R},{R}", 59 | "CMOVA {R},{R}", 60 | "CMOVB {R},{R}", 61 | "CMOVC {R},{R}", 62 | "CMOVE {R},{R}", 63 | "CMOVG {R},{R}", 64 | "CMOVL {R},{R}", 65 | "CMOVO {R},{R}", 66 | "CMOVP {R},{R}", 67 | "CMOVS {R},{R}", 68 | "CMOVZ {R},{R}", 69 | "CMOVAE {R},{R}", 70 | "CMOVGE {R},{R}", 71 | "CMOVLE {R},{R}", 72 | "CMOVNA {R},{R}", 73 | "CMOVNB {R},{R}", 74 | "CMOVNC {R},{R}", 75 | "CMOVNE {R},{R}", 76 | "CMOVNG {R},{R}", 77 | "CMOVNL {R},{R}", 78 | "CMOVNO {R},{R}", 79 | "CMOVNP {R},{R}", 80 | "CMOVNS {R},{R}", 81 | "CMOVNZ {R},{R}", 82 | "CMOVPE {R},{R}", 83 | "CMOVPO {R},{R}", 84 | "CMOVBE {R},{R}", 85 | "CMOVNAE {R},{R}", 86 | "CMOVNBE {R},{R}", 87 | "CMOVNLE {R},{R}", 88 | "CMOVNGE {R},{R}", 89 | // Recursion starts here... 90 | "JMP {L};{G};{L}:", 91 | "NOT {R};{G};NOT {R}", 92 | "NEG {R};{G};NEG {R}", 93 | "INC {R};{G};DEC {R}", 94 | "DEC {R};{G};INC {R}", 95 | "PUSH {R};{G};POP {R}", 96 | "BSWAP {R};{G};BSWAP {R}", 97 | "ADD {R},{K};{G};SUB {R},{K}", 98 | "SUB {R},{K};{G};ADD {R},{K}", 99 | "ROR {R},{K};{G};ROL {R},{K}", 100 | "ROL {R},{K};{G};ROR {R},{K}", 101 | } 102 | 103 | // SupportedOperandTypes contains all operand types supported by SGN 104 | var SupportedOperandTypes = []string{ 105 | "imm8", 106 | "imm16", 107 | "imm32", 108 | "imm64", 109 | "r8", 110 | "r16", 111 | "r32", 112 | "r64", 113 | "r/m8", 114 | "r/m16", 115 | "r/m32", 116 | "r/m64", 117 | "m", 118 | "m8", 119 | "m16", 120 | "m32", 121 | "m64", 122 | "RAX", 123 | "RCX", 124 | "RDX", 125 | "RBX", 126 | "RSP", 127 | "RBP", 128 | "RSI", 129 | "RDI", 130 | "EAX", 131 | "ECX", 132 | "EDX", 133 | "EBX", 134 | "ESP", 135 | "EBP", 136 | "ESI", 137 | "EDI", 138 | "AX", 139 | "CX", 140 | "DX", 141 | "BX", 142 | "SP", 143 | "BP", 144 | "SI", 145 | "DI", 146 | "AH", 147 | "AL", 148 | "CH", 149 | "CL", 150 | "DH", 151 | "DL", 152 | "BH", 153 | "BL", 154 | "SPL", 155 | "BPL", 156 | "SIL", 157 | "DIL", 158 | } 159 | 160 | // JMP 2 -> Jumps to next instruction 161 | // func addGarbageJumpMnemonics() { 162 | // // for _, i := range ConditionalJumpMnemonics { 163 | // // GarbageMnemonics = append(GarbageMnemonics, i+" 2") 164 | // // } 165 | 166 | // for _, i := range ConditionalJumpMnemonics { 167 | // GarbageMnemonics = append(GarbageMnemonics, i+" {L};{G};{L}:") 168 | // } 169 | // } 170 | 171 | /* 172 | !! BLACKLISTED INSTRUCTIONS !! 173 | 174 | * XCHG 175 | * UD1 176 | * CMPXCHG 177 | * CMPXCHG8B 178 | 179 | */ 180 | 181 | // INSTRUCTIONS contains the ENTIRE x86/x64 instruction set 182 | const INSTRUCTIONS string = ` 183 | 184 | 185 | [ 186 | { 187 | "Mnemonic": "AAD", 188 | "V64": true, 189 | "V32": true, 190 | "Operands": [ 191 | { 192 | "Types": [ 193 | "imm8" 194 | ] 195 | } 196 | ] 197 | }, 198 | { 199 | "Mnemonic": "AAM", 200 | "V64": true, 201 | "V32": true, 202 | "Operands": [ 203 | { 204 | "Types": [ 205 | "imm8" 206 | ] 207 | } 208 | ] 209 | }, 210 | { 211 | "Mnemonic": "ADC", 212 | "V64": true, 213 | "V32": true, 214 | "Operands": [ 215 | { 216 | "Types": [ 217 | "AL", 218 | "AX", 219 | "EAX", 220 | "RAX", 221 | "r/m8", 222 | "r/m8", 223 | "r/m16", 224 | "r/m32", 225 | "r/m64", 226 | "r/m16", 227 | "r/m32", 228 | "r/m64", 229 | "r/m8", 230 | "r/m8", 231 | "r/m16", 232 | "r/m32", 233 | "r/m64", 234 | "r8", 235 | "r8", 236 | "r16", 237 | "r32", 238 | "r64" 239 | ] 240 | }, 241 | { 242 | "Types": [ 243 | "imm8", 244 | "imm16", 245 | "imm32", 246 | "imm32", 247 | "imm8", 248 | "imm8", 249 | "imm16", 250 | "imm32", 251 | "imm32", 252 | "imm8", 253 | "imm8", 254 | "imm8", 255 | "r8", 256 | "r8", 257 | "r16", 258 | "r32", 259 | "r64", 260 | "r/m8", 261 | "r/m8", 262 | "r/m16", 263 | "r/m32", 264 | "r/m64" 265 | ] 266 | } 267 | ] 268 | }, 269 | { 270 | "Mnemonic": "ADCX", 271 | "V64": true, 272 | "V32": true, 273 | "Operands": [ 274 | { 275 | "Types": [ 276 | "r32", 277 | "r64" 278 | ] 279 | }, 280 | { 281 | "Types": [ 282 | "r/m32", 283 | "r/m64" 284 | ] 285 | } 286 | ] 287 | }, 288 | { 289 | "Mnemonic": "ADD", 290 | "V64": true, 291 | "V32": true, 292 | "Operands": [ 293 | { 294 | "Types": [ 295 | "AL", 296 | "AX", 297 | "EAX", 298 | "RAX", 299 | "r/m8", 300 | "r/m8", 301 | "r/m16", 302 | "r/m32", 303 | "r/m64", 304 | "r/m16", 305 | "r/m32", 306 | "r/m64", 307 | "r/m8", 308 | "r/m8", 309 | "r/m16", 310 | "r/m32", 311 | "r/m64", 312 | "r8", 313 | "r8", 314 | "r16", 315 | "r32", 316 | "r64" 317 | ] 318 | }, 319 | { 320 | "Types": [ 321 | "imm8", 322 | "imm16", 323 | "imm32", 324 | "imm32", 325 | "imm8", 326 | "imm8", 327 | "imm16", 328 | "imm32", 329 | "imm32", 330 | "imm8", 331 | "imm8", 332 | "imm8", 333 | "r8", 334 | "r8", 335 | "r16", 336 | "r32", 337 | "r64", 338 | "r/m8", 339 | "r/m8", 340 | "r/m16", 341 | "r/m32", 342 | "r/m64" 343 | ] 344 | } 345 | ] 346 | }, 347 | { 348 | "Mnemonic": "ADOX", 349 | "V64": true, 350 | "V32": true, 351 | "Operands": [ 352 | { 353 | "Types": [ 354 | "r32", 355 | "r64" 356 | ] 357 | }, 358 | { 359 | "Types": [ 360 | "r/m32", 361 | "r/m64" 362 | ] 363 | } 364 | ] 365 | }, 366 | { 367 | "Mnemonic": "AND", 368 | "V64": true, 369 | "V32": true, 370 | "Operands": [ 371 | { 372 | "Types": [ 373 | "AL", 374 | "AX", 375 | "EAX", 376 | "RAX", 377 | "r/m8", 378 | "r/m8", 379 | "r/m16", 380 | "r/m32", 381 | "r/m64", 382 | "r/m16", 383 | "r/m32", 384 | "r/m64", 385 | "r/m8", 386 | "r/m8", 387 | "r/m16", 388 | "r/m32", 389 | "r/m64", 390 | "r8", 391 | "r8", 392 | "r16", 393 | "r32", 394 | "r64" 395 | ] 396 | }, 397 | { 398 | "Types": [ 399 | "imm8", 400 | "imm16", 401 | "imm32", 402 | "imm32", 403 | "imm8", 404 | "imm8", 405 | "imm16", 406 | "imm32", 407 | "imm32", 408 | "imm8", 409 | "imm8", 410 | "imm8", 411 | "r8", 412 | "r8", 413 | "r16", 414 | "r32", 415 | "r64", 416 | "r/m8", 417 | "r/m8", 418 | "r/m16", 419 | "r/m32", 420 | "r/m64" 421 | ] 422 | } 423 | ] 424 | }, 425 | { 426 | "Mnemonic": "BLSI", 427 | "V64": true, 428 | "V32": true, 429 | "Operands": [ 430 | { 431 | "Types": [ 432 | "r32", 433 | "r64" 434 | ] 435 | }, 436 | { 437 | "Types": [ 438 | "r/m32", 439 | "r/m64" 440 | ] 441 | } 442 | ] 443 | }, 444 | { 445 | "Mnemonic": "BLSMSK", 446 | "V64": true, 447 | "V32": true, 448 | "Operands": [ 449 | { 450 | "Types": [ 451 | "r32", 452 | "r64" 453 | ] 454 | }, 455 | { 456 | "Types": [ 457 | "r/m32", 458 | "r/m64" 459 | ] 460 | } 461 | ] 462 | }, 463 | { 464 | "Mnemonic": "BLSR", 465 | "V64": true, 466 | "V32": true, 467 | "Operands": [ 468 | { 469 | "Types": [ 470 | "r32", 471 | "r64" 472 | ] 473 | }, 474 | { 475 | "Types": [ 476 | "r/m32", 477 | "r/m64" 478 | ] 479 | } 480 | ] 481 | }, 482 | { 483 | "Mnemonic": "BSF", 484 | "V64": true, 485 | "V32": true, 486 | "Operands": [ 487 | { 488 | "Types": [ 489 | "r16", 490 | "r32", 491 | "r64" 492 | ] 493 | }, 494 | { 495 | "Types": [ 496 | "r/m16", 497 | "r/m32", 498 | "r/m64" 499 | ] 500 | } 501 | ] 502 | }, 503 | { 504 | "Mnemonic": "BSR", 505 | "V64": true, 506 | "V32": true, 507 | "Operands": [ 508 | { 509 | "Types": [ 510 | "r16", 511 | "r32", 512 | "r64" 513 | ] 514 | }, 515 | { 516 | "Types": [ 517 | "r/m16", 518 | "r/m32", 519 | "r/m64" 520 | ] 521 | } 522 | ] 523 | }, 524 | { 525 | "Mnemonic": "BSWAP", 526 | "V64": true, 527 | "V32": true, 528 | "Operands": [ 529 | { 530 | "Types": [ 531 | "r32", 532 | "r64" 533 | ] 534 | } 535 | ] 536 | }, 537 | { 538 | "Mnemonic": "BT", 539 | "V64": true, 540 | "V32": true, 541 | "Operands": [ 542 | { 543 | "Types": [ 544 | "r/m16", 545 | "r/m32", 546 | "r/m64", 547 | "r/m16", 548 | "r/m32", 549 | "r/m64" 550 | ] 551 | }, 552 | { 553 | "Types": [ 554 | "r16", 555 | "r32", 556 | "r64", 557 | "imm8", 558 | "imm8", 559 | "imm8" 560 | ] 561 | } 562 | ] 563 | }, 564 | { 565 | "Mnemonic": "BTC", 566 | "V64": true, 567 | "V32": true, 568 | "Operands": [ 569 | { 570 | "Types": [ 571 | "r/m16", 572 | "r/m32", 573 | "r/m64", 574 | "r/m16", 575 | "r/m32", 576 | "r/m64" 577 | ] 578 | }, 579 | { 580 | "Types": [ 581 | "r16", 582 | "r32", 583 | "r64", 584 | "imm8", 585 | "imm8", 586 | "imm8" 587 | ] 588 | } 589 | ] 590 | }, 591 | { 592 | "Mnemonic": "BTR", 593 | "V64": true, 594 | "V32": true, 595 | "Operands": [ 596 | { 597 | "Types": [ 598 | "r/m16", 599 | "r/m32", 600 | "r/m64", 601 | "r/m16", 602 | "r/m32", 603 | "r/m64" 604 | ] 605 | }, 606 | { 607 | "Types": [ 608 | "r16", 609 | "r32", 610 | "r64", 611 | "imm8", 612 | "imm8", 613 | "imm8" 614 | ] 615 | } 616 | ] 617 | }, 618 | { 619 | "Mnemonic": "BTS", 620 | "V64": true, 621 | "V32": true, 622 | "Operands": [ 623 | { 624 | "Types": [ 625 | "r/m16", 626 | "r/m32", 627 | "r/m64", 628 | "r/m16", 629 | "r/m32", 630 | "r/m64" 631 | ] 632 | }, 633 | { 634 | "Types": [ 635 | "r16", 636 | "r32", 637 | "r64", 638 | "imm8", 639 | "imm8", 640 | "imm8" 641 | ] 642 | } 643 | ] 644 | }, 645 | { 646 | "Mnemonic": "CALL", 647 | "V64": true, 648 | "V32": true, 649 | "Operands": [ 650 | { 651 | "Types": [ 652 | "r/m16", 653 | "r/m32", 654 | "r/m64" 655 | ] 656 | } 657 | ] 658 | }, 659 | { 660 | "Mnemonic": "CLFLUSH", 661 | "V64": true, 662 | "V32": true, 663 | "Operands": [ 664 | { 665 | "Types": [ 666 | "m8" 667 | ] 668 | } 669 | ] 670 | }, 671 | { 672 | "Mnemonic": "CLFLUSHOPT", 673 | "V64": true, 674 | "V32": true, 675 | "Operands": [ 676 | { 677 | "Types": [ 678 | "m8" 679 | ] 680 | } 681 | ] 682 | }, 683 | { 684 | "Mnemonic": "CLWB", 685 | "V64": true, 686 | "V32": true, 687 | "Operands": [ 688 | { 689 | "Types": [ 690 | "m8" 691 | ] 692 | } 693 | ] 694 | }, 695 | { 696 | "Mnemonic": "CMOVA", 697 | "V64": true, 698 | "V32": true, 699 | "Operands": [ 700 | { 701 | "Types": [ 702 | "r16", 703 | "r32", 704 | "r64" 705 | ] 706 | }, 707 | { 708 | "Types": [ 709 | "r/m16", 710 | "r/m32", 711 | "r/m64" 712 | ] 713 | } 714 | ] 715 | }, 716 | { 717 | "Mnemonic": "CMOVAE", 718 | "V64": true, 719 | "V32": true, 720 | "Operands": [ 721 | { 722 | "Types": [ 723 | "r16", 724 | "r32", 725 | "r64" 726 | ] 727 | }, 728 | { 729 | "Types": [ 730 | "r/m16", 731 | "r/m32", 732 | "r/m64" 733 | ] 734 | } 735 | ] 736 | }, 737 | { 738 | "Mnemonic": "CMOVB", 739 | "V64": true, 740 | "V32": true, 741 | "Operands": [ 742 | { 743 | "Types": [ 744 | "r16", 745 | "r32", 746 | "r64" 747 | ] 748 | }, 749 | { 750 | "Types": [ 751 | "r/m16", 752 | "r/m32", 753 | "r/m64" 754 | ] 755 | } 756 | ] 757 | }, 758 | { 759 | "Mnemonic": "CMOVBE", 760 | "V64": true, 761 | "V32": true, 762 | "Operands": [ 763 | { 764 | "Types": [ 765 | "r16", 766 | "r32", 767 | "r64" 768 | ] 769 | }, 770 | { 771 | "Types": [ 772 | "r/m16", 773 | "r/m32", 774 | "r/m64" 775 | ] 776 | } 777 | ] 778 | }, 779 | { 780 | "Mnemonic": "CMOVC", 781 | "V64": true, 782 | "V32": true, 783 | "Operands": [ 784 | { 785 | "Types": [ 786 | "r16", 787 | "r32", 788 | "r64" 789 | ] 790 | }, 791 | { 792 | "Types": [ 793 | "r/m16", 794 | "r/m32", 795 | "r/m64" 796 | ] 797 | } 798 | ] 799 | }, 800 | { 801 | "Mnemonic": "CMOVE", 802 | "V64": true, 803 | "V32": true, 804 | "Operands": [ 805 | { 806 | "Types": [ 807 | "r16", 808 | "r32", 809 | "r64" 810 | ] 811 | }, 812 | { 813 | "Types": [ 814 | "r/m16", 815 | "r/m32", 816 | "r/m64" 817 | ] 818 | } 819 | ] 820 | }, 821 | { 822 | "Mnemonic": "CMOVG", 823 | "V64": true, 824 | "V32": true, 825 | "Operands": [ 826 | { 827 | "Types": [ 828 | "r16", 829 | "r32", 830 | "r64" 831 | ] 832 | }, 833 | { 834 | "Types": [ 835 | "r/m16", 836 | "r/m32", 837 | "r/m64" 838 | ] 839 | } 840 | ] 841 | }, 842 | { 843 | "Mnemonic": "CMOVGE", 844 | "V64": true, 845 | "V32": true, 846 | "Operands": [ 847 | { 848 | "Types": [ 849 | "r16", 850 | "r32", 851 | "r64" 852 | ] 853 | }, 854 | { 855 | "Types": [ 856 | "r/m16", 857 | "r/m32", 858 | "r/m64" 859 | ] 860 | } 861 | ] 862 | }, 863 | { 864 | "Mnemonic": "CMOVL", 865 | "V64": true, 866 | "V32": true, 867 | "Operands": [ 868 | { 869 | "Types": [ 870 | "r16", 871 | "r32", 872 | "r64" 873 | ] 874 | }, 875 | { 876 | "Types": [ 877 | "r/m16", 878 | "r/m32", 879 | "r/m64" 880 | ] 881 | } 882 | ] 883 | }, 884 | { 885 | "Mnemonic": "CMOVLE", 886 | "V64": true, 887 | "V32": true, 888 | "Operands": [ 889 | { 890 | "Types": [ 891 | "r16", 892 | "r32", 893 | "r64" 894 | ] 895 | }, 896 | { 897 | "Types": [ 898 | "r/m16", 899 | "r/m32", 900 | "r/m64" 901 | ] 902 | } 903 | ] 904 | }, 905 | { 906 | "Mnemonic": "CMOVNA", 907 | "V64": true, 908 | "V32": true, 909 | "Operands": [ 910 | { 911 | "Types": [ 912 | "r16", 913 | "r32", 914 | "r64" 915 | ] 916 | }, 917 | { 918 | "Types": [ 919 | "r/m16", 920 | "r/m32", 921 | "r/m64" 922 | ] 923 | } 924 | ] 925 | }, 926 | { 927 | "Mnemonic": "CMOVNAE", 928 | "V64": true, 929 | "V32": true, 930 | "Operands": [ 931 | { 932 | "Types": [ 933 | "r16", 934 | "r32", 935 | "r64" 936 | ] 937 | }, 938 | { 939 | "Types": [ 940 | "r/m16", 941 | "r/m32", 942 | "r/m64" 943 | ] 944 | } 945 | ] 946 | }, 947 | { 948 | "Mnemonic": "CMOVNB", 949 | "V64": true, 950 | "V32": true, 951 | "Operands": [ 952 | { 953 | "Types": [ 954 | "r16", 955 | "r32", 956 | "r64" 957 | ] 958 | }, 959 | { 960 | "Types": [ 961 | "r/m16", 962 | "r/m32", 963 | "r/m64" 964 | ] 965 | } 966 | ] 967 | }, 968 | { 969 | "Mnemonic": "CMOVNBE", 970 | "V64": true, 971 | "V32": true, 972 | "Operands": [ 973 | { 974 | "Types": [ 975 | "r16", 976 | "r32", 977 | "r64" 978 | ] 979 | }, 980 | { 981 | "Types": [ 982 | "r/m16", 983 | "r/m32", 984 | "r/m64" 985 | ] 986 | } 987 | ] 988 | }, 989 | { 990 | "Mnemonic": "CMOVNC", 991 | "V64": true, 992 | "V32": true, 993 | "Operands": [ 994 | { 995 | "Types": [ 996 | "r16", 997 | "r32", 998 | "r64" 999 | ] 1000 | }, 1001 | { 1002 | "Types": [ 1003 | "r/m16", 1004 | "r/m32", 1005 | "r/m64" 1006 | ] 1007 | } 1008 | ] 1009 | }, 1010 | { 1011 | "Mnemonic": "CMOVNE", 1012 | "V64": true, 1013 | "V32": true, 1014 | "Operands": [ 1015 | { 1016 | "Types": [ 1017 | "r16", 1018 | "r32", 1019 | "r64" 1020 | ] 1021 | }, 1022 | { 1023 | "Types": [ 1024 | "r/m16", 1025 | "r/m32", 1026 | "r/m64" 1027 | ] 1028 | } 1029 | ] 1030 | }, 1031 | { 1032 | "Mnemonic": "CMOVNG", 1033 | "V64": true, 1034 | "V32": true, 1035 | "Operands": [ 1036 | { 1037 | "Types": [ 1038 | "r16", 1039 | "r32", 1040 | "r64" 1041 | ] 1042 | }, 1043 | { 1044 | "Types": [ 1045 | "r/m16", 1046 | "r/m32", 1047 | "r/m64" 1048 | ] 1049 | } 1050 | ] 1051 | }, 1052 | { 1053 | "Mnemonic": "CMOVNGE", 1054 | "V64": true, 1055 | "V32": true, 1056 | "Operands": [ 1057 | { 1058 | "Types": [ 1059 | "r16", 1060 | "r32", 1061 | "r64" 1062 | ] 1063 | }, 1064 | { 1065 | "Types": [ 1066 | "r/m16", 1067 | "r/m32", 1068 | "r/m64" 1069 | ] 1070 | } 1071 | ] 1072 | }, 1073 | { 1074 | "Mnemonic": "CMOVNL", 1075 | "V64": true, 1076 | "V32": true, 1077 | "Operands": [ 1078 | { 1079 | "Types": [ 1080 | "r16", 1081 | "r32", 1082 | "r64" 1083 | ] 1084 | }, 1085 | { 1086 | "Types": [ 1087 | "r/m16", 1088 | "r/m32", 1089 | "r/m64" 1090 | ] 1091 | } 1092 | ] 1093 | }, 1094 | { 1095 | "Mnemonic": "CMOVNLE", 1096 | "V64": true, 1097 | "V32": true, 1098 | "Operands": [ 1099 | { 1100 | "Types": [ 1101 | "r16", 1102 | "r32", 1103 | "r64" 1104 | ] 1105 | }, 1106 | { 1107 | "Types": [ 1108 | "r/m16", 1109 | "r/m32", 1110 | "r/m64" 1111 | ] 1112 | } 1113 | ] 1114 | }, 1115 | { 1116 | "Mnemonic": "CMOVNO", 1117 | "V64": true, 1118 | "V32": true, 1119 | "Operands": [ 1120 | { 1121 | "Types": [ 1122 | "r16", 1123 | "r32", 1124 | "r64" 1125 | ] 1126 | }, 1127 | { 1128 | "Types": [ 1129 | "r/m16", 1130 | "r/m32", 1131 | "r/m64" 1132 | ] 1133 | } 1134 | ] 1135 | }, 1136 | { 1137 | "Mnemonic": "CMOVNP", 1138 | "V64": true, 1139 | "V32": true, 1140 | "Operands": [ 1141 | { 1142 | "Types": [ 1143 | "r16", 1144 | "r32", 1145 | "r64" 1146 | ] 1147 | }, 1148 | { 1149 | "Types": [ 1150 | "r/m16", 1151 | "r/m32", 1152 | "r/m64" 1153 | ] 1154 | } 1155 | ] 1156 | }, 1157 | { 1158 | "Mnemonic": "CMOVNS", 1159 | "V64": true, 1160 | "V32": true, 1161 | "Operands": [ 1162 | { 1163 | "Types": [ 1164 | "r16", 1165 | "r32", 1166 | "r64" 1167 | ] 1168 | }, 1169 | { 1170 | "Types": [ 1171 | "r/m16", 1172 | "r/m32", 1173 | "r/m64" 1174 | ] 1175 | } 1176 | ] 1177 | }, 1178 | { 1179 | "Mnemonic": "CMOVNZ", 1180 | "V64": true, 1181 | "V32": true, 1182 | "Operands": [ 1183 | { 1184 | "Types": [ 1185 | "r16", 1186 | "r32", 1187 | "r64" 1188 | ] 1189 | }, 1190 | { 1191 | "Types": [ 1192 | "r/m16", 1193 | "r/m32", 1194 | "r/m64" 1195 | ] 1196 | } 1197 | ] 1198 | }, 1199 | { 1200 | "Mnemonic": "CMOVO", 1201 | "V64": true, 1202 | "V32": true, 1203 | "Operands": [ 1204 | { 1205 | "Types": [ 1206 | "r16", 1207 | "r32", 1208 | "r64" 1209 | ] 1210 | }, 1211 | { 1212 | "Types": [ 1213 | "r/m16", 1214 | "r/m32", 1215 | "r/m64" 1216 | ] 1217 | } 1218 | ] 1219 | }, 1220 | { 1221 | "Mnemonic": "CMOVP", 1222 | "V64": true, 1223 | "V32": true, 1224 | "Operands": [ 1225 | { 1226 | "Types": [ 1227 | "r16", 1228 | "r32", 1229 | "r64" 1230 | ] 1231 | }, 1232 | { 1233 | "Types": [ 1234 | "r/m16", 1235 | "r/m32", 1236 | "r/m64" 1237 | ] 1238 | } 1239 | ] 1240 | }, 1241 | { 1242 | "Mnemonic": "CMOVPE", 1243 | "V64": true, 1244 | "V32": true, 1245 | "Operands": [ 1246 | { 1247 | "Types": [ 1248 | "r16", 1249 | "r32", 1250 | "r64" 1251 | ] 1252 | }, 1253 | { 1254 | "Types": [ 1255 | "r/m16", 1256 | "r/m32", 1257 | "r/m64" 1258 | ] 1259 | } 1260 | ] 1261 | }, 1262 | { 1263 | "Mnemonic": "CMP", 1264 | "V64": true, 1265 | "V32": true, 1266 | "Operands": [ 1267 | { 1268 | "Types": [ 1269 | "AL", 1270 | "AX", 1271 | "EAX", 1272 | "RAX", 1273 | "r/m8", 1274 | "r/m8", 1275 | "r/m16", 1276 | "r/m32", 1277 | "r/m64", 1278 | "r/m16", 1279 | "r/m32", 1280 | "r/m64", 1281 | "r/m8", 1282 | "r/m8", 1283 | "r/m16", 1284 | "r/m32", 1285 | "r/m64", 1286 | "r8", 1287 | "r8", 1288 | "r16", 1289 | "r32", 1290 | "r64" 1291 | ] 1292 | }, 1293 | { 1294 | "Types": [ 1295 | "imm8", 1296 | "imm16", 1297 | "imm32", 1298 | "imm32", 1299 | "imm8", 1300 | "imm8", 1301 | "imm16", 1302 | "imm32", 1303 | "imm32", 1304 | "imm8", 1305 | "imm8", 1306 | "imm8", 1307 | "r8", 1308 | "r8", 1309 | "r16", 1310 | "r32", 1311 | "r64", 1312 | "r/m8", 1313 | "r/m8", 1314 | "r/m16", 1315 | "r/m32", 1316 | "r/m64" 1317 | ] 1318 | } 1319 | ] 1320 | }, 1321 | { 1322 | "Mnemonic": "CMPS", 1323 | "V64": true, 1324 | "V32": true, 1325 | "Operands": [ 1326 | { 1327 | "Types": [ 1328 | "m8", 1329 | "m16", 1330 | "m32", 1331 | "m64" 1332 | ] 1333 | }, 1334 | { 1335 | "Types": [ 1336 | "m8", 1337 | "m16", 1338 | "m32", 1339 | "m64" 1340 | ] 1341 | } 1342 | ] 1343 | }, 1344 | { 1345 | "Mnemonic": "CRC32", 1346 | "V64": true, 1347 | "V32": true, 1348 | "Operands": [ 1349 | { 1350 | "Types": [ 1351 | "r32", 1352 | "r32", 1353 | "r32", 1354 | "r32", 1355 | "r64", 1356 | "r64" 1357 | ] 1358 | }, 1359 | { 1360 | "Types": [ 1361 | "r/m8", 1362 | "r/m8", 1363 | "r/m16", 1364 | "r/m32", 1365 | "r/m8", 1366 | "r/m64" 1367 | ] 1368 | } 1369 | ] 1370 | }, 1371 | { 1372 | "Mnemonic": "DEC", 1373 | "V64": true, 1374 | "V32": true, 1375 | "Operands": [ 1376 | { 1377 | "Types": [ 1378 | "r/m8", 1379 | "r/m8", 1380 | "r/m16", 1381 | "r/m32", 1382 | "r/m64", 1383 | "r16", 1384 | "r32" 1385 | ] 1386 | } 1387 | ] 1388 | }, 1389 | { 1390 | "Mnemonic": "DIV", 1391 | "V64": true, 1392 | "V32": true, 1393 | "Operands": [ 1394 | { 1395 | "Types": [ 1396 | "r/m8", 1397 | "r/m8", 1398 | "r/m16", 1399 | "r/m32", 1400 | "r/m64" 1401 | ] 1402 | } 1403 | ] 1404 | }, 1405 | { 1406 | "Mnemonic": "ENTER", 1407 | "V64": true, 1408 | "V32": true, 1409 | "Operands": [ 1410 | { 1411 | "Types": [ 1412 | "imm16" 1413 | ] 1414 | }, 1415 | { 1416 | "Types": [ 1417 | "imm8" 1418 | ] 1419 | } 1420 | ] 1421 | }, 1422 | { 1423 | "Mnemonic": "FSTSW", 1424 | "V64": true, 1425 | "V32": true, 1426 | "Operands": [ 1427 | { 1428 | "Types": [ 1429 | "AX" 1430 | ] 1431 | } 1432 | ] 1433 | }, 1434 | { 1435 | "Mnemonic": "FNSTSW", 1436 | "V64": true, 1437 | "V32": true, 1438 | "Operands": [ 1439 | { 1440 | "Types": [ 1441 | "AX" 1442 | ] 1443 | } 1444 | ] 1445 | }, 1446 | { 1447 | "Mnemonic": "IDIV", 1448 | "V64": true, 1449 | "V32": true, 1450 | "Operands": [ 1451 | { 1452 | "Types": [ 1453 | "r/m8", 1454 | "r/m8", 1455 | "r/m16", 1456 | "r/m32", 1457 | "r/m64" 1458 | ] 1459 | } 1460 | ] 1461 | }, 1462 | { 1463 | "Mnemonic": "IMUL", 1464 | "V64": true, 1465 | "V32": true, 1466 | "Operands": [ 1467 | { 1468 | "Types": [ 1469 | "r/m8", 1470 | "r/m16", 1471 | "r/m32", 1472 | "r/m64" 1473 | ] 1474 | } 1475 | ] 1476 | }, 1477 | { 1478 | "Mnemonic": "INC", 1479 | "V64": true, 1480 | "V32": true, 1481 | "Operands": [ 1482 | { 1483 | "Types": [ 1484 | "r/m8", 1485 | "r/m8", 1486 | "r/m16", 1487 | "r/m32", 1488 | "r/m64", 1489 | "r16", 1490 | "r32" 1491 | ] 1492 | } 1493 | ] 1494 | }, 1495 | { 1496 | "Mnemonic": "INS", 1497 | "V64": true, 1498 | "V32": true, 1499 | "Operands": [ 1500 | { 1501 | "Types": [ 1502 | "m8", 1503 | "m16", 1504 | "m32" 1505 | ] 1506 | }, 1507 | { 1508 | "Types": [ 1509 | "DX", 1510 | "DX", 1511 | "DX" 1512 | ] 1513 | } 1514 | ] 1515 | }, 1516 | { 1517 | "Mnemonic": "INVLPG", 1518 | "V64": true, 1519 | "V32": true, 1520 | "Operands": [ 1521 | { 1522 | "Types": [ 1523 | "m" 1524 | ] 1525 | } 1526 | ] 1527 | }, 1528 | { 1529 | "Mnemonic": "JMP", 1530 | "V64": true, 1531 | "V32": true, 1532 | "Operands": [ 1533 | { 1534 | "Types": [ 1535 | "r/m16", 1536 | "r/m32", 1537 | "r/m64" 1538 | ] 1539 | } 1540 | ] 1541 | }, 1542 | { 1543 | "Mnemonic": "LDMXCSR", 1544 | "V64": true, 1545 | "V32": true, 1546 | "Operands": [ 1547 | { 1548 | "Types": [ 1549 | "m32" 1550 | ] 1551 | } 1552 | ] 1553 | }, 1554 | { 1555 | "Mnemonic": "VLDMXCSR", 1556 | "V64": true, 1557 | "V32": true, 1558 | "Operands": [ 1559 | { 1560 | "Types": [ 1561 | "m32" 1562 | ] 1563 | } 1564 | ] 1565 | }, 1566 | { 1567 | "Mnemonic": "LEA", 1568 | "V64": true, 1569 | "V32": true, 1570 | "Operands": [ 1571 | { 1572 | "Types": [ 1573 | "r16", 1574 | "r32", 1575 | "r64" 1576 | ] 1577 | }, 1578 | { 1579 | "Types": [ 1580 | "m", 1581 | "m", 1582 | "m" 1583 | ] 1584 | } 1585 | ] 1586 | }, 1587 | { 1588 | "Mnemonic": "LMSW", 1589 | "V64": true, 1590 | "V32": true, 1591 | "Operands": [ 1592 | { 1593 | "Types": [ 1594 | "r/m16" 1595 | ] 1596 | } 1597 | ] 1598 | }, 1599 | { 1600 | "Mnemonic": "LODS", 1601 | "V64": true, 1602 | "V32": true, 1603 | "Operands": [ 1604 | { 1605 | "Types": [ 1606 | "m8", 1607 | "m16", 1608 | "m32", 1609 | "m64" 1610 | ] 1611 | } 1612 | ] 1613 | }, 1614 | { 1615 | "Mnemonic": "LZCNT", 1616 | "V64": true, 1617 | "V32": true, 1618 | "Operands": [ 1619 | { 1620 | "Types": [ 1621 | "r16", 1622 | "r32", 1623 | "r64" 1624 | ] 1625 | }, 1626 | { 1627 | "Types": [ 1628 | "r/m16", 1629 | "r/m32", 1630 | "r/m64" 1631 | ] 1632 | } 1633 | ] 1634 | }, 1635 | { 1636 | "Mnemonic": "MOV", 1637 | "V64": true, 1638 | "V32": true, 1639 | "Operands": [ 1640 | { 1641 | "Types": [ 1642 | "r/m8", 1643 | "r/m8", 1644 | "r/m16", 1645 | "r/m32", 1646 | "r/m64", 1647 | "r8", 1648 | "r8", 1649 | "r16", 1650 | "r32", 1651 | "r64", 1652 | "r8", 1653 | "r8", 1654 | "r16", 1655 | "r32", 1656 | "r64", 1657 | "r/m8", 1658 | "r/m8", 1659 | "r/m16", 1660 | "r/m32", 1661 | "r/m64" 1662 | ] 1663 | }, 1664 | { 1665 | "Types": [ 1666 | "r8", 1667 | "r8", 1668 | "r16", 1669 | "r32", 1670 | "r64", 1671 | "r/m8", 1672 | "r/m8", 1673 | "r/m16", 1674 | "r/m32", 1675 | "r/m64", 1676 | "imm8", 1677 | "imm8", 1678 | "imm16", 1679 | "imm32", 1680 | "imm64", 1681 | "imm8", 1682 | "imm8", 1683 | "imm16", 1684 | "imm32", 1685 | "imm32" 1686 | ] 1687 | } 1688 | ] 1689 | }, 1690 | { 1691 | "Mnemonic": "MOVBE", 1692 | "V64": true, 1693 | "V32": true, 1694 | "Operands": [ 1695 | { 1696 | "Types": [ 1697 | "r16", 1698 | "r32", 1699 | "r64", 1700 | "m16", 1701 | "m32", 1702 | "m64" 1703 | ] 1704 | }, 1705 | { 1706 | "Types": [ 1707 | "m16", 1708 | "m32", 1709 | "m64", 1710 | "r16", 1711 | "r32", 1712 | "r64" 1713 | ] 1714 | } 1715 | ] 1716 | }, 1717 | { 1718 | "Mnemonic": "MOVNTI", 1719 | "V64": true, 1720 | "V32": true, 1721 | "Operands": [ 1722 | { 1723 | "Types": [ 1724 | "m32", 1725 | "m64" 1726 | ] 1727 | }, 1728 | { 1729 | "Types": [ 1730 | "r32", 1731 | "r64" 1732 | ] 1733 | } 1734 | ] 1735 | }, 1736 | { 1737 | "Mnemonic": "MOVS", 1738 | "V64": true, 1739 | "V32": true, 1740 | "Operands": [ 1741 | { 1742 | "Types": [ 1743 | "m8", 1744 | "m16", 1745 | "m32", 1746 | "m64" 1747 | ] 1748 | }, 1749 | { 1750 | "Types": [ 1751 | "m8", 1752 | "m16", 1753 | "m32", 1754 | "m64" 1755 | ] 1756 | } 1757 | ] 1758 | }, 1759 | { 1760 | "Mnemonic": "MOVSX", 1761 | "V64": true, 1762 | "V32": true, 1763 | "Operands": [ 1764 | { 1765 | "Types": [ 1766 | "r16", 1767 | "r32", 1768 | "r64", 1769 | "r32", 1770 | "r64" 1771 | ] 1772 | }, 1773 | { 1774 | "Types": [ 1775 | "r/m8", 1776 | "r/m8", 1777 | "r/m8", 1778 | "r/m16", 1779 | "r/m16" 1780 | ] 1781 | } 1782 | ] 1783 | }, 1784 | { 1785 | "Mnemonic": "MOVZX", 1786 | "V64": true, 1787 | "V32": true, 1788 | "Operands": [ 1789 | { 1790 | "Types": [ 1791 | "r16", 1792 | "r32", 1793 | "r64", 1794 | "r32", 1795 | "r64" 1796 | ] 1797 | }, 1798 | { 1799 | "Types": [ 1800 | "r/m8", 1801 | "r/m8", 1802 | "r/m8", 1803 | "r/m16", 1804 | "r/m16" 1805 | ] 1806 | } 1807 | ] 1808 | }, 1809 | { 1810 | "Mnemonic": "MUL", 1811 | "V64": true, 1812 | "V32": true, 1813 | "Operands": [ 1814 | { 1815 | "Types": [ 1816 | "r/m8", 1817 | "r/m8", 1818 | "r/m16", 1819 | "r/m32", 1820 | "r/m64" 1821 | ] 1822 | } 1823 | ] 1824 | }, 1825 | { 1826 | "Mnemonic": "NEG", 1827 | "V64": true, 1828 | "V32": true, 1829 | "Operands": [ 1830 | { 1831 | "Types": [ 1832 | "r/m8", 1833 | "r/m8", 1834 | "r/m16", 1835 | "r/m32", 1836 | "r/m64" 1837 | ] 1838 | } 1839 | ] 1840 | }, 1841 | { 1842 | "Mnemonic": "NOP", 1843 | "V64": true, 1844 | "V32": true, 1845 | "Operands": [ 1846 | { 1847 | "Types": [ 1848 | "r/m16", 1849 | "r/m32" 1850 | ] 1851 | } 1852 | ] 1853 | }, 1854 | { 1855 | "Mnemonic": "NOT", 1856 | "V64": true, 1857 | "V32": true, 1858 | "Operands": [ 1859 | { 1860 | "Types": [ 1861 | "r/m8", 1862 | "r/m8", 1863 | "r/m16", 1864 | "r/m32", 1865 | "r/m64" 1866 | ] 1867 | } 1868 | ] 1869 | }, 1870 | { 1871 | "Mnemonic": "OR", 1872 | "V64": true, 1873 | "V32": true, 1874 | "Operands": [ 1875 | { 1876 | "Types": [ 1877 | "AL", 1878 | "AX", 1879 | "EAX", 1880 | "RAX", 1881 | "r/m8", 1882 | "r/m8", 1883 | "r/m16", 1884 | "r/m32", 1885 | "r/m64", 1886 | "r/m16", 1887 | "r/m32", 1888 | "r/m64", 1889 | "r/m8", 1890 | "r/m8", 1891 | "r/m16", 1892 | "r/m32", 1893 | "r/m64", 1894 | "r8", 1895 | "r8", 1896 | "r16", 1897 | "r32", 1898 | "r64" 1899 | ] 1900 | }, 1901 | { 1902 | "Types": [ 1903 | "imm8", 1904 | "imm16", 1905 | "imm32", 1906 | "imm32", 1907 | "imm8", 1908 | "imm8", 1909 | "imm16", 1910 | "imm32", 1911 | "imm32", 1912 | "imm8", 1913 | "imm8", 1914 | "imm8", 1915 | "r8", 1916 | "r8", 1917 | "r16", 1918 | "r32", 1919 | "r64", 1920 | "r/m8", 1921 | "r/m8", 1922 | "r/m16", 1923 | "r/m32", 1924 | "r/m64" 1925 | ] 1926 | } 1927 | ] 1928 | }, 1929 | { 1930 | "Mnemonic": "OUT", 1931 | "V64": true, 1932 | "V32": true, 1933 | "Operands": [ 1934 | { 1935 | "Types": [ 1936 | "imm8", 1937 | "imm8", 1938 | "imm8", 1939 | "DX", 1940 | "DX", 1941 | "DX" 1942 | ] 1943 | }, 1944 | { 1945 | "Types": [ 1946 | "AL", 1947 | "AX", 1948 | "EAX", 1949 | "AL", 1950 | "AX", 1951 | "EAX" 1952 | ] 1953 | } 1954 | ] 1955 | }, 1956 | { 1957 | "Mnemonic": "OUTS", 1958 | "V64": true, 1959 | "V32": true, 1960 | "Operands": [ 1961 | { 1962 | "Types": [ 1963 | "DX", 1964 | "DX", 1965 | "DX" 1966 | ] 1967 | }, 1968 | { 1969 | "Types": [ 1970 | "m8", 1971 | "m16", 1972 | "m32" 1973 | ] 1974 | } 1975 | ] 1976 | }, 1977 | { 1978 | "Mnemonic": "POP", 1979 | "V64": true, 1980 | "V32": true, 1981 | "Operands": [ 1982 | { 1983 | "Types": [ 1984 | "r/m16", 1985 | "r/m32", 1986 | "r/m64", 1987 | "r16", 1988 | "r32", 1989 | "r64" 1990 | ] 1991 | } 1992 | ] 1993 | }, 1994 | { 1995 | "Mnemonic": "POPCNT", 1996 | "V64": true, 1997 | "V32": true, 1998 | "Operands": [ 1999 | { 2000 | "Types": [ 2001 | "r16", 2002 | "r32", 2003 | "r64" 2004 | ] 2005 | }, 2006 | { 2007 | "Types": [ 2008 | "r/m16", 2009 | "r/m32", 2010 | "r/m64" 2011 | ] 2012 | } 2013 | ] 2014 | }, 2015 | { 2016 | "Mnemonic": "PREFETCHT0", 2017 | "V64": true, 2018 | "V32": true, 2019 | "Operands": [ 2020 | { 2021 | "Types": [ 2022 | "m8" 2023 | ] 2024 | } 2025 | ] 2026 | }, 2027 | { 2028 | "Mnemonic": "PREFETCHT1", 2029 | "V64": true, 2030 | "V32": true, 2031 | "Operands": [ 2032 | { 2033 | "Types": [ 2034 | "m8" 2035 | ] 2036 | } 2037 | ] 2038 | }, 2039 | { 2040 | "Mnemonic": "PREFETCHT2", 2041 | "V64": true, 2042 | "V32": true, 2043 | "Operands": [ 2044 | { 2045 | "Types": [ 2046 | "m8" 2047 | ] 2048 | } 2049 | ] 2050 | }, 2051 | { 2052 | "Mnemonic": "PREFETCHNTA", 2053 | "V64": true, 2054 | "V32": true, 2055 | "Operands": [ 2056 | { 2057 | "Types": [ 2058 | "m8" 2059 | ] 2060 | } 2061 | ] 2062 | }, 2063 | { 2064 | "Mnemonic": "PREFETCHW", 2065 | "V64": true, 2066 | "V32": true, 2067 | "Operands": [ 2068 | { 2069 | "Types": [ 2070 | "m8" 2071 | ] 2072 | } 2073 | ] 2074 | }, 2075 | { 2076 | "Mnemonic": "PREFETCHWT1", 2077 | "V64": true, 2078 | "V32": true, 2079 | "Operands": [ 2080 | { 2081 | "Types": [ 2082 | "m8" 2083 | ] 2084 | } 2085 | ] 2086 | }, 2087 | { 2088 | "Mnemonic": "PUSH", 2089 | "V64": true, 2090 | "V32": true, 2091 | "Operands": [ 2092 | { 2093 | "Types": [ 2094 | "r/m16", 2095 | "r/m32", 2096 | "r/m64", 2097 | "r16", 2098 | "r32", 2099 | "r64", 2100 | "imm8", 2101 | "imm16", 2102 | "imm32" 2103 | ] 2104 | } 2105 | ] 2106 | }, 2107 | { 2108 | "Mnemonic": "RCL", 2109 | "V64": true, 2110 | "V32": true, 2111 | "Operands": [ 2112 | { 2113 | "Types": [ 2114 | "r/m8", 2115 | "r/m8", 2116 | "r/m8", 2117 | "r/m8", 2118 | "r/m16", 2119 | "r/m16", 2120 | "r/m32", 2121 | "r/m64", 2122 | "r/m32", 2123 | "r/m64" 2124 | ] 2125 | }, 2126 | { 2127 | "Types": [ 2128 | "CL", 2129 | "CL", 2130 | "imm8", 2131 | "imm8", 2132 | "CL", 2133 | "imm8", 2134 | "CL", 2135 | "CL", 2136 | "imm8", 2137 | "imm8" 2138 | ] 2139 | } 2140 | ] 2141 | }, 2142 | { 2143 | "Mnemonic": "RCR", 2144 | "V64": true, 2145 | "V32": true, 2146 | "Operands": [ 2147 | { 2148 | "Types": [ 2149 | "r/m8", 2150 | "r/m8", 2151 | "r/m8", 2152 | "r/m8", 2153 | "r/m16", 2154 | "r/m16", 2155 | "r/m32", 2156 | "r/m64", 2157 | "r/m32", 2158 | "r/m64" 2159 | ] 2160 | }, 2161 | { 2162 | "Types": [ 2163 | "CL", 2164 | "CL", 2165 | "imm8", 2166 | "imm8", 2167 | "CL", 2168 | "imm8", 2169 | "CL", 2170 | "CL", 2171 | "imm8", 2172 | "imm8" 2173 | ] 2174 | } 2175 | ] 2176 | }, 2177 | { 2178 | "Mnemonic": "ROL", 2179 | "V64": true, 2180 | "V32": true, 2181 | "Operands": [ 2182 | { 2183 | "Types": [ 2184 | "r/m8", 2185 | "r/m8", 2186 | "r/m8", 2187 | "r/m8", 2188 | "r/m16", 2189 | "r/m16", 2190 | "r/m32", 2191 | "r/m64", 2192 | "r/m32", 2193 | "r/m64" 2194 | ] 2195 | }, 2196 | { 2197 | "Types": [ 2198 | "CL", 2199 | "CL", 2200 | "imm8", 2201 | "imm8", 2202 | "CL", 2203 | "imm8", 2204 | "CL", 2205 | "CL", 2206 | "imm8", 2207 | "imm8" 2208 | ] 2209 | } 2210 | ] 2211 | }, 2212 | { 2213 | "Mnemonic": "ROR", 2214 | "V64": true, 2215 | "V32": true, 2216 | "Operands": [ 2217 | { 2218 | "Types": [ 2219 | "r/m8", 2220 | "r/m8", 2221 | "r/m8", 2222 | "r/m8", 2223 | "r/m16", 2224 | "r/m16", 2225 | "r/m32", 2226 | "r/m64", 2227 | "r/m32", 2228 | "r/m64" 2229 | ] 2230 | }, 2231 | { 2232 | "Types": [ 2233 | "CL", 2234 | "CL", 2235 | "imm8", 2236 | "imm8", 2237 | "CL", 2238 | "imm8", 2239 | "CL", 2240 | "CL", 2241 | "imm8", 2242 | "imm8" 2243 | ] 2244 | } 2245 | ] 2246 | }, 2247 | { 2248 | "Mnemonic": "RDRAND", 2249 | "V64": true, 2250 | "V32": true, 2251 | "Operands": [ 2252 | { 2253 | "Types": [ 2254 | "r16", 2255 | "r32", 2256 | "r64" 2257 | ] 2258 | } 2259 | ] 2260 | }, 2261 | { 2262 | "Mnemonic": "RDSEED", 2263 | "V64": true, 2264 | "V32": true, 2265 | "Operands": [ 2266 | { 2267 | "Types": [ 2268 | "r16", 2269 | "r32", 2270 | "r64" 2271 | ] 2272 | } 2273 | ] 2274 | }, 2275 | { 2276 | "Mnemonic": "RET", 2277 | "V64": true, 2278 | "V32": true, 2279 | "Operands": [ 2280 | { 2281 | "Types": [ 2282 | "imm16", 2283 | "imm16" 2284 | ] 2285 | } 2286 | ] 2287 | }, 2288 | { 2289 | "Mnemonic": "SAL", 2290 | "V64": true, 2291 | "V32": true, 2292 | "Operands": [ 2293 | { 2294 | "Types": [ 2295 | "r/m8", 2296 | "r/m8", 2297 | "r/m8", 2298 | "r/m8", 2299 | "r/m16", 2300 | "r/m16", 2301 | "r/m32", 2302 | "r/m64", 2303 | "r/m32", 2304 | "r/m64" 2305 | ] 2306 | }, 2307 | { 2308 | "Types": [ 2309 | "CL", 2310 | "CL", 2311 | "imm8", 2312 | "imm8", 2313 | "CL", 2314 | "imm8", 2315 | "CL", 2316 | "CL", 2317 | "imm8", 2318 | "imm8" 2319 | ] 2320 | } 2321 | ] 2322 | }, 2323 | { 2324 | "Mnemonic": "SAR", 2325 | "V64": true, 2326 | "V32": true, 2327 | "Operands": [ 2328 | { 2329 | "Types": [ 2330 | "r/m8", 2331 | "r/m8", 2332 | "r/m8", 2333 | "r/m8", 2334 | "r/m16", 2335 | "r/m16", 2336 | "r/m32", 2337 | "r/m64", 2338 | "r/m32", 2339 | "r/m64" 2340 | ] 2341 | }, 2342 | { 2343 | "Types": [ 2344 | "CL", 2345 | "CL", 2346 | "imm8", 2347 | "imm8", 2348 | "CL", 2349 | "imm8", 2350 | "CL", 2351 | "CL", 2352 | "imm8", 2353 | "imm8" 2354 | ] 2355 | } 2356 | ] 2357 | }, 2358 | { 2359 | "Mnemonic": "SHL", 2360 | "V64": true, 2361 | "V32": true, 2362 | "Operands": [ 2363 | { 2364 | "Types": [ 2365 | "r/m8", 2366 | "r/m8", 2367 | "r/m8", 2368 | "r/m8", 2369 | "r/m16", 2370 | "r/m16", 2371 | "r/m32", 2372 | "r/m64", 2373 | "r/m32", 2374 | "r/m64" 2375 | ] 2376 | }, 2377 | { 2378 | "Types": [ 2379 | "CL", 2380 | "CL", 2381 | "imm8", 2382 | "imm8", 2383 | "CL", 2384 | "imm8", 2385 | "CL", 2386 | "CL", 2387 | "imm8", 2388 | "imm8" 2389 | ] 2390 | } 2391 | ] 2392 | }, 2393 | { 2394 | "Mnemonic": "SHR", 2395 | "V64": true, 2396 | "V32": true, 2397 | "Operands": [ 2398 | { 2399 | "Types": [ 2400 | "r/m8", 2401 | "r/m8", 2402 | "r/m8", 2403 | "r/m8", 2404 | "r/m16", 2405 | "r/m16", 2406 | "r/m32", 2407 | "r/m64", 2408 | "r/m32", 2409 | "r/m64" 2410 | ] 2411 | }, 2412 | { 2413 | "Types": [ 2414 | "CL", 2415 | "CL", 2416 | "imm8", 2417 | "imm8", 2418 | "CL", 2419 | "imm8", 2420 | "CL", 2421 | "CL", 2422 | "imm8", 2423 | "imm8" 2424 | ] 2425 | } 2426 | ] 2427 | }, 2428 | { 2429 | "Mnemonic": "SBB", 2430 | "V64": true, 2431 | "V32": true, 2432 | "Operands": [ 2433 | { 2434 | "Types": [ 2435 | "AL", 2436 | "AX", 2437 | "EAX", 2438 | "RAX", 2439 | "r/m8", 2440 | "r/m8", 2441 | "r/m16", 2442 | "r/m32", 2443 | "r/m64", 2444 | "r/m16", 2445 | "r/m32", 2446 | "r/m64", 2447 | "r/m8", 2448 | "r/m8", 2449 | "r/m16", 2450 | "r/m32", 2451 | "r/m64", 2452 | "r8", 2453 | "r8", 2454 | "r16", 2455 | "r32", 2456 | "r64" 2457 | ] 2458 | }, 2459 | { 2460 | "Types": [ 2461 | "imm8", 2462 | "imm16", 2463 | "imm32", 2464 | "imm32", 2465 | "imm8", 2466 | "imm8", 2467 | "imm16", 2468 | "imm32", 2469 | "imm32", 2470 | "imm8", 2471 | "imm8", 2472 | "imm8", 2473 | "r8", 2474 | "r8", 2475 | "r16", 2476 | "r32", 2477 | "r64", 2478 | "r/m8", 2479 | "r/m8", 2480 | "r/m16", 2481 | "r/m32", 2482 | "r/m64" 2483 | ] 2484 | } 2485 | ] 2486 | }, 2487 | { 2488 | "Mnemonic": "SCAS", 2489 | "V64": true, 2490 | "V32": true, 2491 | "Operands": [ 2492 | { 2493 | "Types": [ 2494 | "m8", 2495 | "m16", 2496 | "m32", 2497 | "m64" 2498 | ] 2499 | } 2500 | ] 2501 | }, 2502 | { 2503 | "Mnemonic": "SETA", 2504 | "V64": true, 2505 | "V32": true, 2506 | "Operands": [ 2507 | { 2508 | "Types": [ 2509 | "r/m8", 2510 | "r/m8" 2511 | ] 2512 | } 2513 | ] 2514 | }, 2515 | { 2516 | "Mnemonic": "SETAE", 2517 | "V64": true, 2518 | "V32": true, 2519 | "Operands": [ 2520 | { 2521 | "Types": [ 2522 | "r/m8", 2523 | "r/m8" 2524 | ] 2525 | } 2526 | ] 2527 | }, 2528 | { 2529 | "Mnemonic": "SETB", 2530 | "V64": true, 2531 | "V32": true, 2532 | "Operands": [ 2533 | { 2534 | "Types": [ 2535 | "r/m8", 2536 | "r/m8" 2537 | ] 2538 | } 2539 | ] 2540 | }, 2541 | { 2542 | "Mnemonic": "SETBE", 2543 | "V64": true, 2544 | "V32": true, 2545 | "Operands": [ 2546 | { 2547 | "Types": [ 2548 | "r/m8", 2549 | "r/m8" 2550 | ] 2551 | } 2552 | ] 2553 | }, 2554 | { 2555 | "Mnemonic": "SETC", 2556 | "V64": true, 2557 | "V32": true, 2558 | "Operands": [ 2559 | { 2560 | "Types": [ 2561 | "r/m8", 2562 | "r/m8" 2563 | ] 2564 | } 2565 | ] 2566 | }, 2567 | { 2568 | "Mnemonic": "SETE", 2569 | "V64": true, 2570 | "V32": true, 2571 | "Operands": [ 2572 | { 2573 | "Types": [ 2574 | "r/m8", 2575 | "r/m8" 2576 | ] 2577 | } 2578 | ] 2579 | }, 2580 | { 2581 | "Mnemonic": "SETG", 2582 | "V64": true, 2583 | "V32": true, 2584 | "Operands": [ 2585 | { 2586 | "Types": [ 2587 | "r/m8", 2588 | "r/m8" 2589 | ] 2590 | } 2591 | ] 2592 | }, 2593 | { 2594 | "Mnemonic": "SETGE", 2595 | "V64": true, 2596 | "V32": true, 2597 | "Operands": [ 2598 | { 2599 | "Types": [ 2600 | "r/m8", 2601 | "r/m8" 2602 | ] 2603 | } 2604 | ] 2605 | }, 2606 | { 2607 | "Mnemonic": "SETL", 2608 | "V64": true, 2609 | "V32": true, 2610 | "Operands": [ 2611 | { 2612 | "Types": [ 2613 | "r/m8", 2614 | "r/m8" 2615 | ] 2616 | } 2617 | ] 2618 | }, 2619 | { 2620 | "Mnemonic": "SETLE", 2621 | "V64": true, 2622 | "V32": true, 2623 | "Operands": [ 2624 | { 2625 | "Types": [ 2626 | "r/m8", 2627 | "r/m8" 2628 | ] 2629 | } 2630 | ] 2631 | }, 2632 | { 2633 | "Mnemonic": "SETNA", 2634 | "V64": true, 2635 | "V32": true, 2636 | "Operands": [ 2637 | { 2638 | "Types": [ 2639 | "r/m8", 2640 | "r/m8" 2641 | ] 2642 | } 2643 | ] 2644 | }, 2645 | { 2646 | "Mnemonic": "SETNAE", 2647 | "V64": true, 2648 | "V32": true, 2649 | "Operands": [ 2650 | { 2651 | "Types": [ 2652 | "r/m8", 2653 | "r/m8" 2654 | ] 2655 | } 2656 | ] 2657 | }, 2658 | { 2659 | "Mnemonic": "SETNB", 2660 | "V64": true, 2661 | "V32": true, 2662 | "Operands": [ 2663 | { 2664 | "Types": [ 2665 | "r/m8", 2666 | "r/m8" 2667 | ] 2668 | } 2669 | ] 2670 | }, 2671 | { 2672 | "Mnemonic": "SETNBE", 2673 | "V64": true, 2674 | "V32": true, 2675 | "Operands": [ 2676 | { 2677 | "Types": [ 2678 | "r/m8", 2679 | "r/m8" 2680 | ] 2681 | } 2682 | ] 2683 | }, 2684 | { 2685 | "Mnemonic": "SETNC", 2686 | "V64": true, 2687 | "V32": true, 2688 | "Operands": [ 2689 | { 2690 | "Types": [ 2691 | "r/m8", 2692 | "r/m8" 2693 | ] 2694 | } 2695 | ] 2696 | }, 2697 | { 2698 | "Mnemonic": "SETNE", 2699 | "V64": true, 2700 | "V32": true, 2701 | "Operands": [ 2702 | { 2703 | "Types": [ 2704 | "r/m8", 2705 | "r/m8" 2706 | ] 2707 | } 2708 | ] 2709 | }, 2710 | { 2711 | "Mnemonic": "SETNG", 2712 | "V64": true, 2713 | "V32": true, 2714 | "Operands": [ 2715 | { 2716 | "Types": [ 2717 | "r/m8", 2718 | "r/m8" 2719 | ] 2720 | } 2721 | ] 2722 | }, 2723 | { 2724 | "Mnemonic": "SETNGE", 2725 | "V64": true, 2726 | "V32": true, 2727 | "Operands": [ 2728 | { 2729 | "Types": [ 2730 | "r/m8", 2731 | "r/m8" 2732 | ] 2733 | } 2734 | ] 2735 | }, 2736 | { 2737 | "Mnemonic": "SETNL", 2738 | "V64": true, 2739 | "V32": true, 2740 | "Operands": [ 2741 | { 2742 | "Types": [ 2743 | "r/m8", 2744 | "r/m8" 2745 | ] 2746 | } 2747 | ] 2748 | }, 2749 | { 2750 | "Mnemonic": "SETNLE", 2751 | "V64": true, 2752 | "V32": true, 2753 | "Operands": [ 2754 | { 2755 | "Types": [ 2756 | "r/m8" 2757 | ] 2758 | } 2759 | ] 2760 | }, 2761 | { 2762 | "Mnemonic": "SGDT", 2763 | "V64": true, 2764 | "V32": true, 2765 | "Operands": [ 2766 | { 2767 | "Types": [ 2768 | "m" 2769 | ] 2770 | } 2771 | ] 2772 | }, 2773 | { 2774 | "Mnemonic": "SIDT", 2775 | "V64": true, 2776 | "V32": true, 2777 | "Operands": [ 2778 | { 2779 | "Types": [ 2780 | "m" 2781 | ] 2782 | } 2783 | ] 2784 | }, 2785 | { 2786 | "Mnemonic": "SLDT", 2787 | "V64": true, 2788 | "V32": true, 2789 | "Operands": [ 2790 | { 2791 | "Types": [ 2792 | "r/m16" 2793 | ] 2794 | } 2795 | ] 2796 | }, 2797 | { 2798 | "Mnemonic": "SMSW", 2799 | "V64": true, 2800 | "V32": true, 2801 | "Operands": [ 2802 | { 2803 | "Types": [ 2804 | "r/m16" 2805 | ] 2806 | } 2807 | ] 2808 | }, 2809 | { 2810 | "Mnemonic": "STMXCSR", 2811 | "V64": true, 2812 | "V32": true, 2813 | "Operands": [ 2814 | { 2815 | "Types": [ 2816 | "m32" 2817 | ] 2818 | } 2819 | ] 2820 | }, 2821 | { 2822 | "Mnemonic": "VSTMXCSR", 2823 | "V64": true, 2824 | "V32": true, 2825 | "Operands": [ 2826 | { 2827 | "Types": [ 2828 | "m32" 2829 | ] 2830 | } 2831 | ] 2832 | }, 2833 | { 2834 | "Mnemonic": "STOS", 2835 | "V64": true, 2836 | "V32": true, 2837 | "Operands": [ 2838 | { 2839 | "Types": [ 2840 | "m8", 2841 | "m16", 2842 | "m32", 2843 | "m64" 2844 | ] 2845 | } 2846 | ] 2847 | }, 2848 | { 2849 | "Mnemonic": "STR", 2850 | "V64": true, 2851 | "V32": true, 2852 | "Operands": [ 2853 | { 2854 | "Types": [ 2855 | "r/m16" 2856 | ] 2857 | } 2858 | ] 2859 | }, 2860 | { 2861 | "Mnemonic": "SUB", 2862 | "V64": true, 2863 | "V32": true, 2864 | "Operands": [ 2865 | { 2866 | "Types": [ 2867 | "AL", 2868 | "AX", 2869 | "EAX", 2870 | "RAX", 2871 | "r/m8", 2872 | "r/m8", 2873 | "r/m16", 2874 | "r/m32", 2875 | "r/m64", 2876 | "r/m16", 2877 | "r/m32", 2878 | "r/m64", 2879 | "r/m8", 2880 | "r/m8", 2881 | "r/m16", 2882 | "r/m32", 2883 | "r/m64", 2884 | "r8", 2885 | "r8", 2886 | "r16", 2887 | "r32", 2888 | "r64" 2889 | ] 2890 | }, 2891 | { 2892 | "Types": [ 2893 | "imm8", 2894 | "imm16", 2895 | "imm32", 2896 | "imm32", 2897 | "imm8", 2898 | "imm8", 2899 | "imm16", 2900 | "imm32", 2901 | "imm32", 2902 | "imm8", 2903 | "imm8", 2904 | "imm8", 2905 | "r8", 2906 | "r8", 2907 | "r16", 2908 | "r32", 2909 | "r64", 2910 | "r/m8", 2911 | "r/m8", 2912 | "r/m16", 2913 | "r/m32", 2914 | "r/m64" 2915 | ] 2916 | } 2917 | ] 2918 | }, 2919 | { 2920 | "Mnemonic": "TEST", 2921 | "V64": true, 2922 | "V32": true, 2923 | "Operands": [ 2924 | { 2925 | "Types": [ 2926 | "AL", 2927 | "AX", 2928 | "EAX", 2929 | "RAX", 2930 | "r/m8", 2931 | "r/m8", 2932 | "r/m16", 2933 | "r/m32", 2934 | "r/m64", 2935 | "r/m8", 2936 | "r/m8", 2937 | "r/m16", 2938 | "r/m32", 2939 | "r/m64" 2940 | ] 2941 | }, 2942 | { 2943 | "Types": [ 2944 | "imm8", 2945 | "imm16", 2946 | "imm32", 2947 | "imm32", 2948 | "imm8", 2949 | "imm8", 2950 | "imm16", 2951 | "imm32", 2952 | "imm32", 2953 | "r8", 2954 | "r8", 2955 | "r16", 2956 | "r32", 2957 | "r64" 2958 | ] 2959 | } 2960 | ] 2961 | }, 2962 | { 2963 | "Mnemonic": "TZCNT", 2964 | "V64": true, 2965 | "V32": true, 2966 | "Operands": [ 2967 | { 2968 | "Types": [ 2969 | "r16", 2970 | "r32", 2971 | "r64" 2972 | ] 2973 | }, 2974 | { 2975 | "Types": [ 2976 | "r/m16", 2977 | "r/m32", 2978 | "r/m64" 2979 | ] 2980 | } 2981 | ] 2982 | }, 2983 | { 2984 | "Mnemonic": "VERR", 2985 | "V64": true, 2986 | "V32": true, 2987 | "Operands": [ 2988 | { 2989 | "Types": [ 2990 | "r/m16" 2991 | ] 2992 | } 2993 | ] 2994 | }, 2995 | { 2996 | "Mnemonic": "VERW", 2997 | "V64": true, 2998 | "V32": true, 2999 | "Operands": [ 3000 | { 3001 | "Types": [ 3002 | "r/m16" 3003 | ] 3004 | } 3005 | ] 3006 | }, 3007 | { 3008 | "Mnemonic": "XABORT", 3009 | "V64": true, 3010 | "V32": true, 3011 | "Operands": [ 3012 | { 3013 | "Types": [ 3014 | "imm8" 3015 | ] 3016 | } 3017 | ] 3018 | }, 3019 | { 3020 | "Mnemonic": "XADD", 3021 | "V64": true, 3022 | "V32": true, 3023 | "Operands": [ 3024 | { 3025 | "Types": [ 3026 | "r/m8", 3027 | "r/m8", 3028 | "r/m16", 3029 | "r/m32", 3030 | "r/m64" 3031 | ] 3032 | }, 3033 | { 3034 | "Types": [ 3035 | "r8", 3036 | "r8", 3037 | "r16", 3038 | "r32", 3039 | "r64" 3040 | ] 3041 | } 3042 | ] 3043 | }, 3044 | { 3045 | "Mnemonic": "XLAT", 3046 | "V64": true, 3047 | "V32": true, 3048 | "Operands": [ 3049 | { 3050 | "Types": [ 3051 | "m8" 3052 | ] 3053 | } 3054 | ] 3055 | }, 3056 | { 3057 | "Mnemonic": "XOR", 3058 | "V64": true, 3059 | "V32": true, 3060 | "Operands": [ 3061 | { 3062 | "Types": [ 3063 | "AL", 3064 | "AX", 3065 | "EAX", 3066 | "RAX", 3067 | "r/m8", 3068 | "r/m8", 3069 | "r/m16", 3070 | "r/m32", 3071 | "r/m64", 3072 | "r/m16", 3073 | "r/m32", 3074 | "r/m64", 3075 | "r/m8", 3076 | "r/m8", 3077 | "r/m16", 3078 | "r/m32", 3079 | "r/m64", 3080 | "r8", 3081 | "r8", 3082 | "r16", 3083 | "r32", 3084 | "r64" 3085 | ] 3086 | }, 3087 | { 3088 | "Types": [ 3089 | "imm8", 3090 | "imm16", 3091 | "imm32", 3092 | "imm32", 3093 | "imm8", 3094 | "imm8", 3095 | "imm16", 3096 | "imm32", 3097 | "imm32", 3098 | "imm8", 3099 | "imm8", 3100 | "imm8", 3101 | "r8", 3102 | "r8", 3103 | "r16", 3104 | "r32", 3105 | "r64", 3106 | "r/m8", 3107 | "r/m8", 3108 | "r/m16", 3109 | "r/m32", 3110 | "r/m64" 3111 | ] 3112 | } 3113 | ] 3114 | } 3115 | ] 3116 | 3117 | 3118 | 3119 | ` 3120 | -------------------------------------------------------------------------------- /sgngui/obfuscate.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "math" 8 | "math/rand" 9 | "strings" 10 | ) 11 | 12 | // SGN ASM Label Definitions; 13 | //----------------------------- 14 | // {R} = RANDOM GENERAL PURPOSE REGISTER 15 | // {K} = RANDOM BYTE OF DATA 16 | // {L} = RANDOM ASM LABEL 17 | // {G} = RANDOM GARBAGE ASSEMBLY 18 | 19 | // GenerateGarbageAssembly generates random garbage instruction(s) assemblies 20 | // based on the subject encoder architecture 21 | func (encoder *Encoder) GenerateGarbageAssembly() string { 22 | 23 | switch rand.Intn(4) { 24 | case 1: 25 | randomGarbageAssembly := GetRandomSafeAssembly() 26 | register := encoder.GetRandomRegister(encoder.architecture) 27 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{R}", register) 28 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{K}", fmt.Sprintf("0x%x", GetRandomByte())) 29 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{L}", RandomLabel()) 30 | randomGarbageAssembly = strings.ReplaceAll(randomGarbageAssembly, "{G}", encoder.GenerateGarbageAssembly()) 31 | return randomGarbageAssembly + ";" 32 | case 2: 33 | return encoder.GetRandomFunctionAssembly() 34 | case 3: 35 | randRegister, _ := encoder.GetSafeRandomRegister(encoder.architecture, encoder.GetStackPointer()) // we can safely ignore the error 36 | // Save the destination register 37 | // After saving the target register to stack we can munipulate the register unlimited times 38 | unsafeGarbageAssembly := fmt.Sprintf("PUSH %s;", randRegister) 39 | if CoinFlip() { 40 | unsafeGarbageAssembly += encoder.GenerateGarbageAssembly() 41 | } 42 | unsafeGarbageAssembly += encoder.GetRandomUnsafeAssembly(randRegister) 43 | // Keep adding unsafe garbage by chance 44 | for { 45 | if CoinFlip() { 46 | unsafeGarbageAssembly += encoder.GetRandomUnsafeAssembly(randRegister) 47 | } else { 48 | break 49 | } 50 | } 51 | if CoinFlip() { 52 | unsafeGarbageAssembly += encoder.GenerateGarbageAssembly() 53 | } 54 | unsafeGarbageAssembly += fmt.Sprintf("POP %s;", randRegister) 55 | return unsafeGarbageAssembly 56 | default: 57 | return ";" 58 | } 59 | } 60 | 61 | // GenerateGarbageInstructions generates random garbage instruction(s) 62 | // with the specified architecture and returns the assembled bytes 63 | func (encoder *Encoder) GenerateGarbageInstructions() ([]byte, error) { 64 | 65 | randomGarbageAssembly := encoder.GenerateGarbageAssembly() 66 | garbage, ok := encoder.Assemble(randomGarbageAssembly) 67 | if !ok { 68 | //fmt.Println(randomGarbageAssembly) 69 | return nil, errors.New("random garbage instruction assembly failed") 70 | } 71 | 72 | if CoinFlip() { 73 | garbageJmp, err := encoder.GenerateGarbageJump() 74 | if err != nil { 75 | return nil, err 76 | } 77 | if CoinFlip() { 78 | garbage = append(garbageJmp, garbage...) 79 | } else { 80 | garbage = append(garbage, garbageJmp...) 81 | } 82 | } 83 | 84 | if len(garbage) <= encoder.ObfuscationLimit { 85 | //fmt.Println(randomGarbageAssembly) 86 | return garbage, nil 87 | } 88 | 89 | return encoder.GenerateGarbageInstructions() 90 | } 91 | 92 | // GetRandomSafeAssembly return a safe garbage instruction assembly 93 | func GetRandomSafeAssembly() string { 94 | 95 | newSafeGarbageInstructions := SafeGarbageInstructions 96 | // Add garbage confditional jumps for more possibility 97 | for _, jmp := range ConditionalJumpMnemonics { 98 | newSafeGarbageInstructions = append(newSafeGarbageInstructions, jmp+" {L};{G};{L}:") 99 | //newSafeGarbageInstructions = append(newSafeGarbageInstructions, jmp+" 2") 100 | } 101 | return newSafeGarbageInstructions[rand.Intn(len(SafeGarbageInstructions))] 102 | } 103 | 104 | // GetRandomUnsafeAssembly return a safe garbage instruction assembly 105 | func (encoder *Encoder) GetRandomUnsafeAssembly(destReg string) string { 106 | 107 | // Random register size between 8-16-32-64 108 | randRegSize := int(math.Pow(2, float64(rand.Intn(3+(encoder.architecture/64))+3))) 109 | subReg := "" 110 | for _, i := range REGS[encoder.architecture] { 111 | if (encoder.architecture == 32 && i.Extended == destReg) || (encoder.architecture == 64 && i.Full == destReg) { 112 | switch randRegSize { 113 | case 8: 114 | subReg = i.Low 115 | case 16: 116 | subReg = i.High 117 | case 32: 118 | subReg = i.Extended 119 | case 64: 120 | subReg = i.Full 121 | } 122 | } 123 | } 124 | 125 | if subReg == "" { 126 | panic("invalid register selected") 127 | } 128 | 129 | // Add first unsafe garbage. 130 | newUnsafeMnemonic := encoder.GetRandomUnsafeMnemonic(randRegSize) 131 | // Generate a random operand value based on a random oprerand type of the selected instruction 132 | operand := encoder.GetRandomOperandValue(newUnsafeMnemonic.GetRandomMatchingOperandType(randRegSize)) 133 | unsafeGarbageAssembly := fmt.Sprintf("%s %s,%s;", newUnsafeMnemonic.Mnemonic, subReg, operand) 134 | 135 | return unsafeGarbageAssembly 136 | } 137 | 138 | // GetRandomUnsafeMnemonic returns a random unsafe instruction based on the encoder architecture and operand number/type 139 | // Currently SGN only supports instructions with 2 parameter 140 | func (encoder *Encoder) GetRandomUnsafeMnemonic(opRegSize int) *INSTRUCTION { 141 | 142 | // UnsafeInstructions contains instructions that manipulate certain registers/stack/memory 143 | var UnsafeInstructions []INSTRUCTION 144 | 145 | err := json.NewDecoder(strings.NewReader(INSTRUCTIONS)).Decode(&UnsafeInstructions) 146 | if err != nil { 147 | panic(err) 148 | } 149 | 150 | new := UnsafeInstructions[rand.Intn(len(UnsafeInstructions))] 151 | if ((new.V32 && encoder.GetArchitecture() == 32) || (new.V64 && encoder.GetArchitecture() == 64)) && len(new.Operands) == 2 { 152 | if include(new.Operands[0].Types, fmt.Sprintf("r/m%d", opRegSize)) || include(new.Operands[0].Types, fmt.Sprintf("r%d", opRegSize)) { 153 | // for _, ope := range new.Operands[1].Types { 154 | // // Mnemonic operand types include one of the unsupported types abot ! 155 | // // because it may be the only combination for valid assembly 156 | // if !include(SupportedOperandTypes, ope) { 157 | // return encoder.GetRandomUnsafeMnemonic(opRegSize) 158 | // } 159 | // } 160 | return &new 161 | 162 | } 163 | } 164 | return encoder.GetRandomUnsafeMnemonic(opRegSize) 165 | 166 | } 167 | 168 | // GetRandomOperandValue generates a instruction parameter value based on given operand type 169 | // Only some operand types are considered because SGN only uses 32-64 bit registers 170 | func (encoder *Encoder) GetRandomOperandValue(operandType string) string { 171 | 172 | switch operandType { 173 | case "imm8": 174 | return fmt.Sprintf("0x%x", GetRandomByte()%127) 175 | case "imm16": 176 | return fmt.Sprintf("0x%x", rand.Intn(32767)) 177 | case "imm32": 178 | return fmt.Sprintf("0x%x", rand.Int31n((2147483647))) 179 | case "imm64": 180 | return fmt.Sprintf("0x%x", GetRandomBytes(8)) 181 | case "r8": 182 | return encoder.GetRandomRegister(8) 183 | case "r16": 184 | return encoder.GetRandomRegister(16) 185 | case "r32": 186 | return encoder.GetRandomRegister(32) 187 | case "r64": 188 | return encoder.GetRandomRegister(64) 189 | case "r/m8": 190 | if CoinFlip() { 191 | return encoder.GetRandomOperandValue("m8") 192 | } 193 | return encoder.GetRandomRegister(8) 194 | case "r/m16": 195 | if CoinFlip() { 196 | return encoder.GetRandomOperandValue("m16") 197 | } 198 | return encoder.GetRandomRegister(16) 199 | case "r/m32": 200 | if CoinFlip() { 201 | return encoder.GetRandomOperandValue("m32") 202 | } 203 | return encoder.GetRandomRegister(32) 204 | case "r/m64": 205 | if CoinFlip() { 206 | return encoder.GetRandomOperandValue("m64") 207 | } 208 | return encoder.GetRandomRegister(64) 209 | case "m": 210 | return encoder.GetRandomStackAddress() 211 | case "m8": 212 | return fmt.Sprintf("BYTE PTR %s", encoder.GetRandomStackAddress()) 213 | case "m16": 214 | return fmt.Sprintf("WORD PTR %s", encoder.GetRandomStackAddress()) 215 | case "m32": 216 | return fmt.Sprintf("DWORD PTR %s", encoder.GetRandomStackAddress()) 217 | case "m64": 218 | return fmt.Sprintf("QWORD PTR %s", encoder.GetRandomStackAddress()) 219 | case "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "AH", "AL", "CH", "CL", "DH", "DL", "BH", "BL", "SPL", "BPL", "SIL", "DIL": 220 | return operandType 221 | default: 222 | panic("unsupported instruction operand type: " + operandType) 223 | } 224 | } 225 | 226 | // GetRandomMatchingOperandType randomly selects a operand type for subject instruction 227 | func (ins *INSTRUCTION) GetRandomMatchingOperandType(srcRegSize int) string { 228 | if len(ins.Operands) != 2 { 229 | panic(errors.New("instruction operand index out of range")) 230 | } 231 | if len(ins.Operands[0].Types) == 0 || len(ins.Operands[1].Types) == 0 { 232 | panic(errors.New("instruction operand has no type")) 233 | } 234 | if len(ins.Operands[0].Types) != len(ins.Operands[1].Types) { 235 | panic(errors.New("unsupported instruction operand types")) 236 | } 237 | 238 | index := []int{} 239 | 240 | for i, j := range ins.Operands[0].Types { 241 | if j == fmt.Sprintf("r/m%d", srcRegSize) || j == fmt.Sprintf("r%d", srcRegSize) { 242 | index = append(index, i) 243 | } 244 | } 245 | 246 | return ins.Operands[1].Types[index[rand.Intn(len(index))]] 247 | } 248 | 249 | func include(arr []string, str string) bool { 250 | for _, i := range arr { 251 | if i == str { 252 | return true 253 | } 254 | } 255 | return false 256 | } 257 | 258 | // CalculateAverageGarbageInstructionSize calculate the avarage size of generated random garbage instructions 259 | func (encoder *Encoder) CalculateAverageGarbageInstructionSize() (float64, error) { 260 | 261 | var average float64 = 0 262 | for i := 0; i < 100; i++ { 263 | randomGarbageAssembly := encoder.GenerateGarbageAssembly() 264 | garbage, ok := encoder.Assemble(randomGarbageAssembly) 265 | if !ok { 266 | return 0, errors.New("random garbage instruction assembly failed") 267 | } 268 | average += float64(len(garbage)) 269 | } 270 | average = average / 100 271 | return average, nil 272 | } 273 | 274 | func (encoder *Encoder) debugAssembly(str string) string { 275 | for _, i := range strings.Split(str, ";") { 276 | _, ok := encoder.Assemble(i) 277 | if !ok { 278 | return i 279 | } 280 | } 281 | return "" 282 | } 283 | 284 | // GetRandomFunctionAssembly generates a function frame assembly with garbage instructions inside 285 | func (encoder *Encoder) GetRandomFunctionAssembly() string { 286 | 287 | bp := "" 288 | sp := "" 289 | 290 | switch encoder.architecture { 291 | case 32: 292 | bp = "EBP" 293 | sp = "ESP" 294 | case 64: 295 | bp = "RBP" 296 | sp = "RSP" 297 | default: 298 | panic(errors.New("invalid architecture selected")) 299 | } 300 | 301 | prologue := fmt.Sprintf("PUSH %s;", bp) 302 | prologue += fmt.Sprintf("MOV %s,%s;", bp, sp) 303 | prologue += fmt.Sprintf("SUB %s,0x%x;", sp, GetRandomByte()) 304 | 305 | // Fill the function body with garbage instructions 306 | garbage := encoder.GenerateGarbageAssembly() 307 | 308 | epilogue := fmt.Sprintf("MOV %s,%s;", sp, bp) 309 | epilogue += fmt.Sprintf("POP %s;", bp) 310 | 311 | return prologue + garbage + epilogue 312 | } 313 | 314 | // GenerateGarbageJump generates a JMP instruction over random bytes 315 | func (encoder Encoder) GenerateGarbageJump() ([]byte, error) { 316 | GetRandomBytes := GetRandomBytes(encoder.ObfuscationLimit / 10) 317 | garbageJmp, err := encoder.AddJmpOver(GetRandomBytes) 318 | if err != nil { 319 | return nil, err 320 | } 321 | return garbageJmp, nil 322 | } 323 | 324 | // RandomLabel generates a random assembly label 325 | func RandomLabel() string { 326 | numbers := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 327 | b := make([]rune, 5) 328 | for i := range b { 329 | b[i] = numbers[rand.Intn(len(numbers))] 330 | } 331 | return string(b) 332 | } 333 | -------------------------------------------------------------------------------- /sgngui/sgn.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "math/rand" 8 | 9 | "github.com/EgeBalci/keystone-go" 10 | ) 11 | 12 | // REG structure for registers 13 | type REG struct { 14 | Full string 15 | Extended string 16 | High string 17 | Low string 18 | Arch int 19 | } 20 | 21 | // INSTRUCTION contains instruction information 22 | // Intel syntax mandates "When two operands are present in an arithmetic or logical instruction, the right operand is the source and the left 23 | // operand is the destination." for our case first operand will allways will be considered destination operand 24 | type INSTRUCTION struct { 25 | Mnemonic string `json:"Mnemonic"` 26 | V64 bool `json:"V64"` 27 | V32 bool `json:"V32"` 28 | Operands []struct { 29 | Types []string `json:"Types"` 30 | } `json:"Operands"` 31 | } 32 | 33 | // Initialize the register values 34 | func init() { 35 | 36 | // Setup x86 GP the register values 37 | REGS = make(map[int][]REG) 38 | REGS[32] = append(REGS[32], REG{Extended: "EAX", High: "AX", Low: "AL", Arch: 32}) 39 | REGS[32] = append(REGS[32], REG{Extended: "EBX", High: "BX", Low: "BL", Arch: 32}) 40 | REGS[32] = append(REGS[32], REG{Extended: "ECX", High: "CX", Low: "CL", Arch: 32}) 41 | REGS[32] = append(REGS[32], REG{Extended: "EDX", High: "DX", Low: "DL", Arch: 32}) 42 | // since there is no way to access 1 byte use above instead 43 | REGS[32] = append(REGS[32], REG{Extended: "ESI", High: "SI", Low: "AL", Arch: 32}) 44 | REGS[32] = append(REGS[32], REG{Extended: "EDI", High: "DI", Low: "BL", Arch: 32}) 45 | // Setup x64 GP the register values 46 | REGS[64] = append(REGS[64], REG{Full: "RAX", Extended: "EAX", High: "AX", Low: "AL", Arch: 64}) 47 | REGS[64] = append(REGS[64], REG{Full: "RBX", Extended: "EBX", High: "BX", Low: "BL", Arch: 64}) 48 | REGS[64] = append(REGS[64], REG{Full: "RCX", Extended: "ECX", High: "CX", Low: "CL", Arch: 64}) 49 | REGS[64] = append(REGS[64], REG{Full: "RDX", Extended: "EDX", High: "DX", Low: "DL", Arch: 64}) 50 | REGS[64] = append(REGS[64], REG{Full: "RSI", Extended: "ESI", High: "SI", Low: "SIL", Arch: 64}) 51 | REGS[64] = append(REGS[64], REG{Full: "RDI", Extended: "EDI", High: "DX", Low: "DIL", Arch: 64}) 52 | REGS[64] = append(REGS[64], REG{Full: "R8", Extended: "R8D", High: "R8W", Low: "R8B", Arch: 64}) 53 | REGS[64] = append(REGS[64], REG{Full: "R9", Extended: "R9D", High: "R9W", Low: "R9B", Arch: 64}) 54 | REGS[64] = append(REGS[64], REG{Full: "R10", Extended: "R10D", High: "R10W", Low: "R10B", Arch: 64}) 55 | REGS[64] = append(REGS[64], REG{Full: "R11", Extended: "R11D", High: "R11W", Low: "R11B", Arch: 64}) 56 | REGS[64] = append(REGS[64], REG{Full: "R12", Extended: "R12D", High: "R12W", Low: "R12B", Arch: 64}) 57 | REGS[64] = append(REGS[64], REG{Full: "R13", Extended: "R13D", High: "R13W", Low: "R13B", Arch: 64}) 58 | REGS[64] = append(REGS[64], REG{Full: "R14", Extended: "R14D", High: "R14W", Low: "R14B", Arch: 64}) 59 | REGS[64] = append(REGS[64], REG{Full: "R15", Extended: "R15D", High: "R15W", Low: "R15B", Arch: 64}) 60 | 61 | // Set the decoder stubs 62 | STUB = make(map[int]string) 63 | STUB[32] = X86_DECODER_STUB 64 | STUB[64] = X64_DECODER_STUB 65 | 66 | // Set safe register prefix/suffix 67 | SafeRegisterPrefix = make(map[int]([]byte)) 68 | SafeRegisterSuffix = make(map[int]([]byte)) 69 | SafeRegisterPrefix[32] = X86_REG_SAVE_PREFIX 70 | SafeRegisterPrefix[64] = X64_REG_SAVE_PREFIX 71 | 72 | SafeRegisterSuffix[32] = X86_REG_SAVE_SUFFIX 73 | SafeRegisterSuffix[64] = X64_REG_SAVE_SUFFIX 74 | } 75 | 76 | // SafeRegisterPrefix contains the instructions for saving registers to stack 77 | var SafeRegisterPrefix map[int]([]byte) 78 | 79 | // SafeRegisterSuffix contains the instructions for restoring registers from stack 80 | var SafeRegisterSuffix map[int]([]byte) 81 | 82 | // X86_REG_SAVE_PREFIX instructions for saving registers to stack 83 | var X86_REG_SAVE_PREFIX = []byte{0x60, 0x9c} // PUSHAD, PUSHFD 84 | // X86_REG_SAVE_SUFFIX instructions for saving registers to stack 85 | var X86_REG_SAVE_SUFFIX = []byte{0x9d, 0x61} // POPFD, POPAD 86 | 87 | // X64_REG_SAVE_PREFIX instructions for saving registers to stack 88 | var X64_REG_SAVE_PREFIX = []byte{ 89 | 0x50, 0x53, 0x51, 0x52, // PUSH RAX,RBX,RCX,RDX 90 | 0x56, 0x57, 0x55, 0x54, // PUSH RSI,RDI,RBP,RSP 91 | 0x41, 0x50, 0x41, 0x51, // PUSH R8,R9 92 | 0x41, 0x52, 0x41, 0x53, // PUSH R10,R11 93 | 0x41, 0x54, 0x41, 0x55, // PUSH R12,R13 94 | 0x41, 0x56, 0x41, 0x57, // PUSH R14,R15 95 | } 96 | 97 | // X64_REG_SAVE_SUFFIX instructions for saving registers to stack 98 | var X64_REG_SAVE_SUFFIX = []byte{ 99 | 0x41, 0x5f, 0x41, 0x5e, // POP R15,R14 100 | 0x41, 0x5d, 0x41, 0x5c, // POP R13,R12 101 | 0x41, 0x5b, 0x41, 0x5a, // POP R11,R10 102 | 0x41, 0x59, 0x41, 0x58, // POP R9,R8 103 | 0x5c, 0x5d, 0x5f, 0x5e, // POP RSP,RBP,RDI,RSI 104 | 0x5a, 0x59, 0x5b, 0x58, // POP RDX,RCX,RBX,RAX 105 | } 106 | 107 | // REGS contains 32/64 bit registers 108 | var REGS map[int][]REG 109 | 110 | // GetRandomRegister returns a random register name based on given size and architecture 111 | func (encoder Encoder) GetRandomRegister(size int) string { 112 | switch size { 113 | case 8: 114 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Low 115 | case 16: 116 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].High 117 | case 32: 118 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Extended 119 | case 64: 120 | return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Full 121 | default: 122 | panic("invalid register size") 123 | } 124 | 125 | } 126 | 127 | // GetRandomStackAddress returns a stack address assembly referance based on the encoder architecture 128 | // Ex: [esp+10] (address range is 1 byte) 129 | func (encoder Encoder) GetRandomStackAddress() string { 130 | if CoinFlip() { 131 | return fmt.Sprintf("[%s+0x%x]", encoder.GetStackPointer(), GetRandomByte()) 132 | } 133 | return fmt.Sprintf("[%s-0x%x]", encoder.GetStackPointer(), GetRandomByte()) 134 | } 135 | 136 | // GetStackPointer returns the stack pointer register string based on the encoder architecture 137 | func (encoder Encoder) GetStackPointer() string { 138 | switch encoder.architecture { 139 | case 32: 140 | return "ESP" 141 | case 64: 142 | return "RSP" 143 | default: 144 | panic("invalid architecture") 145 | } 146 | 147 | } 148 | 149 | // GetBasePointer returns the base pointer register string based on the encoder architecture 150 | func (encoder Encoder) GetBasePointer() string { 151 | switch encoder.architecture { 152 | case 32: 153 | return "EBP" 154 | case 64: 155 | return "RBP" 156 | default: 157 | panic("invalid architecture") 158 | } 159 | 160 | } 161 | 162 | // GetSafeRandomRegister returns a random register among all (registers-excluded parameters) based on given size 163 | func (encoder Encoder) GetSafeRandomRegister(size int, excludes ...string) (string, error) { 164 | regs := make([]REG, len(REGS[encoder.architecture])) 165 | perm := rand.Perm(len(REGS[encoder.architecture])) 166 | for i, v := range perm { 167 | regs[v] = REGS[encoder.architecture][i] 168 | } 169 | 170 | for _, r := range regs { 171 | excluded := false 172 | for _, x := range excludes { 173 | if r.Extended == x || r.Full == x || r.High == x || r.Low == x { 174 | excluded = true 175 | } 176 | } 177 | 178 | if excluded { 179 | continue 180 | } 181 | 182 | switch size { 183 | case 8: 184 | return r.Low, nil 185 | case 16: 186 | return r.High, nil 187 | case 32: 188 | return r.Extended, nil 189 | case 64: 190 | return r.Full, nil 191 | default: 192 | return "", errors.New("invalid register size") 193 | } 194 | } 195 | return "", errors.New("safe register selection failed!") 196 | } 197 | 198 | // Assemble assembes the given instructions 199 | // and return a byte array with a boolean value indicating wether the operation is successful or not 200 | func (encoder Encoder) Assemble(asm string) ([]byte, bool) { 201 | var mode keystone.Mode 202 | switch encoder.architecture { 203 | case 32: 204 | mode = keystone.MODE_32 205 | case 64: 206 | mode = keystone.MODE_64 207 | default: 208 | return nil, false 209 | } 210 | 211 | ks, err := keystone.New(keystone.ARCH_X86, mode) 212 | if err != nil { 213 | return nil, false 214 | } 215 | defer ks.Close() 216 | 217 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 218 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.KS_OPT_SYNTAX_NASM) 219 | err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 220 | if err != nil { 221 | return nil, false 222 | } 223 | //log.Println(asm) 224 | bin, _, ok := ks.Assemble(asm, 0) 225 | return bin, ok 226 | } 227 | 228 | // GetAssemblySize assembes the given instructions and returns the total instruction size 229 | // if assembly fails return value is -1 230 | func (encoder Encoder) GetAssemblySize(asm string) int { 231 | var mode keystone.Mode 232 | switch encoder.architecture { 233 | case 32: 234 | mode = keystone.MODE_32 235 | case 64: 236 | mode = keystone.MODE_64 237 | default: 238 | return -1 239 | } 240 | 241 | ks, err := keystone.New(keystone.ARCH_X86, mode) 242 | if err != nil { 243 | return -1 244 | } 245 | defer ks.Close() 246 | 247 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 248 | //err = ks.Option(keystone.OPT_SYNTAX, keystone.KS_OPT_SYNTAX_NASM) 249 | err = ks.Option(keystone.OPT_SYNTAX, keystone.OPT_SYNTAX_INTEL) 250 | if err != nil { 251 | return -1 252 | } 253 | //log.Println(asm) 254 | bin, _, ok := ks.Assemble(asm, 0) 255 | 256 | if !ok { 257 | return -1 258 | } 259 | return len(bin) 260 | } 261 | 262 | // GenerateIPToStack function generates instructions series that pushes the instruction pointer to stack 263 | func (encoder Encoder) GenerateIPToStack() []byte { 264 | 265 | callBin, ok := encoder.Assemble("call 5") 266 | if !ok { 267 | panic("call 5 assembly failed") 268 | } 269 | return callBin 270 | } 271 | 272 | // AddCallOver function adds a call instruction over the end of the given payload 273 | // address of the payload will be pushed to the stack and execution will continiou after the end of payload 274 | func (encoder Encoder) AddCallOver(payload []byte) ([]byte, error) { 275 | 276 | // Perform a shport call over the payload 277 | call := fmt.Sprintf("call 0x%x", len(payload)+5) 278 | callBin, ok := encoder.Assemble(call) 279 | if !ok { 280 | return nil, errors.New("call-over assembly failed") 281 | } 282 | payload = append(callBin, payload...) 283 | 284 | return payload, nil 285 | } 286 | 287 | // AddJmpOver function adds a jmp instruction over the end of the given payload 288 | // execution will continiou after the end of payload 289 | func (encoder Encoder) AddJmpOver(payload []byte) ([]byte, error) { 290 | // JMP 2 -> Jumps to next instruction 291 | // Perform a short call over the payload 292 | jmp := fmt.Sprintf("jmp 0x%x", len(payload)+2) 293 | jmpBin, ok := encoder.Assemble(jmp) 294 | if !ok { 295 | return nil, errors.New("jmp-over assembly failed") 296 | } 297 | payload = append(jmpBin, payload...) 298 | 299 | return payload, nil 300 | } 301 | 302 | // AddCondJmpOver function adds a jmp instruction over the end of the given payload 303 | // execution will continiou after the end of payload 304 | func (encoder Encoder) AddCondJmpOver(payload []byte) ([]byte, error) { 305 | // JZ 2 -> Jumps to next instruction 306 | // Perform a short call over the payload 307 | 308 | randomConditional := ConditionalJumpMnemonics[rand.Intn(len(ConditionalJumpMnemonics))] 309 | 310 | jmp := fmt.Sprintf("%s 0x%x", randomConditional, len(payload)+2) 311 | jmpBin, ok := encoder.Assemble(jmp) 312 | if !ok { 313 | return nil, errors.New("conditional call-over assembly failed") 314 | } 315 | payload = append(jmpBin, payload...) 316 | 317 | return payload, nil 318 | } 319 | 320 | // EncodeFunction handles encoding with current stored options 321 | func EncodeFunction(opts *Options) error { 322 | encoder, err := NewEncoder(opts.Arch) 323 | if err != nil { 324 | return fmt.Errorf("error creating encoder: %w", err) 325 | } 326 | 327 | encoder.ObfuscationLimit = opts.ObsLevel 328 | encoder.PlainDecoder = opts.PlainDecoder 329 | encoder.EncodingCount = opts.EncCount 330 | encoder.SaveRegisters = opts.Safe 331 | 332 | inputData, err := ioutil.ReadFile(opts.Input) 333 | if err != nil { 334 | return fmt.Errorf("error reading input file: %w", err) 335 | } 336 | 337 | encodedPayload, err := encoder.Encode(inputData) 338 | if err != nil { 339 | return fmt.Errorf("error encoding payload: %w", err) 340 | } 341 | 342 | err = ioutil.WriteFile(opts.Output, encodedPayload, 0644) 343 | if err != nil { 344 | return fmt.Errorf("error writing output file: %w", err) 345 | } 346 | 347 | return nil 348 | } 349 | -------------------------------------------------------------------------------- /sgngui/sgngui.go: -------------------------------------------------------------------------------- 1 | package sgngui 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "strconv" 7 | 8 | "fyne.io/fyne/v2" 9 | "fyne.io/fyne/v2/canvas" 10 | "fyne.io/fyne/v2/container" 11 | "fyne.io/fyne/v2/dialog" 12 | "fyne.io/fyne/v2/layout" 13 | "fyne.io/fyne/v2/widget" 14 | ) 15 | 16 | var storedOptions = &Options{ 17 | Arch: 64, 18 | EncCount: 1, 19 | ObsLevel: 50, 20 | } 21 | 22 | func ShowGUI(mainWindow fyne.Window, statusLabel *canvas.Text, onSave func(*Options)) { 23 | opts := storedOptions 24 | 25 | // Create a new window for the form 26 | formWindow := fyne.CurrentApp().NewWindow("Configuration Options") 27 | 28 | inputEntry := widget.NewEntry() 29 | inputEntry.SetPlaceHolder("Raw or EXE File Path") 30 | inputEntry.SetText(opts.Input) 31 | inputFileButton := widget.NewButton("Open File", func() { 32 | dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) { 33 | if err == nil && reader != nil { 34 | inputEntry.SetText(reader.URI().Path()) 35 | } 36 | }, formWindow).Show() 37 | }) 38 | 39 | outputEntry := widget.NewEntry() 40 | outputEntry.SetPlaceHolder("Output Filename") 41 | outputEntry.SetText(opts.Output) 42 | 43 | archSelect := widget.NewSelect([]string{"32-bit", "64-bit"}, func(value string) { 44 | if value == "32-bit" { 45 | opts.Arch = 32 46 | } else { 47 | opts.Arch = 64 48 | } 49 | }) 50 | if opts.Arch == 32 { 51 | archSelect.SetSelected("32-bit") 52 | } else { 53 | archSelect.SetSelected("64-bit") 54 | } 55 | 56 | encCountSlider := widget.NewSlider(1, 50) 57 | encCountSlider.Step = 1 58 | encCountSlider.Value = 1 59 | encCountSlider.SetValue(float64(opts.EncCount)) 60 | encCountLabel := widget.NewLabel(fmt.Sprintf("Encryption Count: %d", int(encCountSlider.Value))) 61 | encCountSlider.OnChanged = func(value float64) { 62 | encCountLabel.SetText(fmt.Sprintf("Encryption Count: %d", int(value))) 63 | opts.EncCount = int(value) 64 | } 65 | 66 | obsLevelEntry := widget.NewEntry() 67 | obsLevelEntry.SetPlaceHolder("Default:50") 68 | obsLevelEntry.SetText(strconv.Itoa(opts.ObsLevel)) 69 | plainDecoderCheck := widget.NewCheck("Do not encode the decoder stub", nil) 70 | plainDecoderCheck.SetChecked(opts.PlainDecoder) 71 | asciiPayloadCheck := widget.NewCheck("Generates a full ASCII printable payload, may take very long time to bruteforce", nil) 72 | asciiPayloadCheck.SetChecked(opts.AsciiPayload) 73 | safeCheck := widget.NewCheck("Preserve all register values (a.k.a. no clobber)", nil) 74 | safeCheck.SetChecked(opts.Safe) 75 | badCharsEntry := widget.NewEntry() 76 | badCharsEntry.SetPlaceHolder("Specified bad characters given in hex format YOU DON'T WANT TO USE") 77 | badCharsEntry.SetText(opts.BadChars) 78 | verboseCheck := widget.NewCheck("BlueTeam Blinder", nil) 79 | verboseCheck.SetChecked(opts.Verbose) 80 | 81 | form := &widget.Form{ 82 | Items: []*widget.FormItem{ 83 | {Text: "Input", Widget: container.NewBorder(nil, nil, nil, inputFileButton, inputEntry)}, 84 | {Text: "Output", Widget: outputEntry}, 85 | {Text: "Architecture", Widget: archSelect}, 86 | {Text: "Encode Count", Widget: encCountSlider}, 87 | {Text: "", Widget: encCountLabel}, 88 | {Text: "Obfuscation Level", Widget: obsLevelEntry}, 89 | {Text: "Plain Decoder", Widget: plainDecoderCheck}, 90 | {Text: "ASCII Payload", Widget: asciiPayloadCheck}, 91 | {Text: "Safe Mode", Widget: safeCheck}, 92 | {Text: "Bad Characters", Widget: badCharsEntry}, 93 | {Text: "Verbose", Widget: verboseCheck}, 94 | }, 95 | OnSubmit: func() { 96 | opts.Input = inputEntry.Text 97 | opts.Output = outputEntry.Text 98 | opts.ObsLevel, _ = strconv.Atoi(obsLevelEntry.Text) 99 | opts.PlainDecoder = plainDecoderCheck.Checked 100 | opts.AsciiPayload = asciiPayloadCheck.Checked 101 | opts.Safe = safeCheck.Checked 102 | opts.BadChars = badCharsEntry.Text 103 | opts.Verbose = verboseCheck.Checked 104 | 105 | err := ValidateOptions(opts, formWindow) 106 | if err != nil { 107 | return 108 | } 109 | 110 | // Update the global stored options 111 | storedOptions = opts 112 | 113 | // Call your function with opts 114 | configureOptions(opts) 115 | statusLabel.Text = "Check" 116 | statusLabel.Color = color.RGBA{0, 255, 0, 255} 117 | statusLabel.Refresh() 118 | formWindow.Close() 119 | onSave(opts) 120 | }, 121 | } 122 | 123 | formWindow.SetContent(container.New(layout.NewVBoxLayout(), form)) 124 | formWindow.Resize(fyne.NewSize(400, 600)) 125 | formWindow.SetFixedSize(true) 126 | formWindow.Show() 127 | } 128 | 129 | func configureOptions(opts *Options) { 130 | // Your existing logic here, adapted for GUI 131 | if opts.Verbose { 132 | // Set verbose mode in your utility 133 | } 134 | 135 | // Handle other options as needed 136 | // For example: 137 | println("Input: ", opts.Input) 138 | println("Output: ", opts.Output) 139 | println("Architecture: ", opts.Arch) 140 | println("Encode Count: ", opts.EncCount) 141 | println("Obfuscation Level: ", opts.ObsLevel) 142 | println("Plain Decoder: ", opts.PlainDecoder) 143 | println("ASCII Payload: ", opts.AsciiPayload) 144 | println("Safe Mode: ", opts.Safe) 145 | println("Bad Characters: ", opts.BadChars) 146 | println("Verbose: ", opts.Verbose) 147 | } 148 | --------------------------------------------------------------------------------