mirror of
https://github.com/EgeBalci/sgn
synced 2026-06-08 10:56:31 +00:00
Corrects payload selection logic and several register definitions and selection mechanisms.
This commit also optimizes bad-byte checking and improves code style. - fix(main): Correct payload selection logic for ASCII and bad byte constraints - refactor(main): Improve readability of payload selection conditions - fix(sgn): Correct register definitions for ESI, EDI, and RDI - fix(sgn): Remove PUSH/POP of RSP from x64 register save/restore opcodes - fix(sgn): Rework random register selection to prevent returning invalid registers - perf(utils): Optimize `ContainsBytes` by using `bytes.IndexByte` - style(utils): Export `ContainsBytes` function - chore(main): Remove unused `bytes` import
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@@ -82,7 +81,10 @@ func main() {
|
||||
utils.PrintFatal("%s", err)
|
||||
}
|
||||
|
||||
if (opts.AsciiPayload && utils.IsASCIIPrintable(string(p))) || (len(badBytes) > 0 && !bytes.Contains(p, badBytes)) {
|
||||
asciiOk := !opts.AsciiPayload || utils.IsASCIIPrintable(string(p))
|
||||
badBytesOk := len(badBytes) == 0 || !utils.ContainsBytes(p, badBytes)
|
||||
|
||||
if asciiOk && badBytesOk {
|
||||
payload = p
|
||||
break
|
||||
}
|
||||
|
||||
+59
-30
@@ -39,15 +39,15 @@ func init() {
|
||||
REGS[32] = append(REGS[32], REG{Extended: "ECX", High: "CX", Low: "CL", Arch: 32})
|
||||
REGS[32] = append(REGS[32], REG{Extended: "EDX", High: "DX", Low: "DL", Arch: 32})
|
||||
// since there is no way to access 1 byte use above instead
|
||||
REGS[32] = append(REGS[32], REG{Extended: "ESI", High: "SI", Low: "AL", Arch: 32})
|
||||
REGS[32] = append(REGS[32], REG{Extended: "EDI", High: "DI", Low: "BL", Arch: 32})
|
||||
REGS[32] = append(REGS[32], REG{Extended: "ESI", High: "SI", Low: "", Arch: 32})
|
||||
REGS[32] = append(REGS[32], REG{Extended: "EDI", High: "DI", Low: "", Arch: 32})
|
||||
// Setup x64 GP the register values
|
||||
REGS[64] = append(REGS[64], REG{Full: "RAX", Extended: "EAX", High: "AX", Low: "AL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RBX", Extended: "EBX", High: "BX", Low: "BL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RCX", Extended: "ECX", High: "CX", Low: "CL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RDX", Extended: "EDX", High: "DX", Low: "DL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RSI", Extended: "ESI", High: "SI", Low: "SIL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RDI", Extended: "EDI", High: "DX", Low: "DIL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "RDI", Extended: "EDI", High: "DI", Low: "DIL", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "R8", Extended: "R8D", High: "R8W", Low: "R8B", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "R9", Extended: "R9D", High: "R9W", Low: "R9B", Arch: 64})
|
||||
REGS[64] = append(REGS[64], REG{Full: "R10", Extended: "R10D", High: "R10W", Low: "R10B", Arch: 64})
|
||||
@@ -86,7 +86,7 @@ var X86_REG_SAVE_SUFFIX = []byte{0x9d, 0x61} // POPFD, POPAD
|
||||
// X64_REG_SAVE_PREFIX instructions for saving registers to stack
|
||||
var X64_REG_SAVE_PREFIX = []byte{
|
||||
0x50, 0x53, 0x51, 0x52, // PUSH RAX,RBX,RCX,RDX
|
||||
0x56, 0x57, 0x55, 0x54, // PUSH RSI,RDI,RBP,RSP
|
||||
0x56, 0x57, 0x55, // PUSH RSI,RDI,RBP
|
||||
0x41, 0x50, 0x41, 0x51, // PUSH R8,R9
|
||||
0x41, 0x52, 0x41, 0x53, // PUSH R10,R11
|
||||
0x41, 0x54, 0x41, 0x55, // PUSH R12,R13
|
||||
@@ -99,7 +99,7 @@ var X64_REG_SAVE_SUFFIX = []byte{
|
||||
0x41, 0x5d, 0x41, 0x5c, // POP R13,R12
|
||||
0x41, 0x5b, 0x41, 0x5a, // POP R11,R10
|
||||
0x41, 0x59, 0x41, 0x58, // POP R9,R8
|
||||
0x5c, 0x5d, 0x5f, 0x5e, // POP RSP,RBP,RDI,RSI
|
||||
0x5d, 0x5f, 0x5e, // POP RBP,RDI,RSI
|
||||
0x5a, 0x59, 0x5b, 0x58, // POP RDX,RCX,RBX,RAX
|
||||
}
|
||||
|
||||
@@ -108,19 +108,38 @@ var REGS map[int][]REG
|
||||
|
||||
// GetRandomRegister returns a random register name based on given size and architecture
|
||||
func (encoder Encoder) GetRandomRegister(size int) string {
|
||||
switch size {
|
||||
case 8:
|
||||
return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Low
|
||||
case 16:
|
||||
return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].High
|
||||
case 32:
|
||||
return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Extended
|
||||
case 64:
|
||||
return REGS[encoder.architecture][rand.Intn(len(REGS[encoder.architecture]))].Full
|
||||
default:
|
||||
panic("invalid register size")
|
||||
var regs [32]string
|
||||
var count int
|
||||
for _, r := range REGS[encoder.architecture] {
|
||||
switch size {
|
||||
case 8:
|
||||
if r.Low != "" {
|
||||
regs[count] = r.Low
|
||||
count++
|
||||
}
|
||||
case 16:
|
||||
if r.High != "" {
|
||||
regs[count] = r.High
|
||||
count++
|
||||
}
|
||||
case 32:
|
||||
if r.Extended != "" {
|
||||
regs[count] = r.Extended
|
||||
count++
|
||||
}
|
||||
case 64:
|
||||
if r.Full != "" {
|
||||
regs[count] = r.Full
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
panic("invalid register size or no registers available")
|
||||
}
|
||||
|
||||
return regs[rand.Intn(count)]
|
||||
}
|
||||
|
||||
// GetRandomStackAddress returns a stack address assembly referance based on the encoder architecture
|
||||
@@ -160,8 +179,25 @@ func (encoder Encoder) GetBasePointer() string {
|
||||
|
||||
// GetSafeRandomRegister returns a random register among all (registers-excluded parameters) based on given size
|
||||
func (encoder Encoder) GetSafeRandomRegister(size int, excludes ...string) (string, error) {
|
||||
regs := []REG{}
|
||||
var regs [32]string
|
||||
var count int
|
||||
for _, r := range REGS[encoder.architecture] {
|
||||
var regStr string
|
||||
switch size {
|
||||
case 8:
|
||||
regStr = r.Low
|
||||
case 16:
|
||||
regStr = r.High
|
||||
case 32:
|
||||
regStr = r.Extended
|
||||
case 64:
|
||||
regStr = r.Full
|
||||
}
|
||||
|
||||
if regStr == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
safe := true
|
||||
for _, x := range excludes {
|
||||
if r.Extended == x || r.Full == x || r.High == x || r.Low == x {
|
||||
@@ -170,23 +206,16 @@ func (encoder Encoder) GetSafeRandomRegister(size int, excludes ...string) (stri
|
||||
}
|
||||
}
|
||||
if safe {
|
||||
regs = append(regs, r)
|
||||
regs[count] = regStr
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
r := regs[rand.Intn(len(regs))]
|
||||
switch size {
|
||||
case 8:
|
||||
return r.Low, nil
|
||||
case 16:
|
||||
return r.High, nil
|
||||
case 32:
|
||||
return r.Extended, nil
|
||||
case 64:
|
||||
return r.Full, nil
|
||||
default:
|
||||
return "", errors.New("invalid register size")
|
||||
if count == 0 {
|
||||
return "", errors.New("no safe registers available")
|
||||
}
|
||||
|
||||
return regs[rand.Intn(count)], nil
|
||||
}
|
||||
|
||||
// Assemble assembes the given instructions
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ import (
|
||||
var Verbose = false
|
||||
|
||||
// checks if a byte array contains any element of another byte array
|
||||
func containsBytes(data, any []byte) bool {
|
||||
func ContainsBytes(data, any []byte) bool {
|
||||
for _, b := range any {
|
||||
if bytes.Contains(data, []byte{b}) {
|
||||
if bytes.IndexByte(data, b) != -1 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user