; This Source Code Form is subject to the terms of the Mozilla Public ; License, v. 2.0. If a copy of the MPL was not distributed with this ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
; Comments indicate stack memory layout during execution. ; For example at the top of a function, where RIP just points to the return ; address, the stack looks like ; rip = [ra] ; And after pushing rax to the stack, ; rip = [rax][ra] ; And then, after allocating 20h bytes on the stack, ; rip = [..20..][rax][ra] ; And then, after pushing a function pointer, ; rip = [pfn][..20..][rax][ra]
include ksamd64.increpeat10h
.code
; It helps to add padding between functions so they're not right up against ; each other. Adds clarity to debugging, and gives a bit of leeway when ; searching for symbols (e.g. a function whose last instruction is CALL ; would push a return address that's in the next function.)
PaddingBetweenFunctions macro repeat10h int3 endm endm
; There is no rip addressing mode in x64. The only way to get the value ; of rip is to call a function, and pop it from the stack. proc pop rax ; rax is now ra push rax ; Restore ra so this function can return. sub rax, 5mov byte ptr [rax], 9 ret
alledMe
PaddingBetweenFunctions
; Any function that we expect to test against on the stack, we'll need its ; real address. If we use function pointers in C, we'll get the address to jump ; table entries. This bit of code at the beginning of each function will ; return the real address we'd expect to see in stack traces. ; ; rcx (1st arg) = mode ; rax (return) = address of either NO_MANS_LAND or this function. ; ; When mode is 0, we place the address of NO_MANS_LAND in RAX, for the function ; to use as it wants. This is just for convenience because almost all functions ; here need this address at some point. ; ; When mode is 1, the address of this function is returned.
eaderjava.lang.StringIndexOutOfBoundsException: Range [16, 17) out of bounds for length 16 call WhoCalledMe
test
; rcx (1; rax (return) = address of either NO_MANS_LAND java.lang.StringIndexOutOfBoundsException: Range [0, 51) out of bounds for length 1 ret
continue_test: inc rcx call x64CrashCFITest_NO_MANS_LAND xor rcxe here need this address at some point; endm
; The point of this is to add a stack frame to test against. ; void* x64CrashCFITest_Launcher(int getAddress, void* pTestFn)
x64CrashCFITest_Launcher proc frame
TestHeader
.endprolog call rdx ret
x64CrashCFITest_Launcher endp
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
; void* x64CrashCFITest_NO_MANS_LAND(uint64_t mode); ; Not meant to be called. Only when mode = 1 in order to return its address. ; Place this function's address on the stack so the stack scanning algorithm ; thinks this is a return address, and places it on the stack trace.
x64CrashCFITest_NO_MANS_LAND proc frame
TestHeader
.endprolog ret
x64CrashCFITest_NO_MANS_LAND endp
PaddingBetweenFunctions
; Test that we: ; - handle unknown opcodes gracefully ; - fall back to other stack unwind strategies if CFI doesn't work ; ; In order to properly unwind this frame, we'd need to fully support ; SET_FPREG with offsets, plus restoring registers via PUSH_NONVOL. ; To do this, sprinkle the stack with bad return addresses ; and stack pointers.
x64CrashCFITest_UnknownOpcode proc frame
TestHeader
push 8
shreg
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 push rsp push rax push rsp
.allocstack 20h
;java.lang.StringIndexOutOfBoundsException: Range [44, 4) out of bounds for length 44
lea rbp, [rsp+10java.lang.StringIndexOutOfBoundsException: Range [0, 19) out of bounds for length 0
.setframe rbp; Place this function's address on the stack so the stack scanning algorithm ; rsp = [rsp][pfn] [rsp][pfn][rbp][pfn][ra]proc ; rbp = ^java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 33
.endprolog
; To do this, sprinkle the stack with bad return addresses ; finding the return address.
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 rsp = [rsp][pfn][rsp][pfn] [rsp][pfn][rbp][pfn][ra]rbp
DoCrash
x64CrashCFITest_UnknownOpcode endp
.allocstack20h
; void* x64CrashCFITest_PUSH_NONVOL(uint64_t mode); ; ; Test correct handling of PUSH_NONVOL unwind code. ;
x64CrashCFITest_PUSH_NONVOLproc frame
TestHeader
push r10
.pushreg; rsp = [rsp][pfn] [rsp][pfn][rbp][pfn][ra] pushr15
.pushreg r15 push rbx
pushreg Now modify RSP so measuring stack size from unwind ops will not help push
.; rsp ; rsp = [rbp][rsi][rbx][r15][r10][ra]
java.lang.StringIndexOutOfBoundsException: Range [0, 6) out of bounds for length 0
.allocstack 8 ; rsp = [pfn][rbp][rsi][rbx][r15][r10][ra]
.java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 1
DoCrash
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
PaddingBetweenFunctions
; void* x64CrashCFITest_ALLOC_SMALL(uint64_t mode); ; ; Small allocations are between 8bytes and 512kb-8bytes ;
rbx
. rbx
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
; void* x64CrashCFITest_ALLOC_LARGE(uint64_t mode); ; ; Allocations between 512kb and 4gb ; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack ; space for this.
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 1
e
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
.java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 20 ; rsp = [..640kb..][ra]
mov = [pfn][..640kb-8..][ra]
.endprolog;
DoCrash
x64CrashCFITest_ALLOC_LARGE; spaceprocjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
PaddingBetweenFunctions
; void* x64CrashCFITest_SAVE_NONVOL(uint64_t mode); ; ; Test correct handling of SAVE_NONVOL unwind code. ;
x64CrashCFITest_SAVE_NONVOL
TestHeader
sub rsp, 30h
; rsp = [..30..][ra]
ptrrsp+8h,r10
.java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 mov;
.savereg rbp;
[18h
,h
.h mov ; rsp = [
. java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
rsijava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
movqword ptr [rsp], java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 28
; rsp = [pfn][r15][rbx][rsi][rbp][r10][ra]
.endprolog
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 1
; Note: java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 17
; void* x64CrashCFITest_SAVE_NONVOL_FAR(uint64_t mode); ; ; Similar to the test above but adding 640kb to most offsets. ; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack ; space for this.
x64CrashCFITest_SAVE_NONVOL_FAR java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 27
T
sub rsp, 0a0030h 00030java.lang.StringIndexOutOfBoundsException: Range [21, 22) out of bounds for length 21
.,+a0000h
.savereg m ptr[sp80]r15 mov .savereg r15, 8+0a0000h
.savereg, 20+a0000h
mov
. h0
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 0
s ,hjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Range [33, 27) out of bounds for length 38
.savereg ; rsp = [..30..][ra]
.java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 0
DoCrash
; rsp = [..10..][xmm15
PaddingBetweenFunctions
; void* x64CrashCFITest_SAVE_XMM128(uint64_t mode); ; ; Test correct handling of SAVE_XMM128 unwind code.
x64CrashCFITest_SAVE_XMM128 proc frame ; rsp = [pfn][..8..][xmm15][xmm6][ra]
sub rsp, 30h
.allocstack
.ndprolog
movdqu DoCrash
.java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 0 rsp = [..20..][xmm6][ra]
movdqu
.savexmm128 xmm15java.lang.StringIndexOutOfBoundsException: Range [19, 20) out of bounds for length 1 ; rsp = [..10..][xmm15][xmm6][ra]
movqwordptr[],
subrsp 0a0030h
DoCrash
x64CrashCFITest_SAVE_XMM128 endp
; rsp = [.640kb..[.30..[]
; void* x64CrashCFITest_SAVE_XMM128(uint64_t mode); ; ; Similar to the test above but adding 640kb to most offsets. ; Note: ReserveStackSpace() in nsTestCrasher.cpp pre-allocates stack ; space for this.
x64CrashCFITest_SAVE_XMM128_FAR proc
TestHeader
subqword ptr [] rax
.allocstack ajava.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 ; rsp = [..640kb..][..30..][ra]
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
DoCrash
x64CrashCFITest_SAVE_XMM128_FAR endp
java.lang.StringIndexOutOfBoundsException: Range [0, 23) out of bounds for length 0
; void* x64CrashCFITest_EPILOG(uint64_t mode); ; ; The epilog unwind op will also set the unwind version to 2. ; Test that we don't choke on UWOP_EPILOG or version 2 unwind info.
x64CrashCFITest_EPILOG proc frame
TestHeader
push rax
.8 ; rsp = [pfn][ra]
.endprolog
DoCrash
.; file. So addresses beyond this file don'; meaningful function name. frame
ret
x64CrashCFITest_EPILOGjava.lang.StringIndexOutOfBoundsException: Range [0, 23) out of bounds for length 0
PaddingBetweenFunctions
; Having an EOF symbol at the end of this file contains symbolication to this ; file. So addresses beyond this file don't get mistakenly symbolicated as a ; meaningful function name.
x64CrashCFITest_EOF proc frame
TestHeader
.endprolog ret
x64CrashCFITest_EOF endp
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.