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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
#
# C-callable and linkable version of 'patchinst' portion of monitor.asm
#
# Assemble with:
# mipsel-none-elf-gcc -march=r3000 -c stubinst.s -o stubinst.o
#
# Then call the function early in your program:
#
# void mk2_InstallMonitor(void);
#
# ...
#
# int main(int argc, const char *argv[])
# {
# ResetGraph(0);
#
# EnterCriticalSection();
# mk2_InstallMonitor();
# ExitCriticalSection();
# ...
#
.set noreorder
#
# These constants must reflect those in monitor.asm
#
.set MONADDR, 0xC000
.set MAX_BREAK, 32
.set SAVE_mode, 0x30
.set SAVE_tmode, 0x31
.set SAVE_k0, 0x34
.set SAVE_k1, 0x38
.set SAVE_dcic, 0x3C
.set DB_BRK_FLAG, 0
.set DB_BRK_ADDR, 4
.set DB_BRK_INST, 8
.set DB_BRK_LCNT, 12
.set DB_BRK_HCNT, 14
.set DB_BRK_LEN, 16
.set DCIC, $7
.section .text
.global _mk2_InstallMonitor
.type _mk2_InstallMonitor, @function
_mk2_InstallMonitor:
addiu $sp, -4
sw $ra, 0($sp)
li $a0, .Lbreakhook # Install breakpoint vector hook
li $a1, (.Lbreakhook_end-.Lbreakhook)+4
li $a2, 0xA0000040
jal .Lcopymem
nop
li $v0, 0x200 # Hook monitor entrypoint to
li $v1, 0x40 # SysErrUnresolvedException() slot
sll $v1, 2
addu $v0, $v1
la $v1, .Lpayload # Get entrypoint address
lw $v1, 0($v1)
nop
sw $v1, 0($v0)
addiu $t2, $0, 0xB0 # GetB0Table()
jalr $t2
addiu $t1, $0, 0x57
li $a0, 0x17 # Get pointer of ReturnFromException()
sll $a0, 2
addu $a0, $v0
lw $v0, 0($a0) # Save original address for later
la $v1, .Lpayload
lw $v1, 0($v1)
nop
beq $v0, $v1, .Lnoinstall # Don't install if hooked already
nop
addiu $sp, -4
sw $a0, 0($sp)
li $a0, .Lpayload # Load monitor code into target
li $a1, (.Lpayload_end-.Lpayload)+4 # address
lui $a2, 0xA000 # write via uncached segment
jal .Lcopymem
ori $a2, MONADDR
lw $a0, 0($sp)
addiu $sp, 4
lw $v0, 0($a0)
la $v1, .Lpayload
lw $v1, 4($v1)
nop
sw $v0, 0($v1)
la $v0, .Lpayload # Set new address to table
lw $v0, 0($v0)
nop
sw $v0, 0($a0)
li $a0, 0x80 # Move existing exception vector
li $a2, 0x90 # jump to prepend patch
jal .Lcopymem
li $a1, 16
la $a0, .Lexceptpatch # Patch the exception vector for
li $a2, 0x80 # trace to work properly
jal .Lcopymem
li $a1, 16
addiu $t2, $0, 0xA0 # FlushCache() just to make sure
jalr $t2
addiu $t1, $0, 0x44
jal .Linit_breakpoints
nop
.Lnoinstall:
lw $ra, 0($sp) # Return to caller, debugger
addiu $sp, 4 # already installed
jr $ra
nop
# patchinst
#
# = installer's copy routine
#
.Lcopymem:
addiu $a1, -4
lw $v0, 0($a0)
addiu $a0, 4
sw $v0, 0($a2)
bgtz $a1, .Lcopymem
addiu $a2, 4
jr $ra
nop
# copymem
#
# = Initializes breakpoint list
#
.Linit_breakpoints:
la $a2, .Lpayload # Get address of breakpoint table
lw $a2, 8($a2)
li $a3, MAX_BREAK
addiu $v0, $0, -1
.Lclear_loop:
sw $v0, DB_BRK_INST($a2)
sw $v0, DB_BRK_ADDR($a2)
sw $0 , DB_BRK_FLAG($a2)
addiu $a3, -1
bnez $a3, .Lclear_loop
addiu $a2, DB_BRK_LEN
jr $ra
nop
# init_breakpoints
#
# = Break vector hook code
#
# This is copied to the breakpoint exception vector at address 40h
#
.Lbreakhook:
sw $k0, SAVE_k0($0) # Save K0 and K1 registers
mfc0 $k0, DCIC # Save DCIC
sw $k1, SAVE_k1($0)
mtc0 $0, DCIC # Clear DCIC in case trace is still
sw $k0, SAVE_dcic($0) # effective
la $k0, breakhandler # Jump to break vector handler
jr $k0
nop
.Lbreakhook_end:
#
# = Exception vector patch
#
# This is prepended to the exception vector jump at address 80h
#
.Lexceptpatch:
mfc0 $k0, DCIC # backup DCIC value
nop
mtc0 $0 , DCIC # clear DCIC
sw $k0, SAVE_dcic($0)
#
# = Payload data
#
.section .data
.Lpayload:
.incbin "patchcode.bin"
.Lpayload_end:
|