I'm currently tasked to perform post-mortem debugging using gdb, binary and a core file. Often I encounter the phenomenon of stack trashing where the stack cannot be reconstructed by bt. However, by examining memory I can often recover contiguous parts of the stack area that are still intact, including their frame pointers.
My question now is if I can recover such a frame pointer, is there a gdb command that allows me to reconstruct and print the stack up to this point, including all local variables? Or will the bt command only work up from the current frame pointer?
Regards
Related
I have i binary that can be exploited with a buffer overflow, but it has a stack canary
I can get many addresses and values through a gets() call, but i cant locate the stack canary in pwndbg( version of gdb) so i can find out what of the values i get is the stack canary
I tried looking on the stack but cant find it and looked at a script that can already exploit it and it uses a canary value (by this i mean index of the leaked addresses from the gets() ) that i cant even find in the disassembler
I am missing some key details here, but I'll try to give this a go.
Firstly, the canary is not going to be on the stack, but between stack frames:
https://manybutfinite.com/img/stack/bufferCanary.png
Googling "stack canary location gcc" yields a couple images to help you understand this mechanism more easily.
Secondly, I am not quite sure what do you mean by using gets() to read. gets() reads the stdin and puts it into a buffer. You will not be able to use it to read program memory.
Regarding the script that is already working: I am skeptical.
From the gcc docs (https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html):
The guards are initialized when a function is entered and then checked when the function exits.
It might be possible that the code that manages to exploit it either has stack protector turned off in the binary, or it finds another way to bypass this protection by some other means. You can, for example overflow a local function pointer and not trigger the stack protector at all. The stack protector only protects against overflowing into the stored RBP and RIP (32bit: EBP and EIP), not against overflowing into local variables.
My program creates a minidump on crash (using MiniDumpWriteDump from DBGHELP.DLL) and I would like to keep the size of the dump as low as possible while still having important memory information available. I have gone through the different possible combinations of flags and callback functionalities you can pass to MiniDumpWriteDump (links to debuginfo.com or MSDN).
I think I am limited to these MINIDUMP_TYPE flags, since it has to work on an old WinXP machine:
MiniDumpNormal
MiniDumpWithDataSegs
MiniDumpWithFullMemory
MiniDumpWithHandleData
MiniDumpFilterMemory
MiniDumpScanMemory
I am searching for a way how to combine these flags and the callback function to get a dump with the following requirements:
Relative small size (Full memory dump results in ~200MB filesize, I want max. 20MB)
Stack trace of the crashed thread, maybe also the stack trace of other threads but without memory info
Memory information of the whole stack of the crashed thread. This is where it gets complicated: Including stack memory should be no problem in terms of size but heap memory might be overkill.
The question is how can I limit the memory info to the crashed thread and how to include stack memory (local variables) of the whole call stack?
Is it also possible to include parts of the heap memory, like only these parts that are referenced by the current call stack?
For example when we call say, a recursive function, the successive calls are stored in the stack. However, due to an error if it goes on infinitely the error is 'Segmentation fault' (as seen on GCC).
Shouldn't it have been 'stack-overflow'? What then is the basic difference between the two?
Btw, an explanation would be more helpful than wikipedia links (gone through that, but no answer to specific query).
Stack overflow is [a] cause, segmentation fault is the result.
At least on x86 and ARM, the "stack" is a piece of memory reserved for placing local variables and return addresses of function calls. When the stack is exhausted, the memory outside of the reserved area will be accessed. But the app did not ask the kernel for this memory, thus a SegFault will be generated for memory protection.
Modern processors use memory managers to protect processes from each other. The x86 memory manager has many legacy features, one of which is segmentation. Segmentation is meant to keep programs from manipulating memory in certain ways. For instance, one segment might be marked read-only and the code would be put there, while another segment is read/write and that's where your data goes.
During a stack overflow, you exhaust all of the space allocated to one of your segments, and then your program starts writing into segments that the memory manager does not permit, and then you get a segmentation fault.
A stack overflow can manifest as either an explicit stack overflow exception (depending on the compiler and architecture) or as a segmentation fault, i.e., invalid memory access. Ultimately, a stack overflow is the result of running out of stack space, and one possible result of running out of stack space is reading or writing to memory that you shouldn't access. Hence, on many architectures, the result of a stack overflow is a memory access error.
The call stack is being overflowed, however the result of the overflowing is that eventually call-related values are pushed into memory that is not part of the stack and then - SIGSEGV!
I have never seen this but i had this thing in my mind!
stack memory error here could be a memory corruption also.
lets say there is a stack overflow in a c/c++ program.
does it create a core dump file?
It depends on the operating system and language runtime. I'll assume you're talking about some flavour of Unix/Linux, since you mention a core dump.
Typically, there will be some amount (perhaps a single page) of unmapped virtual memory beyond the stack. If you overflow by less than that amount, then the program will attempt to access that, giving a segmentation fault. If the program doesn't handle the signal, then it will abort; and if core dumps are enabled, then one will be produced. You may need to enable core dumps, perhaps using ulimit -c unlimited from the shell you use to launch the program.
If you overflow by a large amount, then you may instead overwrite some other part of the program's memory. If this happens, then all bets are off; the program could crash, or could continue in a corrupt state and cause any kind of damage at any point in the future.
That's assuming that, by "overflow" you mean using more stack memory than has been allocated by some combination of a deep call stack and large automatic objects. If you're talking about writing to the wrong part of the stack (e.g. by an out-of-bounds access to an automatic array), then you'll typically get random memory corruption rather than a segmentation fault; again, the program might shamble on in a corrupt state with unpredictable results.
Stack overflow does not create a core dump file always. If you are lucky, it is just a simple overrun of your stack, some local variables or buffers are overwritten. It might not cause any abnormal behavior of your program, and no core dump file.
However, if the stack overflow overwrites some local variables which are pointers, or the return address, when you use the pointer, which is now invalid address and points to unmapped memory page, or the program use the pointer to write to read-only pages, it causes the segmentation fault and the core dump file is created. Or the return address is overwritten, and the CPU returns to invalid addressing space or executes invalid code, it also causes the exception and a core file is created.
I'm having problems with stack overflows and would like to see exactly what the contents on the stack are.
How can I examine the stack frame with GDB? is kind of the same question, however info locals looks fine here (few variables, most of them std::vectors and std::maps), so I wouldn't expect the stack to overflow from this. Moreover, I have set the stack limit to 32MB, so this should be plenty and no recursive functions are used.
Is there a tool that can show the complete contents of the stack, maybe ordered by size?
Stack overflows are better caught by special profilers rather than manually looking at variables in gdb. It is more likely that you have buffer overrun rather than stack overflow. In either case, here is a list of some profilers that can help you to point out the problem:
Valgrind
Purify
Insure++
Electric Fence
Good luck!
Even if you have no functions that call themselves, it's possible you've created a situation in which two or more functions are mutually recursive.
A good starting point would be to examine not the current stack frame, but a list of stack frames, using the "backtrace" (or "bt" for short) command. If you see a repeated pattern of two or more functions calling each other, then you have mutual recursion.
You can examine the current stack frame using the backtrace command.
You can also get the current stack pointer in gdb (e.g., by running 'info registers') and then dump the memory around that location using the examine (or 'x') command. Just be aware that the stack pointer points below the stack, so you need to start dumping from stack pointer - N to see the first N bytes on the stack.