I am currently attempting to debug a crash of a c++ application that corrupted the stack. After some investigation I am very sure I know valid $rsp and $rip address that correspond to a very useful frame on the stack that should be uncorrupted.
It would be incredibly useful to be able to use all of gdb's built-in features for dealing with dynamically addressed calls when it has a valid stack. Unfortunately gdb cannot set these register values directly when debugging a core file, and I have found a feature request literally a decade old asking for this functionality.
Is there some way to edit the core file directly to set these values? Or does lldb potentially allow you to override these register values when debugging a core file?
Sure -- the values are stored in the
coresomewhere; the trick is finding out where exactly.The register values are stored in the
PRSTATUSnotes (the first such note is usually the one corresponding to the crashing thread).You can examine the notes from your existing
corewithelfutilseu-readelf -Wn core. The output will look similar to:Here you can see that the
Noteis at offset0x580, and therspregister is somewhere within it.From here, you can use
offsetof(struct elf_prstatus, pr_reg)(112onx86_64), andoffsetof(struct user_regs_struct, rsp)(152).If my arithmetic is correct, the value of
rspshould be at0x580 + 20 + 112 + 152. Let's check this:So overwriting the 8-byte value at offset
0x69cinto thiscoreshould produce desired result.P.S. Where did the extra
20come from? TheElf64_Nhdrhas a few data items before the note data starts:n_namesz, n_descsz, n_type(each 4 bytes), followed by note name (CORE\0here), rounded up to 4-byte boundary (so 8 bytes total).