; 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.inc
.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.
WhoCalledMe proc pop rax ; rax is now ra push rax ; Restore ra so this function can return. sub rax, 5; Correct for the size of the call instruction ret
WhoCalledMe endp
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.
TestHeader macro call WhoCalledMe
test rcx, rcx je continue_test ret
continue_test: inc rcx call x64CrashCFITest_NO_MANS_LAND xor rcx, rcx 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
PaddingBetweenFunctions
; 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
; Now modify RSP so measuring stack size from unwind ops will not help ; finding the return address. push rax push rsp ; rsp = [rsp][pfn][rsp][pfn] [rsp][pfn][rbp][pfn][ra]
DoCrash
x64CrashCFITest_UnknownOpcode endp
PaddingBetweenFunctions
; void* x64CrashCFITest_PUSH_NONVOL(uint64_t mode); ; ; Test correct handling of PUSH_NONVOL unwind code. ;
x64CrashCFITest_PUSH_NONVOL proc frame
TestHeader
; void* x64CrashCFITest_ALLOC_SMALL(uint64_t mode); ; ; Small allocations are between 8bytes and 512kb-8bytes ;
x64CrashCFITest_ALLOC_SMALL proc frame
TestHeader
; 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 proc frame
TestHeader
sub rsp, 0a0030h
.allocstack 0a0030h ; rsp = [..640k..][..30..][ra]
; 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 frame
TestHeader
sub rsp, 0a0030h
.allocstack 0a0030h ; rsp = [..640kb..][..30..][ra]
; 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
.allocstack 8 ; rsp = [pfn][ra]
.endprolog
DoCrash
.beginepilog
ret
x64CrashCFITest_EPILOG endp
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
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet am 2026-06-05)
¤
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.