Skip to content

Commit

Permalink
Add support for decoding ENDBR32/64 instructions (#1416)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelroquetto authored Nov 28, 2024
1 parent 9efc255 commit a380cd0
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
21 changes: 21 additions & 0 deletions pkg/internal/goexec/instructions_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,31 @@ import (
"golang.org/x/arch/x86/x86asm"
)

const endbrSize = 4

func isENDBRXX(data []uint8) bool {
if len(data) < endbrSize {
return false
}

return data[0] == 0xF3 &&
data[1] == 0x0F &&
data[2] == 0x1E &&
(data[3] == 0xFA || data[3] == 0xFB)
}

func findReturnOffssets(baseOffset uint64, data []byte) ([]uint64, error) {
var returnOffsets []uint64
index := 0
for index < len(data) {

// FIXME remove this once x86asm is able to recognize and decode
// ENDBR64
if isENDBRXX(data[index:]) {
index += endbrSize
continue
}

instruction, err := x86asm.Decode(data[index:], 64)
if err != nil {
return nil, fmt.Errorf("failed to decode x64 instruction at offset %d: %w", index, err)
Expand Down
52 changes: 52 additions & 0 deletions pkg/internal/goexec/instructions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package goexec

import (
"testing"

"github.com/stretchr/testify/require"
)

var prog = []uint8{
0xf3, 0x0f, 0x1e, 0xfa, // endbr64
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
0x55,
0x48, 0x89, 0xe5,
0x48, 0x83, 0xec, 0x10,
0x64, 0x48, 0x8b, 0x04, 0x25, 0x28, 0x00,
0x00, 0x00,
0x48, 0x89, 0x45, 0xf8,
0x31, 0xc0,
0x85, 0xd2,
0x78, 0x24,
0x48, 0x8d, 0x4d, 0xf0,
0x48, 0x63, 0xd2,
0xe8, 0x25, 0xfd, 0xff, 0xff,
0x85, 0xc0,
0x7e, 0x03,
0x8b, 0x45, 0xf0,
0x48, 0x8b, 0x55, 0xf8,
0x64, 0x48, 0x2b, 0x14, 0x25, 0x28, 0x00,
0x00, 0x00,
0x75, 0x3c,
0xc9,
0xc3, // ret
0xff, 0x15, 0x2f, 0x1a, 0x0b, 0x00,
0x48, 0x8d, 0x15, 0x28, 0xfd, 0x08, 0x00,
0xbe, 0x18, 0x09, 0x00, 0x00,
0x48, 0x8d, 0x3d, 0x82, 0x4f, 0x08, 0x00,
0xff, 0x15, 0x4e, 0x1d, 0x0b, 0x00,
0x31, 0xc0,
0x31, 0xd2,
0xbe, 0x0f, 0x01, 0x00, 0x00,
0xbf, 0x14, 0x00, 0x00, 0x00,
0xff, 0x15, 0x72, 0x1c, 0x0b, 0x00,
0xb8, 0xff, 0xff, 0xff, 0xff,
0xeb, 0xb5,
0xff, 0x15, 0xb5, 0x21, 0x0b, 0x00,
}

func TestFindReturnOffsets(t *testing.T) {
offsets, err := findReturnOffssets(0, prog)
require.NoError(t, err)
require.Contains(t, offsets, uint64(0x46))
}

0 comments on commit a380cd0

Please sign in to comment.