summaryrefslogtreecommitdiff
path: root/src/vm/amd64/asan_wrapper.S
blob: a58828b2d30ae17a6c6e2b65d90ba4871217d418 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# ----------------------------------------------------------------------------------------
# Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
# To assemble and run:
#
#     gcc -c hello.s && ld hello.o && ./a.out
#
# or
#
#     gcc -nostdlib -no-pie hello.s && ./a.out
# ----------------------------------------------------------------------------------------

RETADDR_OFFSET=8*15

.macro PUSH_REGS
	push %rdi       # 0, arg0
	push %rsi       # 1, arg1
	push %rdx       # 2, arg2
	push %rcx       # 3, arg3
	push %r8        # 4, arg4
	push %r9        # 5, arg5
	push %r10       # 6, ...
	push %r11       # 7, temprory reg
	push %rax       # 8

	push %rbp
	push %rbx
	push %r15
	push %r14
	push %r13
	push %r12
.endm

.macro POP_REGS
	pop %r12
	pop %r13
	pop %r14
	pop %r15
	pop %rbx
	pop %rbp


	pop %rax
	pop %r11
	pop %r10
	pop %r9
	pop %r8
	pop %rcx
	pop %rdx
	pop %rsi
	pop %rdi
.endm

        .global hex_wrapper
	.global hex_wrapper_size
	.global hex_wrapper_entry_offset

	# Extern functions
	.global asan_enable_addr_offset
	.global asan_disable_addr_offset
	.global target_addr_offset
	.global get_return_addr_offset


        .text
	.code64

hex_wrapper:
asan_enable_addr:	.quad 0x0badc0de0badc0de
asan_disable_addr:	.quad 0x0badc0de0badc0de
target_addr:		.quad 0x0badc0de0badc0de
get_return_addr:	.quad 0x0badc0de0badc0de

hex_wrapper_entry:
	# Save context
	PUSH_REGS

	# Save the return adderss
	call *get_return_addr(%rip)	# rax: get space for saving the return address
	mov RETADDR_OFFSET(%rsp), %rdi	# rdi: get return address
	mov %rdi, (%rax)		# save the return address to the received space

	# Change the return address on the 'wrapper_second'
	call next
next:	pop %rax				# rax: get current rip
	add $(wrapper_second - next), %rax	# rax: add offset to 'wrapper_second'
	mov %rax, RETADDR_OFFSET(%rsp)		# change the return address

	# Enable ASan
	call *asan_enable_addr(%rip)

	# Restore context
	POP_REGS

	# Call original function
	jmp *target_addr(%rip)
wrapper_second:
	# Save context
	PUSH_REGS

	# Align stack
	add $8, %rsp

	# Disable ASan
	call *asan_disable_addr(%rip)

	# Restore the return address
	call *get_return_addr(%rip)	# rax: get pointer to saved the return address
	sub $8, %rsp			# 'restore' aligned stack
	mov (%rax), %rdi		# rdi: get the return address
	mov %rdi, RETADDR_OFFSET(%rsp)	# restore the return address

	# Restore context
	POP_REGS

	# Return
	ret

hex_wrapper_size:		.quad . - hex_wrapper

hex_wrapper_entry_offset:	.quad hex_wrapper_entry - hex_wrapper
asan_enable_addr_offset:	.quad asan_enable_addr - hex_wrapper
asan_disable_addr_offset:	.quad asan_disable_addr - hex_wrapper
target_addr_offset:		.quad target_addr - hex_wrapper
get_return_addr_offset:		.quad get_return_addr - hex_wrapper


# set environment LD_PRELOAD /root/asan/libasan.so