-
Notifications
You must be signed in to change notification settings - Fork 0
/
ropkit_ropinclude.s
425 lines (313 loc) · 7.92 KB
/
ropkit_ropinclude.s
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
#pragma once
#define ROP_BXR1 POP_R4LR_BXR1+4
#define ROP_BXLR ROP_LDR_R0FROMR0+4 //"bx lr"
#define ROP_EQBXLR_NE_CALLVTABLEFUNCPTR (IFile_Close+0x4) //Offset 0x4 in IFile_Close for ROP conditional execution. For condition-code EQ, bx-lr is executed, otherwise a vtable funcptr call with the r0 object is executed.
#ifdef THROWFATALERR_IPC
#define ROP_SENDCMDADDR THROWFATALERR_IPC+0x14 //Writes r0 to r4+0, then copies 0x80-bytes from r1 to r4+4. Then uses svcSendSyncRequest with handle *r5.
#endif
#ifdef ROP_POPR3_ADDSPR3_POPPC
#define STACKPIVOT_ADR ROP_POPR3_ADDSPR3_POPPC
#endif
#ifndef ROPBUFLOC
#define ROPBUFLOC(x) (ROPBUF + (x - _start))
#endif
@ Size: 0x8
.macro ROP_SETR0 value
#ifdef POP_R0PC
.word POP_R0PC
.word \value
#elif defined (ROP_LDRR0SP_POPR3PC)
.word ROP_LDRR0SP_POPR3PC
.word \value
#else
#error "The gadget for setting r0 is not defined."
#endif
.endm
@ Size: 0x8
.macro ROP_SETR1 value
.word POP_R1PC
.word \value @ r1
.endm
@ Size: 0x8 + 0xc (0x14)
.macro ROP_SETLR lr
ROP_SETR1 ROP_POPPC
.word POP_R4LR_BXR1
.word 0 @ r4
.word \lr
.endm
@ Size: 0x34
.macro ROP_SETLR_OTHER lr
.word POP_R2R6PC
.word ROP_POPPC @ r2
.word 0 @ r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word POP_R4R8LR_BXR2
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word 0 @ r7
.word 0 @ r8
.word \lr
.endm
@ Size: 0x14 + 0x8 + 0x4 (0x20)
.macro ROP_LOADR0_FROMADDR addr
ROP_SETLR ROP_POPPC
ROP_SETR0 \addr
.word ROP_LDR_R0FROMR0
.endm
.macro CALLFUNC funcadr, r0, r1, r2, r3, sp0, sp4, sp8, sp12
ROP_SETLR POP_R2R6PC
ROP_SETR0 \r0
ROP_SETR1 \r1
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.word \sp0
.word \sp4
.word \sp8
.word \sp12
.word 0 @ r6
.endm
@ This is basically: CALLFUNC funcadr, *r0, r1, r2, r3, sp0, sp4, sp8, sp12
.macro CALLFUNC_LOADR0 funcadr, r0, r1, r2, r3, sp0, sp4, sp8, sp12
ROP_LOADR0_FROMADDR \r0
ROP_SETLR POP_R2R6PC
ROP_SETR1 \r1
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.word \sp0
.word \sp4
.word \sp8
.word \sp12
.word 0 @ r6
.endm
@ This is basically: CALLFUNC funcadr, r0, *r1, r2, r3, sp0, sp4, sp8, sp12
.macro CALLFUNC_LDRR1 funcadr, r0, r1, r2, r3, sp0, sp4, sp8, sp12
ROP_SETLR ROP_POPPC
ROPMACRO_COPYWORD ROPBUFLOC(. + 0x8 + 0x14 + 0x8 + 0x4), \r1
ROP_SETLR POP_R2R6PC
ROP_SETR0 \r0
ROP_SETR1 0 @ Overwritten by the above rop.
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.word \sp0
.word \sp4
.word \sp8
.word \sp12
.word 0 @ r6
.endm
@ This is basically: CALLFUNC funcadr, *r0, *r1, r2, r3, sp0, sp4, sp8, sp12
#define CALLFUNC_LDRR0R1_R1OFFSET 0x14 + ROPMACRO_COPYWORD_SRCADDROFFSET
.macro CALLFUNC_LDRR0R1 funcadr, r0, r1, r2, r3, sp0, sp4, sp8, sp12
ROP_SETLR ROP_POPPC
ROPMACRO_COPYWORD ROPBUFLOC(. + 0x8 + 0x14 + 0x20 + 0x4), \r1
ROP_LOADR0_FROMADDR \r0
ROP_SETLR POP_R2R6PC
ROP_SETR1 0 @ Overwritten by the above rop.
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.word \sp0
.word \sp4
.word \sp8
.word \sp12
.word 0 @ r6
.endm
@ Size: 0x40
#define CALLFUNC_NOSP_FUNCADROFFSET 0x3C
.macro CALLFUNC_NOSP funcadr, r0, r1, r2, r3
ROP_SETLR ROP_POPPC
ROP_SETR0 \r0
ROP_SETR1 \r1
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.endm
@ This is is basically: CALLFUNC_NOSP funcadr, *r0, r1, r2, r3
.macro CALLFUNC_NOSP_LDRR0 funcadr, r0, r1, r2, r3
ROP_LOADR0_FROMADDR \r0
ROP_SETR1 \r1
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.endm
@ This is is basically: CALLFUNC_NOSP funcadr, r0, r1, *r2, r3
.macro CALLFUNC_NOSP_LOADR2 funcadr, r0, r1, r2, r3
ROP_SETLR ROP_POPPC
ROPMACRO_COPYWORD ROPBUFLOC(. + 0x8 + 0x8 + 0x8 + 0x4), \r2
ROP_SETR0 \r0
ROP_SETR1 \r1
.word POP_R2R6PC
.word \r2
.word \r3
.word 0 @ r4
.word 0 @ r5
.word 0 @ r6
.word \funcadr
.endm
.macro CALLFUNC_NOARGS funcadr
ROP_SETLR ROP_POPPC
.word \funcadr
.endm
#define CALLFUNC_R0R1_R0OFFSET 0x14 + 0x4
#define CALLFUNC_R0R1_R1OFFSET 0x14 + 0x8 + 0x4
.macro CALLFUNC_R0R1 funcadr, r0, r1
ROP_SETLR ROP_POPPC
ROP_SETR0 \r0
ROP_SETR1 \r1
.word \funcadr
.endm
.macro CALL_GXCMD4 srcadr, dstadr, cpysize
CALLFUNC GXLOW_CMD4, \srcadr, \dstadr, \cpysize, 0, 0, 0, 0, 0x8
.endm
@ This is basically: CALL_GXCMD4 *srcadr, dstadr, cpysize
.macro CALL_GXCMD4_LDRSRC srcadr, dstadr, cpysize
CALLFUNC_LOADR0 GXLOW_CMD4, \srcadr, \dstadr, \cpysize, 0, 0, 0, 0, 0x8
.endm
@ This is basically: CALL_GXCMD4 srcadr, *dstadr, cpysize
.macro CALL_GXCMD4_LDRDST srcadr, dstadr, cpysize
CALLFUNC_LDRR1 GXLOW_CMD4, \srcadr, \dstadr, \cpysize, 0, 0, 0, 0, 0x8
.endm
@ This is basically: CALL_GXCMD4 *srcadr, *dstadr, cpysize
.macro CALL_GXCMD4_LDRSRCDST srcadr, dstadr, cpysize
CALLFUNC_LDRR0R1 GXLOW_CMD4, \srcadr, \dstadr, \cpysize, 0, 0, 0, 0, 0x8
.endm
#ifndef ROP_POPR3_ADDSPR3_POPPC
.macro ROPMACRO_STACKPIVOT_PREPARE sp, pc
.word POP_R4R6PC
.word 0
.word 0
.word pivot_regstore
ROPMACRO_WRITEWORD pivot_regstore-4, \pc
ROPMACRO_WRITEWORD pivot_regstore-12, \sp
.endm
.macro ROPMACRO_STACKPIVOT_PREPAREREGS_BEFOREJUMP
.endm
.macro ROPMACRO_STACKPIVOT_JUMP
.word STACK_PIVOT2
.endm
#endif
#ifdef ROP_POPR3_ADDSPR3_POPPC
.macro ROPMACRO_STACKPIVOT_JUMP
.word ROP_POPR3_ADDSPR3_POPPC
.endm
#endif
.macro ROPMACRO_STACKPIVOT sp, pc
#ifndef ROP_POPR3_ADDSPR3_POPPC
ROPMACRO_STACKPIVOT_PREPARE \sp, \pc
ROPMACRO_STACKPIVOT_PREPAREREGS_BEFOREJUMP
ROPMACRO_STACKPIVOT_JUMP
#else
.word ROP_POPR3_ADDSPR3_POPPC
.word \sp - ROPBUFLOC(. + 0x4)
#endif
.endm
.macro COND_THROWFATALERR
#ifdef ROP_COND_THROWFATALERR
.word ROP_COND_THROWFATALERR
.word 0 @ r3
.word 0 @ r4
.word 0 @ r5
#elif defined (ROP_COND_THROWFATALERR_ALT0)
.word ROP_COND_THROWFATALERR_ALT0
.word 0 @ r3, r0 is also loaded from here.
#else
#error "ROP_COND_THROWFATALERR* isn't defined."
#endif
.endm
#define ROPMACRO_CMPDATA_CMPADDR_OFFSET 0x2C
#define ROPMACRO_CMPDATA_CMPWORD_OFFSET 0x38
.macro ROPMACRO_CMPDATA cmpaddr, cmpword, stackaddr_cmpmismatch
ROP_SETLR ROP_POPPC
ROP_LOADR0_FROMADDR \cmpaddr
ROP_SETR1 \cmpword
#ifdef ROP_CMPR0R1
.word ROP_CMPR0R1
.word 0
#elif defined (ROP_CMPR0R1_ALT0)
.word ROP_CMPR0R1_ALT0
#else
#error "ROP_CMPR0R1* isn't defined."
#endif
#ifndef ROP_POPR3_ADDSPR3_POPPC
ROPMACRO_STACKPIVOT_PREPARE \stackaddr_cmpmismatch, ROP_POPPC
ROPMACRO_STACKPIVOT_PREPAREREGS_BEFOREJUMP
#endif
ROP_SETR0 ROPBUFLOC(ropkit_cmpobject)
#ifdef ROP_POPR3_ADDSPR3_POPPC
ROP_SETLR POP_R1PC
#endif
.word ROP_EQBXLR_NE_CALLVTABLEFUNCPTR @ When the value at cmpaddr matches cmpword, continue the ROP, otherwise call the vtable funcptr which then does the stack-pivot.
#ifdef ROP_POPR3_ADDSPR3_POPPC
.word (\stackaddr_cmpmismatch) - ROPBUFLOC(. + 0x4)
#endif
.endm
@ Size: 0x14 + 0x8 + 0x8 + 0x4 (0x28)
.macro ROPMACRO_WRITEWORD addr, value
ROP_SETLR ROP_POPPC
ROP_SETR0 \addr
ROP_SETR1 \value
.word ROP_STR_R1TOR0
.endm
@ Size: 0x14 + 0x20 + 0x8 + 0x4 (0x40)
#define ROPMACRO_COPYWORD_SRCADDROFFSET 0x2c
#define ROPMACRO_COPYWORD_DSTADDROFFSET 0x38
.macro ROPMACRO_COPYWORD dstaddr, srcaddr
ROP_SETLR ROP_POPPC
ROP_LOADR0_FROMADDR \srcaddr
ROP_SETR1 \dstaddr
.word ROP_STR_R0TOR1
.endm
.macro ROPMACRO_COPYWORD_FROMR0 dstaddr
ROP_SETLR ROP_POPPC
.word ROP_LDR_R0FROMR0
ROP_SETR1 \dstaddr
.word ROP_STR_R0TOR1
.endm
#define ROPMACRO_LDDRR0_ADDR1_STRADDR_VALUEOFFSET 0x24 //Offset relative to the start of ROPMACRO_LDDRR0_ADDR1_STRADDR where the add-value is located.
.macro ROPMACRO_LDDRR0_ADDR1_STRADDR dstaddr, srcaddr, value
ROP_LOADR0_FROMADDR \srcaddr
ROP_SETR1 \value
.word ROP_ADDR0_TO_R1 @ r0 = *srcaddr + value
ROP_SETR1 \dstaddr
.word ROP_STR_R0TOR1 @ Write the above r0 value to *dstaddr.
.endm
.macro ROPMACRO_LDDRR0_ADDR1_STRVALUE addr, addval, writeval
ROP_LOADR0_FROMADDR \addr
ROP_SETR1 \addval
.word ROP_ADDR0_TO_R1 @ r0 = *addr + addval
ROP_SETR1 \writeval
.word ROP_STR_R1TOR0 @ Write the above writeval to <calculated r0>.
.endm
.macro ROPMACRO_IFile_Close IFile_ctx
ROP_LOADR0_FROMADDR \IFile_ctx
.word IFile_Close
.endm