-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path__init__.py
70 lines (57 loc) · 2.21 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Copyright 2021 Linus S. (PistonMiner)
# Go internal ABI changes over time so this may not be the most current, see:
# https://github.com/golang/go/blob/d20a0bfc8a7fd70537766990691d4c9e5841e086/src/cmd/compile/abi-internal.md
# Interactions with assembly functions use a different calling convention
# This is _not_ implemented here
# You can see this e.g. if xorps xmm15, xmm15 runs after calls
# https://go.dev/doc/asm#amd64
from binaryninja import *
BINJA_VERSION = 3
class GoCall_X86_64(CallingConvention):
name = "gocall"
caller_saved_regs = [
"rax", "rbx", "rcx", "rdi", "rsi", "r8", "r9", "r10", "r11", # int
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", # float
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",
] # todo: all
callee_saved_regs = [
#"rbp", # frame pointer
"zmm15", "ymm15", "xmm15", # zero value (may be modified within)
]
implicitly_defined_regs = [
"zmm15", "ymm15", "xmm15", # zero value
"r14" # current goroutine
]
int_arg_regs = [
"rax", "rbx", "rcx", "rdi", "rsi", "r8", "r9", "r10", "r11",
]
float_arg_regs = [
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14",
]
#arg_regs_share_index = False
#arg_regs_for_varargs = ?
#stack_reserved_for_arg_regs
# disable auto-assign
eligible_for_heuristics = False
# actually can return through all the arg regs but binja can only do finite
int_return_reg = "rax"
high_int_return_reg = "rbx"
cc = GoCall_X86_64(arch=Architecture["x86_64"], name="gocall")
Architecture["x86_64"].register_calling_convention(cc)
def setup_go_binary(bv):
for f in bv.functions:
f.calling_convention = bv.arch.calling_conventions["gocall"]
bv.set_analysis_hold(False)
bv.reanalyze()
def setup_go_binary_is_valid(bv):
# We only support x86_64 right now
if bv.arch and bv.arch.name != "x86_64":
return False
return True
PluginCommand.register(
"Go\\Set Go calling convention",
"Should load with analysis hold! Set gocall on all functions.",
setup_go_binary,
setup_go_binary_is_valid
)