RBP register value in windbg windows stack

552 Views Asked by At

If i have code flow like main()--> a()--> b()-->c(), if I break in debugger(windbg) at c() and dump register values of all frames in debugger as ".frame /r frame_number"......do i see correct value for RBP every frame ? From documentation, i see RBP is a non volatile register and is saved during function call....does this mean we will get correct RBP value only while unwinding ?.....if I stop in debugger and dump in above fashion, will I not get correct value...if so how will debugger show the variable values for all frames if we click on that frame

1

There are 1 best solutions below

3
On

you may also need to override local context with /c else baseptr of frame 0 will be displayed for all frames if you are going to use the it for some purpose

:\>ls -lg & cat stackbase.cpp
total 4
-rw-rw-rw-  1 0 354 2020-11-24 19:46 stackbase.cpp


#include <stdio.h>
#include <stdlib.h>
int c (int c) {
    return c+9;     //16
}
int b (int b) {
    return b+c(7);  //21
}
int a (int a) {
    return a+b(5);  //argv[1]==0=>21
}
int main ( int argc , char* argv[] ) {
    int ans = 0;
    if(argc == 2) {
        ans = a(atoi(argv[1]));
    }
    printf("%d\n", ans);
    return ans;
}


:\>cl /Zi /W4 /analyze /Od /EHsc /nologo stackbase.cpp /link /release
stackbase.cpp

:\>stackbase.exe  1316
1337

under windbg broken on c() with callstack;

:\>cdb -c "bp stackbase!c \"kc\";g" stackbase.exe 1316

Microsoft (R) Windows Debugger Version 10.0.18362.1 X86

CommandLine: stackbase.exe 1316

0:000> cdb: Reading initial command 'bp stackbase!c "kc";g'

stackbase!c
stackbase!b
stackbase!a
stackbase!main
stackbase!invoke_main
stackbase!__scrt_common_main_seh
kernel32!BaseThreadInitThunk
ntdll!__RtlUserThreadStart
ntdll!_RtlUserThreadStart

eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a1000 esp=0026f958 ebp=0026f960 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
stackbase!c:
011a1000 55              push    ebp
0:000>

you can check the difference with these two commands

0:000> !for_each_frame ".frame /r @$frame; r ebp"
0:000> !for_each_frame ".frame /r /c @$frame; r ebp"

here is the result for just /r which will always print the last set baseptr while ebp is differnet in all other frames in this 32bit demo

0:000> !for_each_frame ".frame /r @$frame; r ebp"
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
00 0026f954 011a101a stackbase!c
00 0026f954 011a101a stackbase!c
eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a1000 esp=0026f958 ebp=0026f954 
stackbase!c:
011a1000 55              push    ebp
ebp=0026f960
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
01 0026f960 011a103a stackbase!b+0xa
01 0026f960 011a103a stackbase!b+0xa
eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a101a esp=0026f95c ebp=0026f960
stackbase!b+0xa:
011a101a 83c404          add     esp,4
ebp=0026f960
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
02 0026f96c 011a107e stackbase!a+0xa
02 0026f96c 011a107e stackbase!a+0xa
eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a103a esp=0026f968 ebp=0026f96c
stackbase!a+0xa:
011a103a 83c404          add     esp,4
ebp=0026f960
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
03 0026f97c 011a12e3 stackbase!main+0x2e
03 0026f97c 011a12e3 stackbase!main+0x2e
eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a107e esp=0026f974 ebp=0026f97c
stackbase!main+0x2e:
011a107e 83c404          add     esp,4
ebp=0026f960
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
04 (Inline) -------- stackbase!invoke_main+0x1c
04 (Inline) -------- stackbase!invoke_main+0x1c
eax=00000524 ebx=7ffd7000 ecx=00000524 edx=00000000 esi=011ea760 edi=003c9128
eip=011a12e3 esp=0026f984 ebp=0026f9c4